1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;; Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
145 (UNSPEC_DIV_INV_M0 30)
146 (UNSPEC_DIV_INV_M1 31)
147 (UNSPEC_DIV_INV_M2 32)
148 (UNSPEC_DIV_INV_M3 33)
149 (UNSPEC_DIV_INV20 34)
150 (UNSPEC_DIV_INV_TABLE 37)
158 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160 (UNSPEC_EXTRACT_S16 43)
161 (UNSPEC_EXTRACT_U16 44)
163 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
166 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167 (UNSPEC_PCREL_SYMOFF 46)
169 ;; These are used with unspec_volatile.
175 (UNSPECV_WINDOW_END 10)
176 (UNSPECV_CONST_END 11)
177 (UNSPECV_EH_RETURN 12)
180 ;; -------------------------------------------------------------------------
182 ;; -------------------------------------------------------------------------
187 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188 (const (symbol_ref "sh_cpu_attr")))
190 (define_attr "endian" "big,little"
191 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192 (const_string "little") (const_string "big"))))
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197 (const_string "yes") (const_string "no"))))
199 (define_attr "fmovd" "yes,no"
200 (const (if_then_else (symbol_ref "TARGET_FMOVD")
201 (const_string "yes") (const_string "no"))))
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
205 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207 (const_string "sh1"))))
209 ;; cbranch conditional branch instructions
210 ;; jump unconditional jumps
211 ;; arith ordinary arithmetic
212 ;; arith3 a compound insn that behaves similarly to a sequence of
213 ;; three insns of type arith
214 ;; arith3b like above, but might end with a redirected branch
216 ;; load_si Likewise, SImode variant for general register.
217 ;; fload Likewise, but load to fp register.
219 ;; fstore floating point register to memory
220 ;; move general purpose register to register
221 ;; movi8 8-bit immediate to general purpose register
222 ;; mt_group other sh4 mt instructions
223 ;; fmove register to register, floating point
224 ;; smpy word precision integer multiply
225 ;; dmpy longword or doublelongword precision integer multiply
227 ;; pload load of pr reg, which can't be put into delay slot of rts
228 ;; prset copy register to pr reg, ditto
229 ;; pstore store of pr reg, which can't be put into delay slot of jsr
230 ;; prget copy pr to register, ditto
231 ;; pcload pc relative load of constant value
232 ;; pcfload Likewise, but load to fp register.
233 ;; pcload_si Likewise, SImode variant for general register.
234 ;; rte return from exception
235 ;; sfunc special function call with known used registers
236 ;; call function call
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv floating point divide (or square root)
240 ;; gp_fpul move from general purpose register to fpul
241 ;; fpul_gp move from fpul to general purpose register
242 ;; mac_gp move from mac[lh] to general purpose register
243 ;; gp_mac move from general purpose register to mac[lh]
244 ;; mac_mem move from mac[lh] to memory
245 ;; mem_mac move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s fix_truncsfsi2_i4
248 ;; dfdiv double precision floating point divide (or square root)
249 ;; cwb ic_invalidate_line_i
250 ;; movua SH4a unaligned load
251 ;; fsrra square root reciprocal approximate
252 ;; fsca sine and cosine approximate
253 ;; tls_load load TLS related address
254 ;; arith_media SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media SHmedia compare instructions
257 ;; dfdiv_media SHmedia double precision divide and square root
258 ;; dfmul_media SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media SHmedia longword multiply
262 ;; fcmp_media SHmedia floating point compare instructions
263 ;; fdiv_media SHmedia single precision divide and square root
264 ;; fload_media SHmedia floating point register load instructions
265 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media SHmedia unconditional branch instructions
272 ;; load_media SHmedia general register load instructions
273 ;; pt_media SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media SHmedia ptabs instruction
275 ;; store_media SHmedia general register store instructions
276 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media SHmedia mac-style fixed point operations
278 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil no-op move, will be deleted.
284 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
285 (const_string "other"))
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
290 ;; mt_group SH4 "mt" group instructions.
292 ;; ex_group SH4 "ex" group instructions.
294 ;; ls_group SH4 "ls" group instructions.
297 (define_attr "insn_class"
298 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302 (eq_attr "type" "cbranch,jump") (const_string "br_group")
303 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304 (const_string "fe_group")
305 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
306 (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long. Something in the
325 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
330 ;; The maximum range used for SImode constant pool entries is 1018. A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table. That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
348 (define_attr "short_cbranch_p" "no,yes"
349 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
351 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
353 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
357 ] (const_string "no")))
359 (define_attr "med_branch_p" "no,yes"
360 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
363 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
368 ] (const_string "no")))
370 (define_attr "med_cbranch_p" "no,yes"
371 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
374 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
379 ] (const_string "no")))
381 (define_attr "braf_branch_p" "no,yes"
382 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
387 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
392 ] (const_string "no")))
394 (define_attr "braf_cbranch_p" "no,yes"
395 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
397 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
400 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
402 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
405 ] (const_string "no")))
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
414 ; All other instructions are two bytes long by default.
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419 (cond [(eq_attr "type" "cbranch")
420 (cond [(eq_attr "short_cbranch_p" "yes")
422 (eq_attr "med_cbranch_p" "yes")
424 (eq_attr "braf_cbranch_p" "yes")
426 ;; ??? using pc is not computed transitively.
427 (ne (match_dup 0) (match_dup 0))
429 (ne (symbol_ref ("flag_pic")) (const_int 0))
432 (eq_attr "type" "jump")
433 (cond [(eq_attr "med_branch_p" "yes")
435 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
437 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
439 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
440 (symbol_ref "code_for_indirect_jump_scratch"))))
441 (cond [(eq_attr "braf_branch_p" "yes")
443 (eq (symbol_ref "flag_pic") (const_int 0))
445 (ne (symbol_ref "TARGET_SH2") (const_int 0))
446 (const_int 10)] (const_int 18))
447 (eq_attr "braf_branch_p" "yes")
449 ;; ??? using pc is not computed transitively.
450 (ne (match_dup 0) (match_dup 0))
452 (ne (symbol_ref ("flag_pic")) (const_int 0))
455 (eq_attr "type" "pt_media")
456 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
457 (const_int 20) (const_int 12))
458 (and (eq_attr "type" "jump_media")
459 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
461 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
465 ;; DFA descriptions for the pipelines
468 (include "shmedia.md")
471 (include "predicates.md")
472 (include "constraints.md")
474 ;; Definitions for filling delay slots
476 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
478 (define_attr "banked" "yes,no"
479 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
481 (const_string "yes")]
482 (const_string "no")))
484 ;; ??? This should be (nil) instead of (const_int 0)
485 (define_attr "hit_stack" "yes,no"
486 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
489 (const_string "yes")))
491 (define_attr "interrupt_function" "no,yes"
492 (const (symbol_ref "current_function_interrupt")))
494 (define_attr "in_delay_slot" "yes,no"
495 (cond [(eq_attr "type" "cbranch") (const_string "no")
496 (eq_attr "type" "pcload,pcload_si") (const_string "no")
497 (eq_attr "needs_delay_slot" "yes") (const_string "no")
498 (eq_attr "length" "2") (const_string "yes")
499 ] (const_string "no")))
501 (define_attr "cond_delay_slot" "yes,no"
502 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
503 ] (const_string "no")))
505 (define_attr "is_sfunc" ""
506 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
508 (define_attr "is_mac_media" ""
509 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
511 (define_attr "branch_zero" "yes,no"
512 (cond [(eq_attr "type" "!cbranch") (const_string "no")
513 (ne (symbol_ref "(next_active_insn (insn)\
514 == (prev_active_insn\
515 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
516 && get_attr_length (next_active_insn (insn)) == 2")
518 (const_string "yes")]
519 (const_string "no")))
521 ;; SH4 Double-precision computation with double-precision result -
522 ;; the two halves are ready at different times.
523 (define_attr "dfp_comp" "yes,no"
524 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
525 (const_string "no")))
527 ;; Insns for which the latency of a preceding fp insn is decreased by one.
528 (define_attr "late_fp_use" "yes,no" (const_string "no"))
529 ;; And feeding insns for which this relevant.
530 (define_attr "any_fp_comp" "yes,no"
531 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
532 (const_string "yes")]
533 (const_string "no")))
535 (define_attr "any_int_load" "yes,no"
536 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
537 (const_string "yes")]
538 (const_string "no")))
540 (define_attr "highpart" "user, ignore, extend, depend, must_split"
541 (const_string "user"))
544 (eq_attr "needs_delay_slot" "yes")
545 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
547 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
548 ;; and thus we can't put a pop instruction in its delay slot.
549 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
550 ;; instruction can go in the delay slot.
552 ;; Since a normal return (rts) implicitly uses the PR register,
553 ;; we can't allow PR register loads in an rts delay slot.
556 (eq_attr "type" "return")
557 [(and (eq_attr "in_delay_slot" "yes")
558 (ior (and (eq_attr "interrupt_function" "no")
559 (eq_attr "type" "!pload,prset"))
560 (and (eq_attr "interrupt_function" "yes")
562 (eq (symbol_ref "TARGET_SH3") (const_int 0))
563 (eq_attr "hit_stack" "no")
564 (eq_attr "banked" "no"))))) (nil) (nil)])
566 ;; Since a call implicitly uses the PR register, we can't allow
567 ;; a PR register store in a jsr delay slot.
570 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
571 [(and (eq_attr "in_delay_slot" "yes")
572 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
574 ;; Say that we have annulled true branches, since this gives smaller and
575 ;; faster code when branches are predicted as not taken.
577 ;; ??? The non-annulled condition should really be "in_delay_slot",
578 ;; but insns that can be filled in non-annulled get priority over insns
579 ;; that can only be filled in anulled.
582 (and (eq_attr "type" "cbranch")
583 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
584 ;; SH2e has a hardware bug that pretty much prohibits the use of
585 ;; annuled delay slots.
586 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
587 (not (eq_attr "cpu" "sh2e"))) (nil)])
589 ;; -------------------------------------------------------------------------
590 ;; SImode signed integer comparisons
591 ;; -------------------------------------------------------------------------
595 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
596 (match_operand:SI 1 "logical_operand" "K08,r"))
600 [(set_attr "type" "mt_group")])
602 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
603 ;; That would still allow reload to create cmpi instructions, but would
604 ;; perhaps allow forcing the constant into a register when that is better.
605 ;; Probably should use r0 for mem/imm compares, but force constant into a
606 ;; register for pseudo/imm compares.
608 (define_insn "cmpeqsi_t"
610 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
611 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
617 [(set_attr "type" "mt_group")])
619 (define_insn "cmpgtsi_t"
621 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
622 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
627 [(set_attr "type" "mt_group")])
629 (define_insn "cmpgesi_t"
631 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
632 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
637 [(set_attr "type" "mt_group")])
639 ;; -------------------------------------------------------------------------
640 ;; SImode compare and branch
641 ;; -------------------------------------------------------------------------
643 (define_expand "cbranchsi4"
645 (if_then_else (match_operator 0 "comparison_operator"
646 [(match_operand:SI 1 "arith_operand" "")
647 (match_operand:SI 2 "arith_operand" "")])
648 (label_ref (match_operand 3 "" ""))
650 (clobber (reg:SI T_REG))]
653 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
654 operands[2], operands[3]));
655 else if (TARGET_CBRANCHDI4)
656 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
658 sh_emit_compare_and_branch (operands, SImode);
661 ;; -------------------------------------------------------------------------
662 ;; SImode unsigned integer comparisons
663 ;; -------------------------------------------------------------------------
665 (define_insn_and_split "cmpgeusi_t"
667 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
668 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
671 "&& operands[1] == CONST0_RTX (SImode)"
675 emit_insn (gen_sett ());
678 [(set_attr "type" "mt_group")])
680 (define_insn "cmpgtusi_t"
682 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
683 (match_operand:SI 1 "arith_reg_operand" "r")))]
686 [(set_attr "type" "mt_group")])
689 ;; -------------------------------------------------------------------------
690 ;; DImode compare and branch
691 ;; -------------------------------------------------------------------------
694 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
695 ;; Therefore, we aim to have a set of three branches that go straight to the
696 ;; destination, i.e. only one of them is taken at any one time.
697 ;; This mechanism should also be slightly better for the sh4-200.
699 (define_expand "cbranchdi4"
701 (if_then_else (match_operator 0 "comparison_operator"
702 [(match_operand:DI 1 "arith_operand" "")
703 (match_operand:DI 2 "arith_operand" "")])
704 (label_ref (match_operand 3 "" ""))
706 (clobber (match_dup 4))
707 (clobber (reg:SI T_REG))]
708 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
711 enum rtx_code comparison;
715 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
716 operands[2], operands[3]));
720 else if (!TARGET_CBRANCHDI4)
722 sh_emit_compare_and_branch (operands, DImode);
728 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
731 comparison = prepare_cbranch_operands (operands, DImode,
732 LAST_AND_UNUSED_RTX_CODE);
733 if (comparison != GET_CODE (operands[0]))
735 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
736 operands[4] = gen_rtx_SCRATCH (SImode);
740 (define_insn_and_split "cbranchdi4_i"
742 (if_then_else (match_operator 0 "comparison_operator"
743 [(match_operand:DI 1 "arith_operand" "r,r")
744 (match_operand:DI 2 "arith_operand" "rN,I08")])
745 (label_ref (match_operand 3 "" ""))
747 (clobber (match_scratch:SI 4 "=X,&r"))
748 (clobber (reg:SI T_REG))]
751 "&& reload_completed"
755 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
760 ;; -------------------------------------------------------------------------
761 ;; DImode signed integer comparisons
762 ;; -------------------------------------------------------------------------
766 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
767 (match_operand:DI 1 "arith_operand" "r"))
770 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
772 [(set_attr "length" "6")
773 (set_attr "type" "arith3b")])
775 (define_insn "cmpeqdi_t"
777 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
778 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
781 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
782 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
783 [(set_attr "length" "6")
784 (set_attr "type" "arith3b")])
788 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
789 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
790 ;; If we applied this split when not optimizing, it would only be
791 ;; applied during the machine-dependent reorg, when no new basic blocks
793 "TARGET_SH1 && reload_completed && optimize"
794 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
795 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
796 (label_ref (match_dup 6))
798 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
803 = gen_rtx_REG (SImode,
804 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
806 = (operands[1] == const0_rtx
808 : gen_rtx_REG (SImode,
809 true_regnum (operands[1])
810 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
811 operands[4] = gen_lowpart (SImode, operands[0]);
812 operands[5] = gen_lowpart (SImode, operands[1]);
813 operands[6] = gen_label_rtx ();
816 (define_insn "cmpgtdi_t"
818 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
819 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
822 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
823 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
824 [(set_attr "length" "8")
825 (set_attr "type" "arith3")])
827 (define_insn "cmpgedi_t"
829 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
830 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
833 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
835 [(set_attr "length" "8,2")
836 (set_attr "type" "arith3,mt_group")])
838 ;; -------------------------------------------------------------------------
839 ;; DImode unsigned integer comparisons
840 ;; -------------------------------------------------------------------------
842 (define_insn "cmpgeudi_t"
844 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
845 (match_operand:DI 1 "arith_reg_operand" "r")))]
847 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
848 [(set_attr "length" "8")
849 (set_attr "type" "arith3")])
851 (define_insn "cmpgtudi_t"
853 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
854 (match_operand:DI 1 "arith_reg_operand" "r")))]
856 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
857 [(set_attr "length" "8")
858 (set_attr "type" "arith3")])
860 (define_insn "cmpeqsi_media"
861 [(set (match_operand:SI 0 "register_operand" "=r")
862 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
863 (match_operand:SI 2 "cmp_operand" "Nr")))]
866 [(set_attr "type" "cmp_media")])
868 (define_insn "cmpeqdi_media"
869 [(set (match_operand:SI 0 "register_operand" "=r")
870 (eq:SI (match_operand:DI 1 "register_operand" "%r")
871 (match_operand:DI 2 "cmp_operand" "Nr")))]
874 [(set_attr "type" "cmp_media")])
876 (define_insn "cmpgtsi_media"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
879 (match_operand:SI 2 "cmp_operand" "rN")))]
882 [(set_attr "type" "cmp_media")])
884 (define_insn "cmpgtdi_media"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
887 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
890 [(set_attr "type" "cmp_media")])
892 (define_insn "cmpgtusi_media"
893 [(set (match_operand:SI 0 "register_operand" "=r")
894 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
895 (match_operand:SI 2 "cmp_operand" "rN")))]
897 "cmpgtu %N1, %N2, %0"
898 [(set_attr "type" "cmp_media")])
900 (define_insn "cmpgtudi_media"
901 [(set (match_operand:SI 0 "register_operand" "=r")
902 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
903 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
905 "cmpgtu %N1, %N2, %0"
906 [(set_attr "type" "cmp_media")])
908 ; These two patterns are for combine.
909 (define_insn "*cmpne0sisi_media"
910 [(set (match_operand:SI 0 "register_operand" "=r")
911 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
914 [(set_attr "type" "cmp_media")])
916 ;; -------------------------------------------------------------------------
917 ;; Conditional move instructions
918 ;; -------------------------------------------------------------------------
920 ;; The insn names may seem reversed, but note that cmveq performs the move
921 ;; if op1 == 0, and cmvne does it if op1 != 0.
923 (define_insn "movdicc_false"
924 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
925 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
927 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
928 (match_operand:DI 3 "arith_reg_operand" "0")))]
931 [(set_attr "type" "arith_media")])
933 (define_insn "movdicc_true"
934 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
935 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
937 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
938 (match_operand:DI 3 "arith_reg_operand" "0")))]
941 [(set_attr "type" "arith_media")])
944 [(set (match_operand:DI 0 "arith_reg_dest" "")
945 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
946 [(match_operand:DI 1 "arith_reg_operand" "")
948 (match_operand:DI 2 "arith_reg_dest" "")
950 (set (match_dup 2) (match_dup 0))]
951 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
953 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
956 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
957 VOIDmode, operands[1], CONST0_RTX (DImode));
961 [(set (match_operand:DI 0 "general_movdst_operand" "")
962 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
963 (set (match_operand:DI 2 "arith_reg_dest" "")
964 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
965 [(match_operand:DI 3 "arith_reg_operand" "")
969 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
971 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
974 (define_expand "movdicc"
975 [(set (match_operand:DI 0 "register_operand" "")
976 (if_then_else:DI (match_operand 1 "comparison_operator" "")
977 (match_operand:DI 2 "register_operand" "")
978 (match_operand:DI 3 "register_operand" "")))]
982 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
983 && GET_MODE (XEXP (operands[1], 0)) == DImode
984 && XEXP (operands[1], 1) == const0_rtx)
988 if (!can_create_pseudo_p ())
991 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
992 GET_CODE (operands[1]),
993 XEXP (operands[1], 0),
994 XEXP (operands[1], 1));
1000 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1001 ;; SImode to DImode.
1002 (define_insn "movsicc_false"
1003 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1004 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1006 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1007 (match_operand:SI 3 "arith_reg_operand" "0")))]
1010 [(set_attr "type" "arith_media")])
1012 (define_insn "movsicc_true"
1013 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1014 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1016 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1017 (match_operand:SI 3 "arith_reg_operand" "0")))]
1020 [(set_attr "type" "arith_media")])
1023 [(set (match_operand:SI 0 "arith_reg_dest" "")
1024 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1025 [(match_operand:SI 1 "arith_reg_operand" "")
1027 (match_operand:SI 2 "arith_reg_dest" "")
1029 (set (match_dup 2) (match_dup 0))]
1030 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1032 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1035 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1036 VOIDmode, operands[1], CONST0_RTX (SImode));
1040 [(set (match_operand:SI 0 "general_movdst_operand" "")
1041 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1042 (set (match_operand:SI 2 "arith_reg_dest" "")
1043 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1044 [(match_operand:SI 3 "arith_reg_operand" "")
1048 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1049 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1051 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1054 replace_rtx (operands[4], operands[0], operands[1]);
1058 [(set (match_operand 0 "any_register_operand" "")
1059 (match_operand 1 "any_register_operand" ""))
1060 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1061 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1062 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1063 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1064 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1065 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1066 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1067 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1068 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1069 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1070 && (REGNO_REG_CLASS (REGNO (operands[0]))
1071 == REGNO_REG_CLASS (REGNO (operands[2])))
1072 && (REGNO_REG_CLASS (REGNO (operands[1]))
1073 == REGNO_REG_CLASS (REGNO (operands[0])))"
1074 [(set (match_dup 0) (match_dup 3))
1075 (set (match_dup 4) (match_dup 5))]
1078 rtx set1, set2, insn2;
1079 rtx replacements[4];
1081 /* We want to replace occurrences of operands[0] with operands[1] and
1082 operands[2] with operands[0] in operands[4]/operands[5].
1083 Doing just two replace_rtx calls naively would result in the second
1084 replacement undoing all that the first did if operands[1] and operands[2]
1085 are identical, so we must do this simultaneously. */
1086 replacements[0] = operands[0];
1087 replacements[1] = operands[1];
1088 replacements[2] = operands[2];
1089 replacements[3] = operands[0];
1090 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1091 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1092 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1095 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1096 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1097 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1098 /* The operands array is aliased to recog_data.operand, which gets
1099 clobbered by extract_insn, so finish with it now. */
1100 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1101 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1102 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1103 always uses emit_insn. */
1104 /* Check that we don't violate matching constraints or earlyclobbers. */
1105 extract_insn (emit_insn (set1));
1106 if (! constrain_operands (1))
1108 insn2 = emit (set2);
1109 if (GET_CODE (insn2) == BARRIER)
1111 extract_insn (insn2);
1112 if (! constrain_operands (1))
1116 tmp = replacements[0];
1117 replacements[0] = replacements[1];
1118 replacements[1] = tmp;
1119 tmp = replacements[2];
1120 replacements[2] = replacements[3];
1121 replacements[3] = tmp;
1122 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1123 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1124 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1130 ;; The register allocator is rather clumsy in handling multi-way conditional
1131 ;; moves, so allow the combiner to make them, and we split them up after
1133 (define_insn_and_split "*movsicc_umin"
1134 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1135 (umin:SI (if_then_else:SI
1136 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1138 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1139 (match_operand:SI 3 "register_operand" "0"))
1140 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1141 (clobber (match_scratch:SI 5 "=&r"))]
1142 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1144 "TARGET_SHMEDIA && reload_completed"
1148 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1150 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1151 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1156 (define_insn "*movsicc_t_false"
1157 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1158 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1159 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1160 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1161 "TARGET_PRETEND_CMOVE
1162 && (arith_reg_operand (operands[1], SImode)
1163 || (immediate_operand (operands[1], SImode)
1164 && satisfies_constraint_I08 (operands[1])))"
1165 "bt 0f\;mov %1,%0\\n0:"
1166 [(set_attr "type" "mt_group,arith") ;; poor approximation
1167 (set_attr "length" "4")])
1169 (define_insn "*movsicc_t_true"
1170 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1171 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1172 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1173 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1174 "TARGET_PRETEND_CMOVE
1175 && (arith_reg_operand (operands[1], SImode)
1176 || (immediate_operand (operands[1], SImode)
1177 && satisfies_constraint_I08 (operands[1])))"
1178 "bf 0f\;mov %1,%0\\n0:"
1179 [(set_attr "type" "mt_group,arith") ;; poor approximation
1180 (set_attr "length" "4")])
1182 (define_expand "movsicc"
1183 [(set (match_operand:SI 0 "arith_reg_dest" "")
1184 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1185 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1186 (match_operand:SI 3 "arith_reg_operand" "")))]
1187 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1190 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1191 && GET_MODE (XEXP (operands[1], 0)) == SImode
1193 || (REG_P (XEXP (operands[1], 0))
1194 && REGNO (XEXP (operands[1], 0)) == T_REG))
1195 && XEXP (operands[1], 1) == const0_rtx)
1198 else if (TARGET_PRETEND_CMOVE)
1200 enum rtx_code code = GET_CODE (operands[1]);
1201 enum rtx_code new_code = code;
1202 rtx op0 = XEXP (operands[1], 0);
1203 rtx op1 = XEXP (operands[1], 1);
1205 if (! currently_expanding_to_rtl)
1209 case LT: case LE: case LEU: case LTU:
1210 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1213 new_code = reverse_condition (code);
1215 case EQ: case GT: case GE: case GEU: case GTU:
1220 sh_emit_scc_to_t (new_code, op0, op1);
1221 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1222 gen_rtx_REG (SImode, T_REG), const0_rtx);
1226 if (!can_create_pseudo_p ())
1229 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1230 GET_CODE (operands[1]),
1231 XEXP (operands[1], 0),
1232 XEXP (operands[1], 1));
1238 (define_expand "movqicc"
1239 [(set (match_operand:QI 0 "register_operand" "")
1240 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1241 (match_operand:QI 2 "register_operand" "")
1242 (match_operand:QI 3 "register_operand" "")))]
1246 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1247 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1248 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1249 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1253 ;; -------------------------------------------------------------------------
1254 ;; Addition instructions
1255 ;; -------------------------------------------------------------------------
1257 (define_expand "adddi3"
1258 [(set (match_operand:DI 0 "arith_reg_operand" "")
1259 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1260 (match_operand:DI 2 "arith_operand" "")))]
1266 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1268 operands[2] = force_reg (DImode, operands[2]);
1269 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1274 (define_insn "*adddi3_media"
1275 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1276 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1277 (match_operand:DI 2 "arith_operand" "r,I10")))]
1282 [(set_attr "type" "arith_media")])
1284 (define_insn "*adddisi3_media"
1285 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1286 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1287 (match_operand:DI 2 "arith_operand" "r,I10")))]
1292 [(set_attr "type" "arith_media")
1293 (set_attr "highpart" "ignore")])
1295 (define_insn "adddi3z_media"
1296 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1298 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1299 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1301 "addz.l %1, %N2, %0"
1302 [(set_attr "type" "arith_media")
1303 (set_attr "highpart" "ignore")])
1305 (define_insn "adddi3_compact"
1306 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1307 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1308 (match_operand:DI 2 "arith_reg_operand" "r")))
1309 (clobber (reg:SI T_REG))]
1312 [(set_attr "length" "6")])
1315 [(set (match_operand:DI 0 "arith_reg_dest" "")
1316 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1317 (match_operand:DI 2 "arith_reg_operand" "")))
1318 (clobber (reg:SI T_REG))]
1319 "TARGET_SH1 && reload_completed"
1323 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1324 high0 = gen_rtx_REG (SImode,
1325 true_regnum (operands[0])
1326 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1327 high2 = gen_rtx_REG (SImode,
1328 true_regnum (operands[2])
1329 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1330 emit_insn (gen_clrt ());
1331 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1332 emit_insn (gen_addc1 (high0, high0, high2));
1337 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1338 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1339 (match_operand:SI 2 "arith_reg_operand" "r"))
1342 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1345 [(set_attr "type" "arith")])
1347 (define_insn "addc1"
1348 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1349 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1350 (match_operand:SI 2 "arith_reg_operand" "r"))
1352 (clobber (reg:SI T_REG))]
1355 [(set_attr "type" "arith")])
1357 (define_expand "addsi3"
1358 [(set (match_operand:SI 0 "arith_reg_operand" "")
1359 (plus:SI (match_operand:SI 1 "arith_operand" "")
1360 (match_operand:SI 2 "arith_operand" "")))]
1365 operands[1] = force_reg (SImode, operands[1]);
1368 (define_insn "addsi3_media"
1369 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1370 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1371 (match_operand:SI 2 "arith_operand" "r,I10")))]
1376 [(set_attr "type" "arith_media")
1377 (set_attr "highpart" "ignore")])
1379 (define_insn "addsidi3_media"
1380 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1381 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1383 (match_operand:SI 2 "arith_operand"
1389 [(set_attr "type" "arith_media")
1390 (set_attr "highpart" "ignore")])
1392 (define_insn "*addsi3_compact"
1393 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1394 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1395 (match_operand:SI 2 "arith_operand" "rI08")))]
1398 [(set_attr "type" "arith")])
1400 ;; -------------------------------------------------------------------------
1401 ;; Subtraction instructions
1402 ;; -------------------------------------------------------------------------
1404 (define_expand "subdi3"
1405 [(set (match_operand:DI 0 "arith_reg_operand" "")
1406 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1407 (match_operand:DI 2 "arith_reg_operand" "")))]
1413 operands[1] = force_reg (DImode, operands[1]);
1414 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1419 (define_insn "*subdi3_media"
1420 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1421 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1422 (match_operand:DI 2 "arith_reg_operand" "r")))]
1425 [(set_attr "type" "arith_media")])
1427 (define_insn "subdisi3_media"
1428 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1429 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1430 (match_operand:DI 2 "arith_reg_operand" "r")))]
1433 [(set_attr "type" "arith_media")
1434 (set_attr "highpart" "ignore")])
1436 (define_insn "subdi3_compact"
1437 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1438 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1439 (match_operand:DI 2 "arith_reg_operand" "r")))
1440 (clobber (reg:SI T_REG))]
1443 [(set_attr "length" "6")])
1446 [(set (match_operand:DI 0 "arith_reg_dest" "")
1447 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1448 (match_operand:DI 2 "arith_reg_operand" "")))
1449 (clobber (reg:SI T_REG))]
1450 "TARGET_SH1 && reload_completed"
1454 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1455 high0 = gen_rtx_REG (SImode,
1456 true_regnum (operands[0])
1457 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1458 high2 = gen_rtx_REG (SImode,
1459 true_regnum (operands[2])
1460 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461 emit_insn (gen_clrt ());
1462 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1463 emit_insn (gen_subc1 (high0, high0, high2));
1468 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1469 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1470 (match_operand:SI 2 "arith_reg_operand" "r"))
1473 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1478 [(set_attr "type" "arith")])
1480 (define_insn "subc1"
1481 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1482 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1483 (match_operand:SI 2 "arith_reg_operand" "r"))
1485 (clobber (reg:SI T_REG))]
1488 [(set_attr "type" "arith")])
1490 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1491 ;; pattern for this case. This helps multimedia applications that compute
1492 ;; the sum of absolute differences.
1493 (define_insn "mov_neg_si_t"
1494 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1497 [(set_attr "type" "arith")])
1499 (define_insn "*subsi3_internal"
1500 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1501 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1502 (match_operand:SI 2 "arith_reg_operand" "r")))]
1505 [(set_attr "type" "arith")])
1507 (define_insn_and_split "*subsi3_media"
1508 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1509 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1510 (match_operand:SI 2 "extend_reg_operand" "r")))]
1512 && (operands[1] != constm1_rtx
1513 || (GET_CODE (operands[2]) != TRUNCATE
1514 && GET_CODE (operands[2]) != SUBREG))"
1516 "operands[1] == constm1_rtx"
1517 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1519 [(set_attr "type" "arith_media")
1520 (set_attr "highpart" "ignore")])
1523 [(set (match_operand:SI 0 "arith_reg_dest" "")
1524 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1525 "general_extend_operand"
1527 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1528 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1529 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1533 [(set (match_operand:SI 0 "arith_reg_dest" "")
1534 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1535 "general_extend_operand"
1537 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1538 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1539 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1541 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1542 ;; will sometimes save one instruction. Otherwise we might get
1543 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1546 (define_expand "subsi3"
1547 [(set (match_operand:SI 0 "arith_reg_operand" "")
1548 (minus:SI (match_operand:SI 1 "arith_operand" "")
1549 (match_operand:SI 2 "arith_reg_operand" "")))]
1553 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1555 emit_insn (gen_negsi2 (operands[0], operands[2]));
1556 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1561 if (!can_create_pseudo_p ()
1562 && ! arith_reg_or_0_operand (operands[1], SImode))
1564 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1565 operands[1] = force_reg (SImode, operands[1]);
1569 ;; -------------------------------------------------------------------------
1570 ;; Division instructions
1571 ;; -------------------------------------------------------------------------
1573 ;; We take advantage of the library routines which don't clobber as many
1574 ;; registers as a normal function call would.
1576 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1577 ;; also has an effect on the register that holds the address of the sfunc.
1578 ;; To make this work, we have an extra dummy insn that shows the use
1579 ;; of this register for reorg.
1581 (define_insn "use_sfunc_addr"
1582 [(set (reg:SI PR_REG)
1583 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1584 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1586 [(set_attr "length" "0")])
1588 (define_insn "udivsi3_sh2a"
1589 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1590 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1591 (match_operand:SI 2 "arith_reg_operand" "z")))]
1594 [(set_attr "type" "arith")
1595 (set_attr "in_delay_slot" "no")])
1597 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1598 ;; hard register 0. If we used hard register 0, then the next instruction
1599 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1600 ;; gets allocated to a stack slot that needs its address reloaded, then
1601 ;; there is nothing to prevent reload from using r0 to reload the address.
1602 ;; This reload would clobber the value in r0 we are trying to store.
1603 ;; If we let reload allocate r0, then this problem can never happen.
1605 (define_insn "udivsi3_i1"
1606 [(set (match_operand:SI 0 "register_operand" "=z")
1607 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1608 (clobber (reg:SI T_REG))
1609 (clobber (reg:SI PR_REG))
1610 (clobber (reg:SI R4_REG))
1611 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1612 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1614 [(set_attr "type" "sfunc")
1615 (set_attr "needs_delay_slot" "yes")])
1617 ; Since shmedia-nofpu code could be linked against shcompact code, and
1618 ; the udivsi3 libcall has the same name, we must consider all registers
1619 ; clobbered that are in the union of the registers clobbered by the
1620 ; shmedia and the shcompact implementation. Note, if the shcompact
1621 ; implementation actually used shcompact code, we'd need to clobber
1622 ; also r23 and fr23.
1623 (define_insn "udivsi3_i1_media"
1624 [(set (match_operand:SI 0 "register_operand" "=z")
1625 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1626 (clobber (reg:SI T_MEDIA_REG))
1627 (clobber (reg:SI PR_MEDIA_REG))
1628 (clobber (reg:SI R20_REG))
1629 (clobber (reg:SI R21_REG))
1630 (clobber (reg:SI R22_REG))
1631 (clobber (reg:DI TR0_REG))
1632 (clobber (reg:DI TR1_REG))
1633 (clobber (reg:DI TR2_REG))
1634 (use (match_operand 1 "target_reg_operand" "b"))]
1635 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1637 [(set_attr "type" "sfunc")
1638 (set_attr "needs_delay_slot" "yes")])
1640 (define_expand "udivsi3_i4_media"
1642 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1644 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1645 (set (match_dup 5) (float:DF (match_dup 3)))
1646 (set (match_dup 6) (float:DF (match_dup 4)))
1647 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1648 (set (match_dup 8) (fix:DI (match_dup 7)))
1649 (set (match_operand:SI 0 "register_operand" "")
1650 (truncate:SI (match_dup 8)))]
1651 "TARGET_SHMEDIA_FPU"
1654 operands[3] = gen_reg_rtx (DImode);
1655 operands[4] = gen_reg_rtx (DImode);
1656 operands[5] = gen_reg_rtx (DFmode);
1657 operands[6] = gen_reg_rtx (DFmode);
1658 operands[7] = gen_reg_rtx (DFmode);
1659 operands[8] = gen_reg_rtx (DImode);
1662 (define_insn "udivsi3_i4"
1663 [(set (match_operand:SI 0 "register_operand" "=y")
1664 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1665 (clobber (reg:SI T_REG))
1666 (clobber (reg:SI PR_REG))
1667 (clobber (reg:DF DR0_REG))
1668 (clobber (reg:DF DR2_REG))
1669 (clobber (reg:DF DR4_REG))
1670 (clobber (reg:SI R0_REG))
1671 (clobber (reg:SI R1_REG))
1672 (clobber (reg:SI R4_REG))
1673 (clobber (reg:SI R5_REG))
1674 (use (reg:PSI FPSCR_REG))
1675 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1676 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1678 [(set_attr "type" "sfunc")
1679 (set_attr "fp_mode" "double")
1680 (set_attr "needs_delay_slot" "yes")])
1682 (define_insn "udivsi3_i4_single"
1683 [(set (match_operand:SI 0 "register_operand" "=y")
1684 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1685 (clobber (reg:SI T_REG))
1686 (clobber (reg:SI PR_REG))
1687 (clobber (reg:DF DR0_REG))
1688 (clobber (reg:DF DR2_REG))
1689 (clobber (reg:DF DR4_REG))
1690 (clobber (reg:SI R0_REG))
1691 (clobber (reg:SI R1_REG))
1692 (clobber (reg:SI R4_REG))
1693 (clobber (reg:SI R5_REG))
1694 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1695 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1697 [(set_attr "type" "sfunc")
1698 (set_attr "needs_delay_slot" "yes")])
1700 (define_insn "udivsi3_i4_int"
1701 [(set (match_operand:SI 0 "register_operand" "=z")
1702 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1703 (clobber (reg:SI T_REG))
1704 (clobber (reg:SI R1_REG))
1705 (clobber (reg:SI PR_REG))
1706 (clobber (reg:SI MACH_REG))
1707 (clobber (reg:SI MACL_REG))
1708 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1711 [(set_attr "type" "sfunc")
1712 (set_attr "needs_delay_slot" "yes")])
1715 (define_expand "udivsi3"
1716 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1717 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1718 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1719 (parallel [(set (match_operand:SI 0 "register_operand" "")
1720 (udiv:SI (reg:SI R4_REG)
1722 (clobber (reg:SI T_REG))
1723 (clobber (reg:SI PR_REG))
1724 (clobber (reg:SI R4_REG))
1725 (use (match_dup 3))])]
1731 operands[3] = gen_reg_rtx (Pmode);
1732 /* Emit the move of the address to a pseudo outside of the libcall. */
1733 if (TARGET_DIVIDE_CALL_TABLE)
1735 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1736 that causes problems when the divide code is supposed to come from a
1737 separate library. Division by zero is undefined, so dividing 1 can be
1738 implemented by comparing with the divisor. */
1739 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1741 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1742 emit_insn (gen_cstoresi4 (operands[0], test,
1743 operands[1], operands[2]));
1746 else if (operands[2] == const0_rtx)
1748 emit_move_insn (operands[0], operands[2]);
1751 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1752 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1754 else if (TARGET_DIVIDE_CALL_FP)
1756 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1757 if (TARGET_FPU_SINGLE)
1758 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1760 last = gen_udivsi3_i4 (operands[0], operands[3]);
1762 else if (TARGET_SHMEDIA_FPU)
1764 operands[1] = force_reg (SImode, operands[1]);
1765 operands[2] = force_reg (SImode, operands[2]);
1766 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1769 else if (TARGET_SH2A)
1771 operands[1] = force_reg (SImode, operands[1]);
1772 operands[2] = force_reg (SImode, operands[2]);
1773 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1776 else if (TARGET_SH5)
1778 function_symbol (operands[3],
1779 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1783 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1784 else if (TARGET_FPU_ANY)
1785 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1787 last = gen_udivsi3_i1 (operands[0], operands[3]);
1791 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1792 last = gen_udivsi3_i1 (operands[0], operands[3]);
1794 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1795 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1800 (define_insn "divsi3_sh2a"
1801 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1802 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1803 (match_operand:SI 2 "arith_reg_operand" "z")))]
1806 [(set_attr "type" "arith")
1807 (set_attr "in_delay_slot" "no")])
1809 (define_insn "divsi3_i1"
1810 [(set (match_operand:SI 0 "register_operand" "=z")
1811 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1812 (clobber (reg:SI T_REG))
1813 (clobber (reg:SI PR_REG))
1814 (clobber (reg:SI R1_REG))
1815 (clobber (reg:SI R2_REG))
1816 (clobber (reg:SI R3_REG))
1817 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1818 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1820 [(set_attr "type" "sfunc")
1821 (set_attr "needs_delay_slot" "yes")])
1823 (define_insn "divsi3_i1_media"
1824 [(set (match_operand:SI 0 "register_operand" "=z")
1825 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1826 (clobber (reg:SI T_MEDIA_REG))
1827 (clobber (reg:SI PR_MEDIA_REG))
1828 (clobber (reg:SI R1_REG))
1829 (clobber (reg:SI R20_REG))
1830 (clobber (reg:SI R21_REG))
1831 (clobber (reg:SI TR0_REG))
1832 (use (match_operand 1 "target_reg_operand" "b"))]
1833 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1835 [(set_attr "type" "sfunc")])
1837 (define_insn "divsi3_media_2"
1838 [(set (match_operand:SI 0 "register_operand" "=z")
1839 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1840 (clobber (reg:SI T_MEDIA_REG))
1841 (clobber (reg:SI PR_MEDIA_REG))
1842 (clobber (reg:SI R1_REG))
1843 (clobber (reg:SI R21_REG))
1844 (clobber (reg:SI TR0_REG))
1845 (use (reg:SI R20_REG))
1846 (use (match_operand 1 "target_reg_operand" "b"))]
1847 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1849 [(set_attr "type" "sfunc")])
1851 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1852 ;; hard reg clobbers and data dependencies that we need when we want
1853 ;; to rematerialize the division into a call.
1854 (define_insn_and_split "divsi_inv_call"
1855 [(set (match_operand:SI 0 "register_operand" "=r")
1856 (div:SI (match_operand:SI 1 "register_operand" "r")
1857 (match_operand:SI 2 "register_operand" "r")))
1858 (clobber (reg:SI R4_REG))
1859 (clobber (reg:SI R5_REG))
1860 (clobber (reg:SI T_MEDIA_REG))
1861 (clobber (reg:SI PR_MEDIA_REG))
1862 (clobber (reg:SI R1_REG))
1863 (clobber (reg:SI R21_REG))
1864 (clobber (reg:SI TR0_REG))
1865 (clobber (reg:SI R20_REG))
1866 (use (match_operand:SI 3 "register_operand" "r"))]
1869 "&& (high_life_started || reload_completed)"
1870 [(set (match_dup 0) (match_dup 3))]
1872 [(set_attr "highpart" "must_split")])
1874 ;; This is the combiner pattern for -mdiv=inv:call .
1875 (define_insn_and_split "*divsi_inv_call_combine"
1876 [(set (match_operand:SI 0 "register_operand" "=z")
1877 (div:SI (match_operand:SI 1 "register_operand" "r")
1878 (match_operand:SI 2 "register_operand" "r")))
1879 (clobber (reg:SI R4_REG))
1880 (clobber (reg:SI R5_REG))
1881 (clobber (reg:SI T_MEDIA_REG))
1882 (clobber (reg:SI PR_MEDIA_REG))
1883 (clobber (reg:SI R1_REG))
1884 (clobber (reg:SI R21_REG))
1885 (clobber (reg:SI TR0_REG))
1886 (clobber (reg:SI R20_REG))
1887 (use (unspec:SI [(match_dup 1)
1888 (match_operand:SI 3 "" "")
1889 (unspec:SI [(match_operand:SI 4 "" "")
1891 (match_operand:DI 5 "" "")]
1893 (match_operand:DI 6 "" "")
1896 UNSPEC_DIV_INV_M3))]
1899 "&& (high_life_started || reload_completed)"
1903 const char *name = sh_divsi3_libfunc;
1904 enum sh_function_kind kind = SFUNC_GOT;
1907 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1908 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1909 while (TARGET_DIVIDE_INV_CALL2)
1911 rtx x = operands[3];
1913 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1915 x = XVECEXP (x, 0, 0);
1916 name = \"__sdivsi3_2\";
1917 kind = SFUNC_STATIC;
1918 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1921 sym = function_symbol (NULL, name, kind);
1922 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1925 [(set_attr "highpart" "must_split")])
1927 (define_expand "divsi3_i4_media"
1928 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1929 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1930 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1931 (set (match_operand:SI 0 "register_operand" "=r")
1932 (fix:SI (match_dup 5)))]
1933 "TARGET_SHMEDIA_FPU"
1936 operands[3] = gen_reg_rtx (DFmode);
1937 operands[4] = gen_reg_rtx (DFmode);
1938 operands[5] = gen_reg_rtx (DFmode);
1941 (define_insn "divsi3_i4"
1942 [(set (match_operand:SI 0 "register_operand" "=y")
1943 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1944 (clobber (reg:SI PR_REG))
1945 (clobber (reg:DF DR0_REG))
1946 (clobber (reg:DF DR2_REG))
1947 (use (reg:PSI FPSCR_REG))
1948 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1949 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1951 [(set_attr "type" "sfunc")
1952 (set_attr "fp_mode" "double")
1953 (set_attr "needs_delay_slot" "yes")])
1955 (define_insn "divsi3_i4_single"
1956 [(set (match_operand:SI 0 "register_operand" "=y")
1957 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1958 (clobber (reg:SI PR_REG))
1959 (clobber (reg:DF DR0_REG))
1960 (clobber (reg:DF DR2_REG))
1961 (clobber (reg:SI R2_REG))
1962 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1963 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1965 [(set_attr "type" "sfunc")
1966 (set_attr "needs_delay_slot" "yes")])
1968 (define_insn "divsi3_i4_int"
1969 [(set (match_operand:SI 0 "register_operand" "=z")
1970 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1971 (clobber (reg:SI T_REG))
1972 (clobber (reg:SI PR_REG))
1973 (clobber (reg:SI R1_REG))
1974 (clobber (reg:SI MACH_REG))
1975 (clobber (reg:SI MACL_REG))
1976 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1979 [(set_attr "type" "sfunc")
1980 (set_attr "needs_delay_slot" "yes")])
1982 (define_expand "divsi3"
1983 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1984 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1985 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1986 (parallel [(set (match_operand:SI 0 "register_operand" "")
1987 (div:SI (reg:SI R4_REG)
1989 (clobber (reg:SI T_REG))
1990 (clobber (reg:SI PR_REG))
1991 (clobber (reg:SI R1_REG))
1992 (clobber (reg:SI R2_REG))
1993 (clobber (reg:SI R3_REG))
1994 (use (match_dup 3))])]
2000 operands[3] = gen_reg_rtx (Pmode);
2001 /* Emit the move of the address to a pseudo outside of the libcall. */
2002 if (TARGET_DIVIDE_CALL_TABLE)
2004 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2005 last = gen_divsi3_i4_int (operands[0], operands[3]);
2007 else if (TARGET_DIVIDE_CALL_FP)
2009 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2010 if (TARGET_FPU_SINGLE)
2011 last = gen_divsi3_i4_single (operands[0], operands[3]);
2013 last = gen_divsi3_i4 (operands[0], operands[3]);
2015 else if (TARGET_SH2A)
2017 operands[1] = force_reg (SImode, operands[1]);
2018 operands[2] = force_reg (SImode, operands[2]);
2019 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2022 else if (TARGET_DIVIDE_INV)
2024 rtx dividend = operands[1];
2025 rtx divisor = operands[2];
2027 rtx nsb_res = gen_reg_rtx (DImode);
2028 rtx norm64 = gen_reg_rtx (DImode);
2029 rtx tab_ix = gen_reg_rtx (DImode);
2030 rtx norm32 = gen_reg_rtx (SImode);
2031 rtx i92 = force_reg (DImode, GEN_INT (92));
2032 rtx scratch0a = gen_reg_rtx (DImode);
2033 rtx scratch0b = gen_reg_rtx (DImode);
2034 rtx inv0 = gen_reg_rtx (SImode);
2035 rtx scratch1a = gen_reg_rtx (DImode);
2036 rtx scratch1b = gen_reg_rtx (DImode);
2037 rtx shift = gen_reg_rtx (DImode);
2039 rtx inv1 = gen_reg_rtx (SImode);
2040 rtx scratch2a = gen_reg_rtx (DImode);
2041 rtx scratch2b = gen_reg_rtx (SImode);
2042 rtx inv2 = gen_reg_rtx (SImode);
2043 rtx scratch3a = gen_reg_rtx (DImode);
2044 rtx scratch3b = gen_reg_rtx (DImode);
2045 rtx scratch3c = gen_reg_rtx (DImode);
2046 rtx scratch3d = gen_reg_rtx (SImode);
2047 rtx scratch3e = gen_reg_rtx (DImode);
2048 rtx result = gen_reg_rtx (SImode);
2050 if (! arith_reg_or_0_operand (dividend, SImode))
2051 dividend = force_reg (SImode, dividend);
2052 if (! arith_reg_operand (divisor, SImode))
2053 divisor = force_reg (SImode, divisor);
2054 if (flag_pic && Pmode != DImode)
2056 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2057 tab_base = gen_datalabel_ref (tab_base);
2058 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2062 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2063 tab_base = gen_datalabel_ref (tab_base);
2064 tab_base = force_reg (DImode, tab_base);
2066 if (TARGET_DIVIDE_INV20U)
2067 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2069 i2p27 = GEN_INT (0);
2070 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2071 i43 = force_reg (DImode, GEN_INT (43));
2074 emit_insn (gen_nsbdi (nsb_res,
2075 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2076 emit_insn (gen_ashldi3_media (norm64,
2077 gen_rtx_SUBREG (DImode, divisor, 0),
2079 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2080 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2081 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2082 inv0, scratch0a, scratch0b,
2083 scratch1a, scratch1b));
2084 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2085 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2087 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2089 scratch3a, scratch3b, scratch3c,
2090 scratch2a, scratch2b, scratch3d, scratch3e));
2091 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2092 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2093 else if (TARGET_DIVIDE_INV_FP)
2094 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2095 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2096 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2097 gen_reg_rtx (DFmode)));
2099 emit_move_insn (operands[0], result);
2102 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2104 operands[1] = force_reg (SImode, operands[1]);
2105 operands[2] = force_reg (SImode, operands[2]);
2106 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2109 else if (TARGET_SH5)
2111 if (TARGET_DIVIDE_CALL2)
2113 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2114 tab_base = gen_datalabel_ref (tab_base);
2115 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2117 if (TARGET_FPU_ANY && TARGET_SH1)
2118 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2119 else if (TARGET_DIVIDE_CALL2)
2120 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2122 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2125 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2126 (operands[0], operands[3]));
2127 else if (TARGET_FPU_ANY)
2128 last = gen_divsi3_i4_single (operands[0], operands[3]);
2130 last = gen_divsi3_i1 (operands[0], operands[3]);
2134 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2135 last = gen_divsi3_i1 (operands[0], operands[3]);
2137 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2138 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2143 ;; operands: scratch, tab_base, tab_ix
2144 ;; These are unspecs because we could generate an indexed addressing mode
2145 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2146 ;; confuse reload. See PR27117.
2148 (define_insn "divsi_inv_qitable"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2150 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2151 (match_operand:DI 2 "register_operand" "r")]
2152 UNSPEC_DIV_INV_TABLE)))]
2156 [(set_attr "type" "load_media")
2157 (set_attr "highpart" "user")])
2159 ;; operands: scratch, tab_base, tab_ix
2160 (define_insn "divsi_inv_hitable"
2161 [(set (match_operand:DI 0 "register_operand" "=r")
2162 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2163 (match_operand:DI 2 "register_operand" "r")]
2164 UNSPEC_DIV_INV_TABLE)))]
2168 [(set_attr "type" "load_media")
2169 (set_attr "highpart" "user")])
2171 ;; operands: inv0, tab_base, tab_ix, norm32
2172 ;; scratch equiv in sdivsi3_2: r19, r21
2173 (define_expand "divsi_inv_m0"
2174 [(set (match_operand:SI 0 "register_operand" "=r")
2175 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2176 (match_operand:DI 2 "register_operand" "r")
2177 (match_operand:SI 3 "register_operand" "r")]
2179 (clobber (match_operand:DI 4 "register_operand" "=r"))
2180 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2188 ldx.ub r20, r21, r19 // u0.8
2190 muls.l r25, r19, r19 // s2.38
2191 ldx.w r20, r21, r21 // s2.14
2192 shari r19, 24, r19 // truncate to s2.14
2193 sub r21, r19, r19 // some 11 bit inverse in s1.14
2196 rtx inv0 = operands[0];
2197 rtx tab_base = operands[1];
2198 rtx tab_ix = operands[2];
2199 rtx norm32 = operands[3];
2200 rtx scratch0 = operands[4];
2201 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2202 rtx scratch1 = operands[5];
2204 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2205 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2206 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2207 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2208 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2209 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2213 ;; operands: inv1, tab_base, tab_ix, norm32
2214 (define_insn_and_split "divsi_inv_m1"
2215 [(set (match_operand:SI 0 "register_operand" "=r")
2216 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2217 (match_operand:DI 2 "register_operand" "r")
2218 (match_operand:SI 3 "register_operand" "r")]
2220 (clobber (match_operand:SI 4 "register_operand" "=r"))
2221 (clobber (match_operand:DI 5 "register_operand" "=r"))
2222 (clobber (match_operand:DI 6 "register_operand" "=r"))
2223 (clobber (match_operand:DI 7 "register_operand" "=r"))
2224 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2227 "&& !can_create_pseudo_p ()"
2232 muls.l r19, r19, r18 // u0.28
2233 muls.l r25, r18, r18 // s2.58
2234 shlli r19, 45, r0 // multiply by two and convert to s2.58
2236 shari r18, 28, r18 // some 18 bit inverse in s1.30
2239 rtx inv1 = operands[0];
2240 rtx tab_base = operands[1];
2241 rtx tab_ix = operands[2];
2242 rtx norm32 = operands[3];
2243 rtx inv0 = operands[4];
2244 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2245 rtx scratch0a = operands[5];
2246 rtx scratch0b = operands[6];
2247 rtx scratch0 = operands[7];
2248 rtx scratch1 = operands[8];
2249 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2251 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2252 scratch0a, scratch0b));
2253 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2254 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2255 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2256 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2257 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2261 ;; operands: inv2, norm32, inv1, i92
2262 (define_insn_and_split "divsi_inv_m2"
2263 [(set (match_operand:SI 0 "register_operand" "=r")
2264 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2265 (match_operand:SI 2 "register_operand" "r")
2266 (match_operand:DI 3 "register_operand" "r")]
2268 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2271 "&& !can_create_pseudo_p ()"
2276 muls.l r18, r25, r0 // s2.60
2277 shari r0, 16, r0 // s-16.44
2279 muls.l r0, r18, r19 // s-16.74
2280 shari r19, 30, r19 // s-16.44
2282 rtx inv2 = operands[0];
2283 rtx norm32 = operands[1];
2284 rtx inv1 = operands[2];
2285 rtx i92 = operands[3];
2286 rtx scratch0 = operands[4];
2287 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2289 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2290 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2291 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2292 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2293 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2297 (define_insn_and_split "divsi_inv_m3"
2298 [(set (match_operand:SI 0 "register_operand" "=r")
2299 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2300 (match_operand:SI 2 "register_operand" "r")
2301 (match_operand:SI 3 "register_operand" "r")
2302 (match_operand:DI 4 "register_operand" "r")
2303 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2304 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2306 (clobber (match_operand:DI 7 "register_operand" "=r"))
2307 (clobber (match_operand:DI 8 "register_operand" "=r"))
2308 (clobber (match_operand:DI 9 "register_operand" "=r"))
2309 (clobber (match_operand:DI 10 "register_operand" "=r"))
2310 (clobber (match_operand:SI 11 "register_operand" "=r"))
2311 (clobber (match_operand:SI 12 "register_operand" "=r"))
2312 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2315 "&& !can_create_pseudo_p ()"
2320 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2321 r0: scratch0 r19: scratch1 r21: scratch2
2323 muls.l r18, r4, r25 // s32.30
2324 muls.l r19, r4, r19 // s15.30
2326 shari r19, 14, r19 // s18.-14
2332 rtx result = operands[0];
2333 rtx dividend = operands[1];
2334 rtx inv1 = operands[2];
2335 rtx inv2 = operands[3];
2336 rtx shift = operands[4];
2337 rtx scratch0 = operands[7];
2338 rtx scratch1 = operands[8];
2339 rtx scratch2 = operands[9];
2341 if (satisfies_constraint_N (dividend))
2343 emit_move_insn (result, dividend);
2347 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2348 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2349 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2350 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2351 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2352 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2353 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2357 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2358 ;; inv1: tab_base, tab_ix, norm32
2359 ;; inv2: norm32, inv1, i92
2360 (define_insn_and_split "divsi_inv_m1_3"
2361 [(set (match_operand:SI 0 "register_operand" "=r")
2362 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2363 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2364 (match_operand:DI 3 "register_operand" "r")
2365 (match_operand:SI 4 "register_operand" "r")]
2367 (unspec:SI [(match_dup 4)
2368 (unspec:SI [(match_dup 2)
2370 (match_dup 4)] UNSPEC_DIV_INV_M1)
2371 (match_operand:SI 5 "" "")]
2373 (match_operand:DI 6 "register_operand" "r")
2374 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2375 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2377 (clobber (match_operand:DI 9 "register_operand" "=r"))
2378 (clobber (match_operand:DI 10 "register_operand" "=r"))
2379 (clobber (match_operand:DI 11 "register_operand" "=r"))
2380 (clobber (match_operand:DI 12 "register_operand" "=r"))
2381 (clobber (match_operand:SI 13 "register_operand" "=r"))
2382 (clobber (match_operand:SI 14 "register_operand" "=r"))
2383 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2385 && (TARGET_DIVIDE_INV_MINLAT
2386 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2388 "&& !can_create_pseudo_p ()"
2392 rtx result = operands[0];
2393 rtx dividend = operands[1];
2394 rtx tab_base = operands[2];
2395 rtx tab_ix = operands[3];
2396 rtx norm32 = operands[4];
2397 /* rtx i92 = operands[5]; */
2398 rtx shift = operands[6];
2399 rtx i2p27 = operands[7];
2400 rtx i43 = operands[8];
2401 rtx scratch0 = operands[9];
2402 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2403 rtx scratch1 = operands[10];
2404 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2405 rtx scratch2 = operands[11];
2406 rtx scratch3 = operands[12];
2407 rtx scratch4 = operands[13];
2408 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2409 rtx scratch5 = operands[14];
2410 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2411 rtx scratch6 = operands[15];
2413 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2414 scratch0, scratch1));
2415 /* inv0 == scratch4 */
2416 if (! TARGET_DIVIDE_INV20U)
2418 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2420 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2424 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2425 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2427 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2428 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2429 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2430 /* inv1 == scratch4 */
2432 if (TARGET_DIVIDE_INV_MINLAT)
2434 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2435 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2436 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2437 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2438 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2439 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2440 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2441 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2442 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2443 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2444 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2448 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2449 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2450 emit_insn (gen_nsbdi (scratch6,
2451 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2452 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2453 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2454 emit_insn (gen_divsi_inv20 (scratch2,
2455 norm32, scratch4, dividend,
2456 scratch6, scratch3, i43,
2457 /* scratch0 may be shared with i2p27. */
2458 scratch0, scratch1, scratch5,
2459 label, label, i2p27));
2461 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2462 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2466 (define_insn "divsi_inv20"
2467 [(set (match_operand:DI 0 "register_operand" "=&r")
2468 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2469 (match_operand:SI 2 "register_operand" "r")
2470 (match_operand:SI 3 "register_operand" "r")
2471 (match_operand:DI 4 "register_operand" "r")
2472 (match_operand:DI 5 "register_operand" "r")
2473 (match_operand:DI 6 "register_operand" "r")
2474 (match_operand:DI 12 "register_operand" "r")
2475 (match_operand 10 "target_operand" "b")
2476 (match_operand 11 "immediate_operand" "i")]
2478 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2479 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2480 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2482 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2485 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2486 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2487 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2488 %10 label (tr), %11 label (imm)
2490 muls.l inv1, norm32, scratch0 // s2.60
2491 muls.l inv1, dividend, result // s32.30
2492 xor i2p27, result_sign, round_scratch
2493 bge/u dividend_nsb, i43, tr.. (label)
2494 shari scratch0, 16, scratch0 // s-16.44
2495 muls.l sratch0_si, inv1, scratch0 // s-16.74
2496 sub result, round_scratch, result
2497 shari dividend, 14, scratch1 // s19.-14
2498 shari scratch0, 30, scratch0 // s-16.44
2499 muls.l scratch0, scratch1, round_scratch // s15.30
2501 sub result, round_scratch, result */
2503 int likely = TARGET_DIVIDE_INV20L;
2505 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2506 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2507 output_asm_insn (likely
2508 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2509 : \"bge/u\t%4, %6, %10\", operands);
2510 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2511 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2512 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2514 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2515 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2518 (define_insn_and_split "divsi_inv_fp"
2519 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2520 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2521 (match_operand:SI 2 "register_operand" "rf")))
2522 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2523 (clobber (match_operand:SI 4 "register_operand" "=r"))
2524 (clobber (match_operand:SI 5 "register_operand" "=r"))
2525 (clobber (match_operand:DF 6 "register_operand" "=r"))
2526 (clobber (match_operand:DF 7 "register_operand" "=r"))
2527 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2528 "TARGET_SHMEDIA_FPU"
2530 "&& (high_life_started || reload_completed)"
2531 [(set (match_dup 0) (match_dup 3))]
2533 [(set_attr "highpart" "must_split")])
2535 ;; If a matching group of divide-by-inverse instructions is in the same
2536 ;; basic block after gcse & loop optimizations, we want to transform them
2537 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2538 (define_insn_and_split "*divsi_inv_fp_combine"
2539 [(set (match_operand:SI 0 "register_operand" "=f")
2540 (div:SI (match_operand:SI 1 "register_operand" "f")
2541 (match_operand:SI 2 "register_operand" "f")))
2542 (use (unspec:SI [(match_dup 1)
2543 (match_operand:SI 3 "" "")
2544 (unspec:SI [(match_operand:SI 4 "" "")
2546 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2547 (match_operand:DI 6 "" "")
2549 (const_int 0)] UNSPEC_DIV_INV_M3))
2550 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2551 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2552 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2553 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2554 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2555 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2558 [(set (match_dup 9) (float:DF (match_dup 1)))
2559 (set (match_dup 10) (float:DF (match_dup 2)))
2560 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2562 (fix:SI (match_dup 11)))
2563 (set (match_dup 0) (match_dup 8))]
2566 if (! fp_arith_reg_operand (operands[1], SImode))
2568 emit_move_insn (operands[7], operands[1]);
2569 operands[1] = operands[7];
2571 if (! fp_arith_reg_operand (operands[2], SImode))
2573 emit_move_insn (operands[8], operands[2]);
2574 operands[2] = operands[8];
2577 [(set_attr "highpart" "must_split")])
2579 ;; -------------------------------------------------------------------------
2580 ;; Multiplication instructions
2581 ;; -------------------------------------------------------------------------
2583 (define_insn "umulhisi3_i"
2584 [(set (reg:SI MACL_REG)
2585 (mult:SI (zero_extend:SI
2586 (match_operand:HI 0 "arith_reg_operand" "r"))
2588 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2591 [(set_attr "type" "smpy")])
2593 (define_insn "mulhisi3_i"
2594 [(set (reg:SI MACL_REG)
2595 (mult:SI (sign_extend:SI
2596 (match_operand:HI 0 "arith_reg_operand" "r"))
2598 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2601 [(set_attr "type" "smpy")])
2603 (define_expand "mulhisi3"
2604 [(set (reg:SI MACL_REG)
2605 (mult:SI (sign_extend:SI
2606 (match_operand:HI 1 "arith_reg_operand" ""))
2608 (match_operand:HI 2 "arith_reg_operand" ""))))
2609 (set (match_operand:SI 0 "arith_reg_operand" "")
2616 macl = gen_rtx_REG (SImode, MACL_REG);
2618 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2619 insn = get_insns ();
2621 /* expand_binop can't find a suitable code in umul_widen_optab to
2622 make a REG_EQUAL note from, so make one here.
2623 See also smulsi3_highpart.
2624 ??? Alternatively, we could put this at the calling site of expand_binop,
2625 i.e. expand_expr. */
2626 /* Use emit_libcall_block for loop invariant code motion and to make
2627 a REG_EQUAL note. */
2628 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2633 (define_expand "umulhisi3"
2634 [(set (reg:SI MACL_REG)
2635 (mult:SI (zero_extend:SI
2636 (match_operand:HI 1 "arith_reg_operand" ""))
2638 (match_operand:HI 2 "arith_reg_operand" ""))))
2639 (set (match_operand:SI 0 "arith_reg_operand" "")
2646 macl = gen_rtx_REG (SImode, MACL_REG);
2648 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2649 insn = get_insns ();
2651 /* expand_binop can't find a suitable code in umul_widen_optab to
2652 make a REG_EQUAL note from, so make one here.
2653 See also smulsi3_highpart.
2654 ??? Alternatively, we could put this at the calling site of expand_binop,
2655 i.e. expand_expr. */
2656 /* Use emit_libcall_block for loop invariant code motion and to make
2657 a REG_EQUAL note. */
2658 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2663 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2664 ;; a call to a routine which clobbers known registers.
2667 [(set (match_operand:SI 1 "register_operand" "=z")
2668 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2669 (clobber (reg:SI MACL_REG))
2670 (clobber (reg:SI T_REG))
2671 (clobber (reg:SI PR_REG))
2672 (clobber (reg:SI R3_REG))
2673 (clobber (reg:SI R2_REG))
2674 (clobber (reg:SI R1_REG))
2675 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2678 [(set_attr "type" "sfunc")
2679 (set_attr "needs_delay_slot" "yes")])
2681 (define_expand "mulsi3_call"
2682 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2683 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2684 (parallel[(set (match_operand:SI 0 "register_operand" "")
2685 (mult:SI (reg:SI R4_REG)
2687 (clobber (reg:SI MACL_REG))
2688 (clobber (reg:SI T_REG))
2689 (clobber (reg:SI PR_REG))
2690 (clobber (reg:SI R3_REG))
2691 (clobber (reg:SI R2_REG))
2692 (clobber (reg:SI R1_REG))
2693 (use (match_operand:SI 3 "register_operand" ""))])]
2697 (define_insn "mul_r"
2698 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2699 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2700 (match_operand:SI 2 "arith_reg_operand" "z")))]
2703 [(set_attr "type" "dmpy")])
2705 (define_insn "mul_l"
2706 [(set (reg:SI MACL_REG)
2707 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2708 (match_operand:SI 1 "arith_reg_operand" "r")))]
2711 [(set_attr "type" "dmpy")])
2713 (define_expand "mulsi3"
2714 [(set (reg:SI MACL_REG)
2715 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2716 (match_operand:SI 2 "arith_reg_operand" "")))
2717 (set (match_operand:SI 0 "arith_reg_operand" "")
2724 /* The address must be set outside the libcall,
2725 since it goes into a pseudo. */
2726 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2727 rtx addr = force_reg (SImode, sym);
2728 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2734 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2736 emit_insn (gen_mul_l (operands[1], operands[2]));
2737 /* consec_sets_giv can only recognize the first insn that sets a
2738 giv as the giv insn. So we must tag this also with a REG_EQUAL
2740 emit_insn (gen_movsi_i ((operands[0]), macl));
2745 (define_insn "mulsidi3_i"
2746 [(set (reg:SI MACH_REG)
2750 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2751 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2753 (set (reg:SI MACL_REG)
2754 (mult:SI (match_dup 0)
2758 [(set_attr "type" "dmpy")])
2760 (define_expand "mulsidi3"
2761 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2762 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2763 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2764 "TARGET_SH2 || TARGET_SHMEDIA"
2769 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2775 (define_insn "mulsidi3_media"
2776 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2777 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2778 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2781 [(set_attr "type" "dmpy_media")
2782 (set_attr "highpart" "ignore")])
2784 (define_insn "mulsidi3_compact"
2785 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2787 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2788 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2789 (clobber (reg:SI MACH_REG))
2790 (clobber (reg:SI MACL_REG))]
2795 [(set (match_operand:DI 0 "arith_reg_dest" "")
2797 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2798 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2799 (clobber (reg:SI MACH_REG))
2800 (clobber (reg:SI MACL_REG))]
2805 rtx low_dst = gen_lowpart (SImode, operands[0]);
2806 rtx high_dst = gen_highpart (SImode, operands[0]);
2808 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2810 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2811 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2812 /* We need something to tag the possible REG_EQUAL notes on to. */
2813 emit_move_insn (operands[0], operands[0]);
2817 (define_insn "umulsidi3_i"
2818 [(set (reg:SI MACH_REG)
2822 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2823 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2825 (set (reg:SI MACL_REG)
2826 (mult:SI (match_dup 0)
2830 [(set_attr "type" "dmpy")])
2832 (define_expand "umulsidi3"
2833 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2834 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2835 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2836 "TARGET_SH2 || TARGET_SHMEDIA"
2841 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2847 (define_insn "umulsidi3_media"
2848 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2849 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2850 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2853 [(set_attr "type" "dmpy_media")
2854 (set_attr "highpart" "ignore")])
2856 (define_insn "umulsidi3_compact"
2857 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2859 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2860 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2861 (clobber (reg:SI MACH_REG))
2862 (clobber (reg:SI MACL_REG))]
2867 [(set (match_operand:DI 0 "arith_reg_dest" "")
2868 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2869 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2870 (clobber (reg:SI MACH_REG))
2871 (clobber (reg:SI MACL_REG))]
2876 rtx low_dst = gen_lowpart (SImode, operands[0]);
2877 rtx high_dst = gen_highpart (SImode, operands[0]);
2879 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2881 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2882 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2883 /* We need something to tag the possible REG_EQUAL notes on to. */
2884 emit_move_insn (operands[0], operands[0]);
2888 (define_insn "smulsi3_highpart_i"
2889 [(set (reg:SI MACH_REG)
2893 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2894 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2896 (clobber (reg:SI MACL_REG))]
2899 [(set_attr "type" "dmpy")])
2901 (define_expand "smulsi3_highpart"
2903 [(set (reg:SI MACH_REG)
2907 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2908 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2910 (clobber (reg:SI MACL_REG))])
2911 (set (match_operand:SI 0 "arith_reg_operand" "")
2918 mach = gen_rtx_REG (SImode, MACH_REG);
2920 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2921 insn = get_insns ();
2923 /* expand_binop can't find a suitable code in mul_highpart_optab to
2924 make a REG_EQUAL note from, so make one here.
2925 See also {,u}mulhisi.
2926 ??? Alternatively, we could put this at the calling site of expand_binop,
2927 i.e. expand_mult_highpart. */
2928 /* Use emit_libcall_block for loop invariant code motion and to make
2929 a REG_EQUAL note. */
2930 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2935 (define_insn "umulsi3_highpart_i"
2936 [(set (reg:SI MACH_REG)
2940 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2941 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2943 (clobber (reg:SI MACL_REG))]
2946 [(set_attr "type" "dmpy")])
2948 (define_expand "umulsi3_highpart"
2950 [(set (reg:SI MACH_REG)
2954 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2955 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2957 (clobber (reg:SI MACL_REG))])
2958 (set (match_operand:SI 0 "arith_reg_operand" "")
2965 mach = gen_rtx_REG (SImode, MACH_REG);
2967 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2968 insn = get_insns ();
2970 /* Use emit_libcall_block for loop invariant code motion and to make
2971 a REG_EQUAL note. */
2972 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2977 (define_insn_and_split "muldi3"
2978 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2979 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2980 (match_operand:DI 2 "arith_reg_operand" "r")))
2981 (clobber (match_scratch:DI 3 "=&r"))
2982 (clobber (match_scratch:DI 4 "=r"))]
2989 rtx op3_v2si, op2_v2si;
2991 op3_v2si = operands[3];
2992 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2994 op3_v2si = XEXP (op3_v2si, 0);
2995 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2997 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2998 op2_v2si = operands[2];
2999 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3001 op2_v2si = XEXP (op2_v2si, 0);
3002 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3004 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3005 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3006 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3007 emit_insn (gen_umulsidi3_media (operands[4],
3008 sh_gen_truncate (SImode, operands[1], 0),
3009 sh_gen_truncate (SImode, operands[2], 0)));
3010 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3011 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3012 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3013 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3018 ;; -------------------------------------------------------------------------
3019 ;; Logical operations
3020 ;; -------------------------------------------------------------------------
3022 (define_insn "*andsi3_compact"
3023 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3024 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3025 (match_operand:SI 2 "logical_operand" "r,K08")))]
3028 [(set_attr "type" "arith")])
3030 (define_insn "*andsi3_media"
3031 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3032 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3033 (match_operand:SI 2 "logical_operand" "r,I10")))]
3038 [(set_attr "type" "arith_media")])
3040 (define_insn "*andsi3_bclr"
3041 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3042 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3043 (match_operand:SI 2 "const_int_operand" "Psz")))]
3044 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3046 [(set_attr "type" "arith")])
3048 ;; If the constant is 255, then emit an extu.b instruction instead of an
3049 ;; and, since that will give better code.
3051 (define_expand "andsi3"
3052 [(set (match_operand:SI 0 "arith_reg_operand" "")
3053 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3054 (match_operand:SI 2 "logical_operand" "")))]
3059 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3061 emit_insn (gen_zero_extendqisi2 (operands[0],
3062 gen_lowpart (QImode, operands[1])));
3067 (define_insn_and_split "anddi3"
3068 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3069 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3070 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3077 && ! logical_operand (operands[2], DImode)"
3081 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3082 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3084 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3087 [(set_attr "type" "arith_media")])
3089 (define_insn "andcsi3"
3090 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3091 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3092 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3095 [(set_attr "type" "arith_media")])
3097 (define_insn "andcdi3"
3098 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3099 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3100 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3103 [(set_attr "type" "arith_media")])
3105 (define_expand "iorsi3"
3106 [(set (match_operand:SI 0 "arith_reg_operand" "")
3107 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3108 (match_operand:SI 2 "logical_operand" "")))]
3112 (define_insn "*iorsi3_compact"
3113 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3114 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3115 (match_operand:SI 2 "logical_operand" "r,K08")))]
3117 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3119 [(set_attr "type" "arith")])
3121 (define_insn "*iorsi3_media"
3122 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3123 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3124 (match_operand:SI 2 "logical_operand" "r,I10")))]
3129 [(set_attr "type" "arith_media")])
3131 (define_insn "*iorsi3_bset"
3132 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3133 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3134 (match_operand:SI 2 "const_int_operand" "Pso")))]
3135 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3137 [(set_attr "type" "arith")])
3139 (define_insn "iordi3"
3140 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3141 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3142 (match_operand:DI 2 "logical_operand" "r,I10")))]
3147 [(set_attr "type" "arith_media")])
3149 (define_insn_and_split "*logical_sidi3"
3150 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3151 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3152 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3153 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3156 "&& reload_completed"
3157 [(set (match_dup 0) (match_dup 3))]
3161 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3162 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3163 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3166 (define_insn_and_split "*logical_sidisi3"
3167 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3168 (truncate:SI (sign_extend:DI
3169 (match_operator:SI 3 "logical_operator"
3170 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3171 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3175 [(set (match_dup 0) (match_dup 3))])
3177 (define_insn_and_split "*logical_sidi3_2"
3178 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3179 (sign_extend:DI (truncate:SI (sign_extend:DI
3180 (match_operator:SI 3 "logical_operator"
3181 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3182 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3186 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3188 (define_expand "xorsi3"
3189 [(set (match_operand:SI 0 "arith_reg_operand" "")
3190 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3191 (match_operand:SI 2 "xor_operand" "")))]
3195 (define_insn "*xorsi3_compact"
3196 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3197 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3198 (match_operand:SI 2 "logical_operand" "K08,r")))]
3201 [(set_attr "type" "arith")])
3203 (define_insn "*xorsi3_media"
3204 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3205 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3206 (match_operand:SI 2 "xor_operand" "r,I06")))]
3211 [(set_attr "type" "arith_media")])
3213 ;; Store the complements of the T bit in a register.
3214 (define_insn "xorsi3_movrt"
3215 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3216 (xor:SI (reg:SI T_REG)
3220 [(set_attr "type" "arith")])
3222 (define_insn "xordi3"
3223 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3224 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3225 (match_operand:DI 2 "xor_operand" "r,I06")))]
3230 [(set_attr "type" "arith_media")])
3232 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3233 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3235 [(set (match_operand:DI 0 "arith_reg_dest" "")
3236 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3237 [(match_operand 1 "any_register_operand" "")
3238 (match_operand 2 "any_register_operand" "")])))]
3240 [(set (match_dup 5) (match_dup 4))
3241 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3244 enum machine_mode inmode = GET_MODE (operands[1]);
3247 if (GET_CODE (operands[0]) == SUBREG)
3249 offset = SUBREG_BYTE (operands[0]);
3250 operands[0] = SUBREG_REG (operands[0]);
3252 gcc_assert (REG_P (operands[0]));
3253 if (! TARGET_LITTLE_ENDIAN)
3254 offset += 8 - GET_MODE_SIZE (inmode);
3255 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3258 ;; -------------------------------------------------------------------------
3259 ;; Shifts and rotates
3260 ;; -------------------------------------------------------------------------
3262 (define_expand "rotldi3"
3263 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3264 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3265 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3267 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3269 (define_insn "rotldi3_mextr"
3270 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3271 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3272 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3276 static char templ[16];
3278 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3279 8 - (int) (INTVAL (operands[2]) >> 3));
3282 [(set_attr "type" "arith_media")])
3284 (define_expand "rotrdi3"
3285 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3286 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3287 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3289 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3291 (define_insn "rotrdi3_mextr"
3292 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3293 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3294 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3298 static char templ[16];
3300 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3303 [(set_attr "type" "arith_media")])
3306 [(set (match_operand:DI 0 "arith_reg_dest" "")
3307 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3308 "ua_address_operand" "")))
3309 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3311 (clobber (match_operand:DI 3 "register_operand" ""))]
3313 [(match_dup 4) (match_dup 5)]
3316 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3317 (operands[3], operands[1]));
3318 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3319 GEN_INT (56), GEN_INT (8));
3322 (define_insn "rotlsi3_1"
3323 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3324 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3327 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3330 [(set_attr "type" "arith")])
3332 (define_insn "rotlsi3_31"
3333 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3334 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3336 (clobber (reg:SI T_REG))]
3339 [(set_attr "type" "arith")])
3341 (define_insn "rotlsi3_16"
3342 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3343 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3347 [(set_attr "type" "arith")])
3349 (define_expand "rotlsi3"
3350 [(set (match_operand:SI 0 "arith_reg_dest" "")
3351 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3352 (match_operand:SI 2 "immediate_operand" "")))]
3356 static const char rot_tab[] = {
3357 000, 000, 000, 000, 000, 000, 010, 001,
3358 001, 001, 011, 013, 003, 003, 003, 003,
3359 003, 003, 003, 003, 003, 013, 012, 002,
3360 002, 002, 010, 000, 000, 000, 000, 000,
3365 if (!CONST_INT_P (operands[2]))
3367 count = INTVAL (operands[2]);
3368 choice = rot_tab[count];
3369 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3375 emit_move_insn (operands[0], operands[1]);
3376 count -= (count & 16) * 2;
3379 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3386 parts[0] = gen_reg_rtx (SImode);
3387 parts[1] = gen_reg_rtx (SImode);
3388 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3389 emit_move_insn (parts[choice-1], operands[1]);
3390 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3391 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3392 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3393 count = (count & ~16) - 8;
3397 for (; count > 0; count--)
3398 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3399 for (; count < 0; count++)
3400 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3405 (define_insn "*rotlhi3_8"
3406 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3407 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3411 [(set_attr "type" "arith")])
3413 (define_expand "rotlhi3"
3414 [(set (match_operand:HI 0 "arith_reg_operand" "")
3415 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3416 (match_operand:HI 2 "immediate_operand" "")))]
3420 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3427 (define_insn "ashlsi3_sh2a"
3428 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3429 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3430 (match_operand:SI 2 "arith_reg_operand" "r")))]
3433 [(set_attr "type" "arith")
3434 (set_attr "length" "4")])
3436 ;; This pattern is used by init_expmed for computing the costs of shift
3439 (define_insn_and_split "ashlsi3_std"
3440 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3441 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3442 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3443 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3445 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3453 && CONST_INT_P (operands[2])
3454 && ! satisfies_constraint_P27 (operands[2])"
3455 [(set (match_dup 3) (match_dup 2))
3457 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3458 (clobber (match_dup 4))])]
3459 "operands[4] = gen_rtx_SCRATCH (SImode);"
3460 [(set_attr "length" "*,*,*,4")
3461 (set_attr "type" "dyn_shift,arith,arith,arith")])
3463 (define_insn "ashlhi3_k"
3464 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3465 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3466 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3467 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3471 [(set_attr "type" "arith")])
3473 (define_insn "ashlsi3_n"
3474 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3475 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3476 (match_operand:SI 2 "const_int_operand" "n")))
3477 (clobber (reg:SI T_REG))]
3478 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3480 [(set (attr "length")
3481 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3483 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3485 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3487 (const_string "8")))
3488 (set_attr "type" "arith")])
3491 [(set (match_operand:SI 0 "arith_reg_dest" "")
3492 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3493 (match_operand:SI 2 "const_int_operand" "")))
3494 (clobber (reg:SI T_REG))]
3495 "TARGET_SH1 && reload_completed"
3496 [(use (reg:SI R0_REG))]
3499 gen_shifty_op (ASHIFT, operands);
3503 (define_insn "ashlsi3_media"
3504 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3505 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3506 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3511 [(set_attr "type" "arith_media")
3512 (set_attr "highpart" "ignore")])
3514 (define_expand "ashlsi3"
3515 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3516 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3517 (match_operand:SI 2 "nonmemory_operand" "")))
3518 (clobber (reg:SI T_REG))])]
3524 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3527 if (CONST_INT_P (operands[2])
3528 && sh_dynamicalize_shift_p (operands[2]))
3529 operands[2] = force_reg (SImode, operands[2]);
3532 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3535 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3539 (define_insn "*ashlhi3_n"
3540 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3541 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3542 (match_operand:HI 2 "const_int_operand" "n")))
3543 (clobber (reg:SI T_REG))]
3546 [(set (attr "length")
3547 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3549 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3551 (const_string "6")))
3552 (set_attr "type" "arith")])
3554 (define_expand "ashlhi3"
3555 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3556 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3557 (match_operand:SI 2 "nonmemory_operand" "")))
3558 (clobber (reg:SI T_REG))])]
3562 if (!CONST_INT_P (operands[2]))
3564 /* It may be possible to call gen_ashlhi3 directly with more generic
3565 operands. Make sure operands[1] is a HImode register here. */
3566 if (!arith_reg_operand (operands[1], HImode))
3567 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3571 [(set (match_operand:HI 0 "arith_reg_dest" "")
3572 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3573 (match_operand:HI 2 "const_int_operand" "")))
3574 (clobber (reg:SI T_REG))]
3575 "TARGET_SH1 && reload_completed"
3576 [(use (reg:SI R0_REG))]
3579 gen_shifty_hi_op (ASHIFT, operands);
3584 ; arithmetic shift right
3587 (define_insn "ashrsi3_sh2a"
3588 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3589 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3590 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3593 [(set_attr "type" "dyn_shift")
3594 (set_attr "length" "4")])
3596 (define_insn "ashrsi3_k"
3597 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3598 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3599 (match_operand:SI 2 "const_int_operand" "M")))
3600 (clobber (reg:SI T_REG))]
3601 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3603 [(set_attr "type" "arith")])
3605 ;; We can't do HImode right shifts correctly unless we start out with an
3606 ;; explicit zero / sign extension; doing that would result in worse overall
3607 ;; code, so just let the machine independent code widen the mode.
3608 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3611 ;; ??? This should be a define expand.
3613 (define_insn "ashrsi2_16"
3614 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3615 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3619 [(set_attr "length" "4")])
3622 [(set (match_operand:SI 0 "arith_reg_dest" "")
3623 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3626 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3627 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3628 "operands[2] = gen_lowpart (HImode, operands[0]);")
3630 ;; ??? This should be a define expand.
3632 (define_insn "ashrsi2_31"
3633 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3634 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3636 (clobber (reg:SI T_REG))]
3639 [(set_attr "length" "4")])
3642 [(set (match_operand:SI 0 "arith_reg_dest" "")
3643 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3645 (clobber (reg:SI T_REG))]
3650 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3651 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3656 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3658 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3660 && peep2_reg_dead_p (2, operands[0])
3661 && peep2_reg_dead_p (2, operands[1])"
3665 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3669 (define_insn "ashlsi_c"
3670 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3671 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3673 (lt:SI (match_dup 1) (const_int 0)))]
3676 [(set_attr "type" "arith")])
3678 (define_insn "*ashlsi_c_void"
3679 [(set (reg:SI T_REG)
3680 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3681 (clobber (match_scratch:SI 1 "=0"))]
3682 "TARGET_SH1 && cse_not_expected"
3684 [(set_attr "type" "arith")])
3686 (define_insn "ashrsi3_d"
3687 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3688 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3689 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3692 [(set_attr "type" "dyn_shift")])
3694 (define_insn "ashrsi3_n"
3695 [(set (reg:SI R4_REG)
3696 (ashiftrt:SI (reg:SI R4_REG)
3697 (match_operand:SI 0 "const_int_operand" "i")))
3698 (clobber (reg:SI T_REG))
3699 (clobber (reg:SI PR_REG))
3700 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3703 [(set_attr "type" "sfunc")
3704 (set_attr "needs_delay_slot" "yes")])
3706 (define_insn "ashrsi3_media"
3707 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3708 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3709 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3714 [(set_attr "type" "arith_media")
3715 (set_attr "highpart" "ignore")])
3717 (define_expand "ashrsi3"
3718 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3719 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3720 (match_operand:SI 2 "nonmemory_operand" "")))
3721 (clobber (reg:SI T_REG))])]
3727 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3730 if (expand_ashiftrt (operands))
3736 ;; logical shift right
3738 (define_insn "lshrsi3_sh2a"
3739 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3740 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3741 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3744 [(set_attr "type" "dyn_shift")
3745 (set_attr "length" "4")])
3747 (define_insn "lshrsi3_d"
3748 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3749 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3750 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3753 [(set_attr "type" "dyn_shift")])
3755 ;; Only the single bit shift clobbers the T bit.
3757 (define_insn "lshrsi3_m"
3758 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3759 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3760 (match_operand:SI 2 "const_int_operand" "M")))
3761 (clobber (reg:SI T_REG))]
3762 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3764 [(set_attr "type" "arith")])
3766 (define_insn "lshrsi3_k"
3767 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3768 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3769 (match_operand:SI 2 "const_int_operand" "P27")))]
3770 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3771 && ! satisfies_constraint_M (operands[2])"
3773 [(set_attr "type" "arith")])
3775 (define_insn "lshrsi3_n"
3776 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3777 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3778 (match_operand:SI 2 "const_int_operand" "n")))
3779 (clobber (reg:SI T_REG))]
3780 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3782 [(set (attr "length")
3783 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3785 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3787 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3789 (const_string "8")))
3790 (set_attr "type" "arith")])
3793 [(set (match_operand:SI 0 "arith_reg_dest" "")
3794 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3795 (match_operand:SI 2 "const_int_operand" "")))
3796 (clobber (reg:SI T_REG))]
3797 "TARGET_SH1 && reload_completed"
3798 [(use (reg:SI R0_REG))]
3801 gen_shifty_op (LSHIFTRT, operands);
3805 (define_insn "lshrsi3_media"
3806 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3807 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3808 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3813 [(set_attr "type" "arith_media")
3814 (set_attr "highpart" "ignore")])
3816 (define_expand "lshrsi3"
3817 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3818 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3819 (match_operand:SI 2 "nonmemory_operand" "")))
3820 (clobber (reg:SI T_REG))])]
3826 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3829 if (CONST_INT_P (operands[2])
3830 && sh_dynamicalize_shift_p (operands[2]))
3831 operands[2] = force_reg (SImode, operands[2]);
3832 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3834 rtx count = copy_to_mode_reg (SImode, operands[2]);
3835 emit_insn (gen_negsi2 (count, count));
3836 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3839 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3843 ;; ??? This should be a define expand.
3845 (define_insn "ashldi3_k"
3846 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3847 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3849 (clobber (reg:SI T_REG))]
3851 "shll %R0\;rotcl %S0"
3852 [(set_attr "length" "4")
3853 (set_attr "type" "arith")])
3855 ;; Expander for DImode shift left with SImode operations.
3857 (define_expand "ashldi3_std"
3858 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3859 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3860 (match_operand:DI 2 "const_int_operand" "n")))]
3861 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3864 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3865 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3866 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3867 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3868 rtx dst = gen_reg_rtx (DImode);
3869 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3870 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3873 tmp0 = gen_reg_rtx (SImode);
3874 tmp1 = gen_reg_rtx (SImode);
3875 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3876 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3877 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3878 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3879 emit_move_insn (operands[0], dst);
3883 (define_insn "ashldi3_media"
3884 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3885 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3886 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3891 [(set_attr "type" "arith_media")])
3893 (define_insn "*ashldisi3_media"
3894 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3895 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3896 (match_operand:DI 2 "const_int_operand" "n")))]
3897 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3898 "shlli.l %1, %2, %0"
3899 [(set_attr "type" "arith_media")
3900 (set_attr "highpart" "ignore")])
3902 (define_expand "ashldi3"
3903 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3904 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3905 (match_operand:DI 2 "immediate_operand" "")))
3906 (clobber (reg:SI T_REG))])]
3912 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3915 if (CONST_INT_P (operands[2])
3916 && INTVAL (operands[2]) == 1)
3918 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3921 else if (CONST_INT_P (operands[2])
3922 && INTVAL (operands[2]) < 32)
3924 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3931 ;; ??? This should be a define expand.
3933 (define_insn "lshrdi3_k"
3934 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3935 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3937 (clobber (reg:SI T_REG))]
3939 "shlr %S0\;rotcr %R0"
3940 [(set_attr "length" "4")
3941 (set_attr "type" "arith")])
3943 (define_insn "lshrdi3_media"
3944 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3945 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3946 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3948 && (arith_reg_dest (operands[0], DImode)
3949 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3953 [(set_attr "type" "arith_media")])
3955 (define_insn "*lshrdisi3_media"
3956 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3957 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3958 (match_operand:DI 2 "const_int_operand" "n")))]
3959 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3960 "shlri.l %1, %2, %0"
3961 [(set_attr "type" "arith_media")
3962 (set_attr "highpart" "ignore")])
3964 (define_expand "lshrdi3"
3965 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3966 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3967 (match_operand:DI 2 "immediate_operand" "")))
3968 (clobber (reg:SI T_REG))])]
3974 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3977 if (!CONST_INT_P (operands[2])
3978 || INTVAL (operands[2]) != 1)
3982 ;; ??? This should be a define expand.
3984 (define_insn "ashrdi3_k"
3985 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3986 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3988 (clobber (reg:SI T_REG))]
3990 "shar %S0\;rotcr %R0"
3991 [(set_attr "length" "4")
3992 (set_attr "type" "arith")])
3994 (define_insn "ashrdi3_media"
3995 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3996 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3997 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3999 && (arith_reg_dest (operands[0], DImode)
4000 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4004 [(set_attr "type" "arith_media")])
4006 (define_insn "*ashrdisi3_media"
4007 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4008 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4009 (match_operand:DI 2 "const_int_operand" "n")))]
4010 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4011 "shari.l %1, %2, %0"
4012 [(set_attr "type" "arith_media")
4013 (set_attr "highpart" "ignore")])
4015 (define_insn "ashrdisi3_media_high"
4016 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4018 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4019 (match_operand:DI 2 "const_int_operand" "n"))))]
4020 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4022 [(set_attr "type" "arith_media")])
4024 (define_insn "ashrdisi3_media_opaque"
4025 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4026 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4027 (match_operand:DI 2 "const_int_operand" "n")]
4031 [(set_attr "type" "arith_media")])
4033 (define_expand "ashrdi3"
4034 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4035 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4036 (match_operand:DI 2 "immediate_operand" "")))
4037 (clobber (reg:SI T_REG))])]
4043 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4046 if (!CONST_INT_P (operands[2])
4047 || INTVAL (operands[2]) != 1)
4051 ;; combined left/right shift
4054 [(set (match_operand:SI 0 "register_operand" "")
4055 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4056 (match_operand:SI 2 "const_int_operand" ""))
4057 (match_operand:SI 3 "const_int_operand" "")))]
4058 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4059 [(use (reg:SI R0_REG))]
4060 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4064 [(set (match_operand:SI 0 "register_operand" "")
4065 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4066 (match_operand:SI 2 "const_int_operand" ""))
4067 (match_operand:SI 3 "const_int_operand" "")))
4068 (clobber (reg:SI T_REG))]
4069 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4070 [(use (reg:SI R0_REG))]
4071 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4075 [(set (match_operand:SI 0 "register_operand" "=r")
4076 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4077 (match_operand:SI 2 "const_int_operand" "n"))
4078 (match_operand:SI 3 "const_int_operand" "n")))
4079 (clobber (reg:SI T_REG))]
4080 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4082 [(set (attr "length")
4083 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4085 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4087 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4089 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4091 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4093 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4095 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4096 (const_string "16")]
4097 (const_string "18")))
4098 (set_attr "type" "arith")])
4101 [(set (match_operand:SI 0 "register_operand" "=z")
4102 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4103 (match_operand:SI 2 "const_int_operand" "n"))
4104 (match_operand:SI 3 "const_int_operand" "n")))
4105 (clobber (reg:SI T_REG))]
4106 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4108 [(set (attr "length")
4109 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4111 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4113 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4115 (const_string "10")))
4116 (set_attr "type" "arith")])
4118 ;; shift left / and combination with a scratch register: The combine pass
4119 ;; does not accept the individual instructions, even though they are
4120 ;; cheap. But it needs a precise description so that it is usable after
4122 (define_insn "and_shl_scratch"
4123 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4127 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4128 (match_operand:SI 2 "const_int_operand" "N,n"))
4129 (match_operand:SI 3 "" "0,r"))
4130 (match_operand:SI 4 "const_int_operand" "n,n"))
4131 (match_operand:SI 5 "const_int_operand" "n,n")))
4132 (clobber (reg:SI T_REG))]
4135 [(set (attr "length")
4136 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4138 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4140 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4142 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4143 (const_string "10")]
4144 (const_string "12")))
4145 (set_attr "type" "arith")])
4148 [(set (match_operand:SI 0 "register_operand" "")
4152 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4153 (match_operand:SI 2 "const_int_operand" ""))
4154 (match_operand:SI 3 "register_operand" ""))
4155 (match_operand:SI 4 "const_int_operand" ""))
4156 (match_operand:SI 5 "const_int_operand" "")))
4157 (clobber (reg:SI T_REG))]
4159 [(use (reg:SI R0_REG))]
4162 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4164 if (INTVAL (operands[2]))
4166 gen_shifty_op (LSHIFTRT, operands);
4168 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4169 operands[2] = operands[4];
4170 gen_shifty_op (ASHIFT, operands);
4171 if (INTVAL (operands[5]))
4173 operands[2] = operands[5];
4174 gen_shifty_op (LSHIFTRT, operands);
4179 ;; signed left/right shift combination.
4181 [(set (match_operand:SI 0 "register_operand" "")
4183 (ashift:SI (match_operand:SI 1 "register_operand" "")
4184 (match_operand:SI 2 "const_int_operand" ""))
4185 (match_operand:SI 3 "const_int_operand" "")
4187 (clobber (reg:SI T_REG))]
4189 [(use (reg:SI R0_REG))]
4190 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4193 (define_insn "shl_sext_ext"
4194 [(set (match_operand:SI 0 "register_operand" "=r")
4196 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4197 (match_operand:SI 2 "const_int_operand" "n"))
4198 (match_operand:SI 3 "const_int_operand" "n")
4200 (clobber (reg:SI T_REG))]
4201 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4203 [(set (attr "length")
4204 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4206 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4208 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4210 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4212 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4214 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4216 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4218 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4219 (const_string "16")]
4220 (const_string "18")))
4221 (set_attr "type" "arith")])
4223 (define_insn "shl_sext_sub"
4224 [(set (match_operand:SI 0 "register_operand" "=z")
4226 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4227 (match_operand:SI 2 "const_int_operand" "n"))
4228 (match_operand:SI 3 "const_int_operand" "n")
4230 (clobber (reg:SI T_REG))]
4231 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4233 [(set (attr "length")
4234 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4236 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4238 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4240 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4241 (const_string "12")]
4242 (const_string "14")))
4243 (set_attr "type" "arith")])
4245 ;; These patterns are found in expansions of DImode shifts by 16, and
4246 ;; allow the xtrct instruction to be generated from C source.
4248 (define_insn "xtrct_left"
4249 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4250 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4252 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4256 [(set_attr "type" "arith")])
4258 (define_insn "xtrct_right"
4259 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4260 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4262 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4266 [(set_attr "type" "arith")])
4268 ;; -------------------------------------------------------------------------
4270 ;; -------------------------------------------------------------------------
4273 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4274 (neg:SI (plus:SI (reg:SI T_REG)
4275 (match_operand:SI 1 "arith_reg_operand" "r"))))
4277 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4281 [(set_attr "type" "arith")])
4283 (define_insn "*negdi_media"
4284 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4285 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4288 [(set_attr "type" "arith_media")])
4290 (define_expand "negdi2"
4291 [(set (match_operand:DI 0 "arith_reg_operand" "")
4292 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4298 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4299 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4301 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4302 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4304 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4305 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4307 emit_insn (gen_clrt ());
4308 emit_insn (gen_negc (low_dst, low_src));
4309 emit_insn (gen_negc (high_dst, high_src));
4314 (define_insn "negsi2"
4315 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4316 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4319 [(set_attr "type" "arith")])
4321 (define_insn "one_cmplsi2"
4322 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4323 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4326 [(set_attr "type" "arith")])
4328 (define_expand "one_cmpldi2"
4329 [(set (match_operand:DI 0 "arith_reg_dest" "")
4330 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4332 "TARGET_SHMEDIA" "")
4334 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4335 This can be used as some kind of conditional execution, which is useful
4338 [(set (match_operand:SI 0 "arith_reg_dest" "")
4339 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4340 (match_operand:SI 1 "arith_reg_operand" ""))
4344 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4345 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4349 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4350 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4351 (match_operand:SI 1 "arith_reg_operand" "0")
4352 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4354 "bf 0f\;neg %2,%0\\n0:"
4355 [(set_attr "type" "arith") ;; poor approximation
4356 (set_attr "length" "4")])
4359 ;; -------------------------------------------------------------------------
4360 ;; Zero extension instructions
4361 ;; -------------------------------------------------------------------------
4363 (define_insn "zero_extendsidi2"
4364 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4365 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4367 "addz.l %1, r63, %0"
4368 [(set_attr "type" "arith_media")
4369 (set_attr "highpart" "extend")])
4371 (define_insn "zero_extendhidi2"
4372 [(set (match_operand:DI 0 "register_operand" "=r,r")
4373 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4378 [(set_attr "type" "*,load_media")
4379 (set (attr "highpart")
4380 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4381 (const_string "user")]
4382 (const_string "ignore")))])
4385 [(set (match_operand:DI 0 "register_operand" "")
4386 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4387 "TARGET_SHMEDIA && reload_completed"
4388 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4389 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4392 if (GET_CODE (operands[1]) == TRUNCATE)
4393 operands[1] = XEXP (operands[1], 0);
4396 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4397 ;; reload the entire truncate expression.
4398 (define_insn_and_split "*loaddi_trunc"
4399 [(set (match_operand 0 "any_register_operand" "=r")
4400 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4401 "TARGET_SHMEDIA && reload_completed"
4403 "TARGET_SHMEDIA && reload_completed"
4404 [(set (match_dup 0) (match_dup 1))]
4405 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4407 (define_insn "zero_extendqidi2"
4408 [(set (match_operand:DI 0 "register_operand" "=r,r")
4409 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4414 [(set_attr "type" "arith_media,load_media")
4415 (set (attr "highpart")
4416 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4417 (const_string "user")]
4418 (const_string "ignore")))])
4420 (define_expand "zero_extendhisi2"
4421 [(set (match_operand:SI 0 "arith_reg_operand" "")
4422 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4426 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4427 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4430 (define_insn "*zero_extendhisi2_compact"
4431 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4432 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4435 [(set_attr "type" "arith")])
4437 (define_insn "*zero_extendhisi2_media"
4438 [(set (match_operand:SI 0 "register_operand" "=r,r")
4439 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4444 [(set_attr "type" "arith_media,load_media")
4445 (set (attr "highpart")
4446 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4447 (const_string "user")]
4448 (const_string "ignore")))])
4451 [(set (match_operand:SI 0 "register_operand" "")
4452 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4453 "TARGET_SHMEDIA && reload_completed"
4454 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4455 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4458 rtx op1 = operands[1];
4460 if (GET_CODE (op1) == TRUNCATE)
4461 op1 = XEXP (op1, 0);
4463 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4464 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4467 (define_expand "zero_extendqisi2"
4468 [(set (match_operand:SI 0 "arith_reg_operand" "")
4469 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4473 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4474 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4477 (define_insn "*zero_extendqisi2_compact"
4478 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4479 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4482 [(set_attr "type" "arith")])
4484 (define_insn "*zero_extendqisi2_media"
4485 [(set (match_operand:SI 0 "register_operand" "=r,r")
4486 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4491 [(set_attr "type" "arith_media,load_media")
4492 (set (attr "highpart")
4493 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4494 (const_string "user")]
4495 (const_string "ignore")))])
4497 (define_insn "zero_extendqihi2"
4498 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4499 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4502 [(set_attr "type" "arith")])
4504 ;; -------------------------------------------------------------------------
4505 ;; Sign extension instructions
4506 ;; -------------------------------------------------------------------------
4508 ;; ??? This should be a define expand.
4509 ;; ??? Or perhaps it should be dropped?
4511 ;; convert_move generates good code for SH[1-4].
4512 (define_insn "extendsidi2"
4513 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4514 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4520 [(set_attr "type" "arith_media,load_media,fpconv_media")
4521 (set (attr "highpart")
4522 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4523 (const_string "user")]
4524 (const_string "extend")))])
4526 (define_insn "extendhidi2"
4527 [(set (match_operand:DI 0 "register_operand" "=r,r")
4528 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4533 [(set_attr "type" "*,load_media")
4534 (set (attr "highpart")
4535 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4536 (const_string "user")]
4537 (const_string "ignore")))])
4540 [(set (match_operand:DI 0 "register_operand" "")
4541 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4542 "TARGET_SHMEDIA && reload_completed"
4543 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4544 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4547 if (GET_CODE (operands[1]) == TRUNCATE)
4548 operands[1] = XEXP (operands[1], 0);
4551 (define_insn "extendqidi2"
4552 [(set (match_operand:DI 0 "register_operand" "=r,r")
4553 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4558 [(set_attr "type" "*,load_media")
4559 (set (attr "highpart")
4560 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4561 (const_string "user")]
4562 (const_string "ignore")))])
4565 [(set (match_operand:DI 0 "register_operand" "")
4566 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4567 "TARGET_SHMEDIA && reload_completed"
4568 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4569 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4572 if (GET_CODE (operands[1]) == TRUNCATE)
4573 operands[1] = XEXP (operands[1], 0);
4576 (define_expand "extendhisi2"
4577 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4578 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4582 (define_insn "*extendhisi2_compact"
4583 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4584 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4589 [(set_attr "type" "arith,load")])
4591 (define_insn "*extendhisi2_media"
4592 [(set (match_operand:SI 0 "register_operand" "=r,r")
4593 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4598 [(set_attr "type" "arith_media,load_media")
4599 (set (attr "highpart")
4600 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4601 (const_string "user")]
4602 (const_string "ignore")))])
4605 [(set (match_operand:SI 0 "register_operand" "")
4606 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4607 "TARGET_SHMEDIA && reload_completed"
4608 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4609 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4612 rtx op1 = operands[1];
4613 if (GET_CODE (op1) == TRUNCATE)
4614 op1 = XEXP (op1, 0);
4616 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4617 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4620 (define_expand "extendqisi2"
4621 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4622 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4626 (define_insn "*extendqisi2_compact"
4627 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4628 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4633 [(set_attr "type" "arith,load")
4634 (set_attr_alternative "length"
4637 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4638 (const_int 4) (const_int 2))])])
4640 (define_insn "*extendqisi2_media"
4641 [(set (match_operand:SI 0 "register_operand" "=r,r")
4642 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4647 [(set_attr "type" "arith_media,load_media")
4648 (set (attr "highpart")
4649 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4650 (const_string "user")]
4651 (const_string "ignore")))])
4654 [(set (match_operand:SI 0 "register_operand" "")
4655 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4656 "TARGET_SHMEDIA && reload_completed"
4657 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4658 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4661 rtx op1 = operands[1];
4662 if (GET_CODE (op1) == TRUNCATE)
4663 op1 = XEXP (op1, 0);
4665 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4666 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4669 (define_insn "extendqihi2"
4670 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4671 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4676 [(set_attr "type" "arith,load")
4677 (set_attr_alternative "length"
4680 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4681 (const_int 4) (const_int 2))])])
4683 /* It would seem useful to combine the truncXi patterns into the movXi
4684 patterns, but unary operators are ignored when matching constraints,
4685 so we need separate patterns. */
4686 (define_insn "truncdisi2"
4687 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4688 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4697 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4698 (set (attr "highpart")
4699 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4700 (const_string "user")]
4701 (const_string "extend")))])
4703 (define_insn "truncdihi2"
4704 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4705 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4708 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4710 [(set_attr "type" "arith_media,store_media")
4711 (set_attr "length" "8,4")
4712 (set (attr "highpart")
4713 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4714 (const_string "user")]
4715 (const_string "extend")))])
4717 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4718 ; Because we use zero extension, we can't provide signed QImode compares
4719 ; using a simple compare or conditional branch insn.
4720 (define_insn "truncdiqi2"
4721 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4722 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4727 [(set_attr "type" "arith_media,store")
4728 (set (attr "highpart")
4729 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4730 (const_string "user")]
4731 (const_string "extend")))])
4732 ;; -------------------------------------------------------------------------
4733 ;; Move instructions
4734 ;; -------------------------------------------------------------------------
4736 ;; define push and pop so it is easy for sh.c
4737 ;; We can't use push and pop on SHcompact because the stack must always
4738 ;; be 8-byte aligned.
4740 (define_expand "push"
4741 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4742 (match_operand:SI 0 "register_operand" "r,l,x"))]
4743 "TARGET_SH1 && ! TARGET_SH5"
4746 (define_expand "pop"
4747 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4748 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4749 "TARGET_SH1 && ! TARGET_SH5"
4752 (define_expand "push_e"
4753 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4754 (match_operand:SF 0 "" ""))
4755 (use (reg:PSI FPSCR_REG))
4756 (clobber (scratch:SI))])]
4757 "TARGET_SH1 && ! TARGET_SH5"
4760 (define_insn "push_fpul"
4761 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4762 "TARGET_SH2E && ! TARGET_SH5"
4764 [(set_attr "type" "fstore")
4765 (set_attr "late_fp_use" "yes")
4766 (set_attr "hit_stack" "yes")])
4768 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4770 (define_expand "push_4"
4771 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4772 (match_operand:DF 0 "" ""))
4773 (use (reg:PSI FPSCR_REG))
4774 (clobber (scratch:SI))])]
4775 "TARGET_SH1 && ! TARGET_SH5"
4778 (define_expand "pop_e"
4779 [(parallel [(set (match_operand:SF 0 "" "")
4780 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4781 (use (reg:PSI FPSCR_REG))
4782 (clobber (scratch:SI))])]
4783 "TARGET_SH1 && ! TARGET_SH5"
4786 (define_insn "pop_fpul"
4787 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4788 "TARGET_SH2E && ! TARGET_SH5"
4790 [(set_attr "type" "load")
4791 (set_attr "hit_stack" "yes")])
4793 (define_expand "pop_4"
4794 [(parallel [(set (match_operand:DF 0 "" "")
4795 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4796 (use (reg:PSI FPSCR_REG))
4797 (clobber (scratch:SI))])]
4798 "TARGET_SH1 && ! TARGET_SH5"
4801 (define_expand "push_fpscr"
4806 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4807 gen_rtx_PRE_DEC (Pmode,
4808 stack_pointer_rtx)),
4810 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4814 (define_expand "pop_fpscr"
4819 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4820 gen_frame_mem (PSImode,
4821 gen_rtx_POST_INC (Pmode,
4822 stack_pointer_rtx))));
4823 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4827 ;; These two patterns can happen as the result of optimization, when
4828 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4829 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4832 [(set (reg:SI T_REG) (const_int 0))]
4837 [(set (reg:SI T_REG) (const_int 1))]
4841 ;; Define additional pop for SH1 and SH2 so it does not get
4842 ;; placed in the delay slot.
4843 (define_insn "*movsi_pop"
4844 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
4845 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
4846 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
4852 [(set_attr "type" "load_si,mem_mac,pload")
4853 (set_attr "length" "2,2,2")
4854 (set_attr "in_delay_slot" "no,no,no")])
4856 ;; t/r must come after r/r, lest reload will try to reload stuff like
4857 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4858 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4859 (define_insn "movsi_i"
4860 [(set (match_operand:SI 0 "general_movdst_operand"
4861 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4862 (match_operand:SI 1 "general_movsrc_operand"
4863 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4867 && (register_operand (operands[0], SImode)
4868 || register_operand (operands[1], SImode))"
4886 [(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")
4887 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4889 ;; t/r must come after r/r, lest reload will try to reload stuff like
4890 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4891 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4892 ;; will require a reload.
4893 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4894 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4895 (define_insn "movsi_ie"
4896 [(set (match_operand:SI 0 "general_movdst_operand"
4897 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4898 (match_operand:SI 1 "general_movsrc_operand"
4899 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4900 "(TARGET_SH2E || TARGET_SH2A)
4901 && (register_operand (operands[0], SImode)
4902 || register_operand (operands[1], SImode))"
4929 ! move optimized away"
4930 [(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")
4931 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4932 (set_attr_alternative "length"
4940 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4941 (const_int 4) (const_int 2))
4946 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4947 (const_int 4) (const_int 2))
4964 (define_insn "movsi_i_lowpart"
4965 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4966 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4968 && (register_operand (operands[0], SImode)
4969 || register_operand (operands[1], SImode))"
4980 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4982 (define_insn_and_split "load_ra"
4983 [(set (match_operand:SI 0 "general_movdst_operand" "")
4984 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4987 "&& ! currently_expanding_to_rtl"
4988 [(set (match_dup 0) (match_dup 1))]
4991 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4992 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4995 ;; The '?'s in the following constraints may not reflect the time taken
4996 ;; to perform the move. They are there to discourage the use of floating-
4997 ;; point registers for storing integer values.
4998 (define_insn "*movsi_media"
4999 [(set (match_operand:SI 0 "general_movdst_operand"
5000 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5001 (match_operand:SI 1 "general_movsrc_operand"
5002 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5004 && (register_operand (operands[0], SImode)
5005 || sh_register_operand (operands[1], SImode)
5006 || GET_CODE (operands[1]) == TRUNCATE)"
5021 [(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")
5022 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5023 (set (attr "highpart")
5024 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5025 (const_string "user")]
5026 (const_string "ignore")))])
5028 (define_insn "*movsi_media_nofpu"
5029 [(set (match_operand:SI 0 "general_movdst_operand"
5030 "=r,r,r,r,m,*b,r,*b")
5031 (match_operand:SI 1 "general_movsrc_operand"
5032 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5034 && (register_operand (operands[0], SImode)
5035 || sh_register_operand (operands[1], SImode)
5036 || GET_CODE (operands[1]) == TRUNCATE)"
5046 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5047 (set_attr "length" "4,4,8,4,4,4,4,12")
5048 (set (attr "highpart")
5049 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5050 (const_string "user")]
5051 (const_string "ignore")))])
5053 (define_expand "movsi_const"
5054 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5055 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5056 (const_int 16)] UNSPEC_EXTRACT_S16)))
5058 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5059 (const:SI (unspec:SI [(match_dup 1)
5060 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5061 "TARGET_SHMEDIA && reload_completed
5062 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5065 if (GET_CODE (operands[1]) == LABEL_REF
5066 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5067 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5068 else if (GOTOFF_P (operands[1]))
5070 rtx unspec = XEXP (operands[1], 0);
5072 if (! UNSPEC_GOTOFF_P (unspec))
5074 unspec = XEXP (unspec, 0);
5075 if (! UNSPEC_GOTOFF_P (unspec))
5078 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5079 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5080 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5084 (define_expand "movsi_const_16bit"
5085 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5086 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5087 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5088 "TARGET_SHMEDIA && flag_pic && reload_completed
5089 && GET_CODE (operands[1]) == SYMBOL_REF"
5093 [(set (match_operand:SI 0 "arith_reg_dest" "")
5094 (match_operand:SI 1 "immediate_operand" ""))]
5095 "TARGET_SHMEDIA && reload_completed
5096 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5100 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5102 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5108 [(set (match_operand:SI 0 "register_operand" "")
5109 (match_operand:SI 1 "immediate_operand" ""))]
5110 "TARGET_SHMEDIA && reload_completed
5111 && ((CONST_INT_P (operands[1])
5112 && ! satisfies_constraint_I16 (operands[1]))
5113 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5114 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5116 (define_expand "movsi"
5117 [(set (match_operand:SI 0 "general_movdst_operand" "")
5118 (match_operand:SI 1 "general_movsrc_operand" ""))]
5120 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5122 (define_expand "ic_invalidate_line"
5123 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5124 (match_dup 1)] UNSPEC_ICACHE)
5125 (clobber (scratch:SI))])]
5126 "TARGET_HARD_SH4 || TARGET_SH5"
5131 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5134 else if (TARGET_SHCOMPACT)
5136 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5137 operands[1] = force_reg (Pmode, operands[1]);
5138 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5141 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5143 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5146 operands[0] = force_reg (Pmode, operands[0]);
5147 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5151 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5152 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5153 ;; the requirement *1*00 for associative address writes. The alignment of
5154 ;; %0 implies that its least significant bit is cleared,
5155 ;; thus we clear the V bit of a matching entry if there is one.
5156 (define_insn "ic_invalidate_line_i"
5157 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5158 (match_operand:SI 1 "register_operand" "r")]
5160 (clobber (match_scratch:SI 2 "=&r"))]
5162 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5163 [(set_attr "length" "8")
5164 (set_attr "type" "cwb")])
5166 (define_insn "ic_invalidate_line_sh4a"
5167 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5169 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5170 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5171 [(set_attr "length" "16")
5172 (set_attr "type" "cwb")])
5174 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5175 ;; an add in the code that calculates the address.
5176 (define_insn "ic_invalidate_line_media"
5177 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5180 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5181 [(set_attr "length" "16")
5182 (set_attr "type" "invalidate_line_media")])
5184 (define_insn "ic_invalidate_line_compact"
5185 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5186 (match_operand:SI 1 "register_operand" "r")]
5188 (clobber (reg:SI PR_REG))]
5191 [(set_attr "type" "sfunc")
5192 (set_attr "needs_delay_slot" "yes")])
5194 (define_expand "initialize_trampoline"
5195 [(match_operand:SI 0 "" "")
5196 (match_operand:SI 1 "" "")
5197 (match_operand:SI 2 "" "")]
5203 tramp = force_reg (Pmode, operands[0]);
5204 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5206 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5207 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5209 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5213 (define_insn "initialize_trampoline_compact"
5214 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5215 (match_operand:SI 1 "register_operand" "r")
5216 (reg:SI R2_REG) (reg:SI R3_REG)]
5219 (clobber (reg:SI PR_REG))]
5222 [(set_attr "type" "sfunc")
5223 (set_attr "needs_delay_slot" "yes")])
5225 (define_insn "movqi_i"
5226 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5227 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5229 && (arith_reg_operand (operands[0], QImode)
5230 || arith_reg_operand (operands[1], QImode))"
5239 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5240 (set_attr_alternative "length"
5244 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5245 (const_int 4) (const_int 2))
5247 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5248 (const_int 4) (const_int 2))
5253 (define_insn "*movqi_media"
5254 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5255 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5257 && (arith_reg_operand (operands[0], QImode)
5258 || extend_reg_or_0_operand (operands[1], QImode))"
5264 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5265 (set (attr "highpart")
5266 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5267 (const_string "user")]
5268 (const_string "ignore")))])
5270 (define_expand "movqi"
5271 [(set (match_operand:QI 0 "general_operand" "")
5272 (match_operand:QI 1 "general_operand" ""))]
5274 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5276 (define_expand "reload_inqi"
5277 [(set (match_operand:SI 2 "" "=&r")
5278 (match_operand:QI 1 "inqhi_operand" ""))
5279 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5280 (truncate:QI (match_dup 3)))]
5284 rtx inner = XEXP (operands[1], 0);
5285 int regno = REGNO (inner);
5287 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5288 operands[1] = gen_rtx_REG (SImode, regno);
5289 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5292 /* When storing r0, we have to avoid reg+reg addressing. */
5293 (define_insn "movhi_i"
5294 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5295 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5297 && (arith_reg_operand (operands[0], HImode)
5298 || arith_reg_operand (operands[1], HImode))
5299 && (!MEM_P (operands[0])
5300 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5301 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5302 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5312 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5314 (define_insn "*movhi_media"
5315 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5316 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5318 && (arith_reg_operand (operands[0], HImode)
5319 || arith_reg_or_0_operand (operands[1], HImode))"
5326 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5327 (set (attr "highpart")
5328 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5329 (const_string "user")]
5330 (const_string "ignore")))])
5333 [(set (match_operand:HI 0 "register_operand" "")
5334 (match_operand:HI 1 "immediate_operand" ""))]
5335 "TARGET_SHMEDIA && reload_completed
5336 && ! satisfies_constraint_I16 (operands[1])"
5337 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5339 (define_expand "movhi"
5340 [(set (match_operand:HI 0 "general_movdst_operand" "")
5341 (match_operand:HI 1 "general_movsrc_operand" ""))]
5343 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5345 (define_expand "reload_inhi"
5346 [(set (match_operand:SI 2 "" "=&r")
5347 (match_operand:HI 1 "inqhi_operand" ""))
5348 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5349 (truncate:HI (match_dup 3)))]
5353 rtx inner = XEXP (operands[1], 0);
5354 int regno = REGNO (inner);
5356 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5357 operands[1] = gen_rtx_REG (SImode, regno);
5358 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5361 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5362 ;; compiled with -m2 -ml -O3 -funroll-loops
5363 (define_insn "*movdi_i"
5364 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5365 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5367 && (arith_reg_operand (operands[0], DImode)
5368 || arith_reg_operand (operands[1], DImode))"
5369 "* return output_movedouble (insn, operands, DImode);"
5370 [(set_attr "length" "4")
5371 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5373 ;; If the output is a register and the input is memory or a register, we have
5374 ;; to be careful and see which word needs to be loaded first.
5377 [(set (match_operand:DI 0 "general_movdst_operand" "")
5378 (match_operand:DI 1 "general_movsrc_operand" ""))]
5379 "TARGET_SH1 && reload_completed"
5380 [(set (match_dup 2) (match_dup 3))
5381 (set (match_dup 4) (match_dup 5))]
5386 if ((MEM_P (operands[0])
5387 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5388 || (MEM_P (operands[1])
5389 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5392 switch (GET_CODE (operands[0]))
5395 regno = REGNO (operands[0]);
5398 regno = subreg_regno (operands[0]);
5408 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5410 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5411 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5412 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5413 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5417 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5418 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5419 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5420 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5423 if (operands[2] == 0 || operands[3] == 0
5424 || operands[4] == 0 || operands[5] == 0)
5428 ;; The '?'s in the following constraints may not reflect the time taken
5429 ;; to perform the move. They are there to discourage the use of floating-
5430 ;; point registers for storing integer values.
5431 (define_insn "*movdi_media"
5432 [(set (match_operand:DI 0 "general_movdst_operand"
5433 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5434 (match_operand:DI 1 "general_movsrc_operand"
5435 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5437 && (register_operand (operands[0], DImode)
5438 || sh_register_operand (operands[1], DImode))"
5453 [(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")
5454 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5456 (define_insn "*movdi_media_nofpu"
5457 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5458 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5460 && (register_operand (operands[0], DImode)
5461 || sh_register_operand (operands[1], DImode))"
5471 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5472 (set_attr "length" "4,4,16,4,4,4,4,*")])
5474 (define_insn "*movdi_media_I16"
5475 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5476 (match_operand:DI 1 "const_int_operand" "I16"))]
5477 "TARGET_SHMEDIA && reload_completed"
5479 [(set_attr "type" "arith_media")
5480 (set_attr "length" "4")])
5483 [(set (match_operand:DI 0 "arith_reg_dest" "")
5484 (match_operand:DI 1 "immediate_operand" ""))]
5485 "TARGET_SHMEDIA && reload_completed
5486 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5487 [(set (match_dup 0) (match_dup 1))]
5492 if (TARGET_SHMEDIA64)
5493 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5495 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5497 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5502 (define_expand "movdi_const"
5503 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5504 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5505 (const_int 48)] UNSPEC_EXTRACT_S16)))
5507 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5508 (const:DI (unspec:DI [(match_dup 1)
5509 (const_int 32)] UNSPEC_EXTRACT_U16))))
5511 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5512 (const:DI (unspec:DI [(match_dup 1)
5513 (const_int 16)] UNSPEC_EXTRACT_U16))))
5515 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5516 (const:DI (unspec:DI [(match_dup 1)
5517 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5518 "TARGET_SHMEDIA64 && reload_completed
5519 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5522 sh_mark_label (operands[1], 4);
5525 (define_expand "movdi_const_32bit"
5526 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5527 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5528 (const_int 16)] UNSPEC_EXTRACT_S16)))
5530 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5531 (const:DI (unspec:DI [(match_dup 1)
5532 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5533 "TARGET_SHMEDIA32 && reload_completed
5534 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5537 sh_mark_label (operands[1], 2);
5540 (define_expand "movdi_const_16bit"
5541 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5542 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5543 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5544 "TARGET_SHMEDIA && flag_pic && reload_completed
5545 && GET_CODE (operands[1]) == SYMBOL_REF"
5549 [(set (match_operand:DI 0 "ext_dest_operand" "")
5550 (match_operand:DI 1 "immediate_operand" ""))]
5551 "TARGET_SHMEDIA && reload_completed
5552 && CONST_INT_P (operands[1])
5553 && ! satisfies_constraint_I16 (operands[1])"
5554 [(set (match_dup 0) (match_dup 2))
5558 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5559 unsigned HOST_WIDE_INT low = val;
5560 unsigned HOST_WIDE_INT high = val;
5561 unsigned HOST_WIDE_INT sign;
5562 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5564 /* Zero-extend the 16 least-significant bits. */
5567 /* Arithmetic shift right the word by 16 bits. */
5569 if (GET_CODE (operands[0]) == SUBREG
5570 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5579 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5585 /* If we can't generate the constant with a two-insn movi / shori
5586 sequence, try some other strategies. */
5587 if (! CONST_OK_FOR_I16 (high))
5589 /* Try constant load / left shift. We know VAL != 0. */
5590 val2 = val ^ (val-1);
5593 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5595 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5596 || (! CONST_OK_FOR_I16 (high >> 16)
5597 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5599 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5600 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5601 GEN_INT (trailing_zeroes));
5605 /* Try constant load / right shift. */
5606 val2 = (val >> 15) + 1;
5607 if (val2 == (val2 & -val2))
5609 int shift = 49 - exact_log2 (val2);
5611 val2 = trunc_int_for_mode (val << shift, DImode);
5612 if (CONST_OK_FOR_I16 (val2))
5614 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5620 val2 = val & 0xffff;
5621 if ((val >> 16 & 0xffff) == val2
5622 && (val >> 32 & 0xffff) == val2
5623 && (val >> 48 & 0xffff) == val2)
5625 val2 = (HOST_WIDE_INT) val >> 48;
5626 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5627 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5630 /* Try movi / mshflo.l */
5631 val2 = (HOST_WIDE_INT) val >> 32;
5632 if (val2 == ((unsigned HOST_WIDE_INT)
5633 trunc_int_for_mode (val, SImode)))
5635 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5639 /* Try movi / mshflo.l w/ r63. */
5640 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5641 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5643 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5649 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5652 operands[2] = GEN_INT (val2);
5656 [(set (match_operand:DI 0 "ext_dest_operand" "")
5657 (match_operand:DI 1 "immediate_operand" ""))]
5658 "TARGET_SHMEDIA && reload_completed
5659 && GET_CODE (operands[1]) == CONST_DOUBLE"
5660 [(set (match_dup 0) (match_dup 2))
5662 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5665 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5666 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5667 unsigned HOST_WIDE_INT val = low;
5668 unsigned HOST_WIDE_INT sign;
5670 /* Zero-extend the 16 least-significant bits. */
5672 operands[1] = GEN_INT (val);
5674 /* Arithmetic shift right the double-word by 16 bits. */
5676 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5679 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5683 /* This will only be true if high is a sign-extension of low, i.e.,
5684 it must be either 0 or (unsigned)-1, and be zero iff the
5685 most-significant bit of low is set. */
5686 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5687 operands[2] = GEN_INT (low);
5689 operands[2] = immed_double_const (low, high, DImode);
5692 (define_insn "shori_media"
5693 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5694 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5696 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5697 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5701 [(set_attr "type" "arith_media,*")])
5703 (define_insn "*shori_media_si"
5704 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5705 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5707 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5711 (define_expand "movdi"
5712 [(set (match_operand:DI 0 "general_movdst_operand" "")
5713 (match_operand:DI 1 "general_movsrc_operand" ""))]
5715 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5717 (define_insn "movdf_media"
5718 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5719 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5721 && (register_operand (operands[0], DFmode)
5722 || sh_register_operand (operands[1], DFmode))"
5733 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5735 (define_insn "movdf_media_nofpu"
5736 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5737 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5739 && (register_operand (operands[0], DFmode)
5740 || sh_register_operand (operands[1], DFmode))"
5746 [(set_attr "type" "arith_media,*,load_media,store_media")])
5749 [(set (match_operand:DF 0 "arith_reg_dest" "")
5750 (match_operand:DF 1 "immediate_operand" ""))]
5751 "TARGET_SHMEDIA && reload_completed"
5752 [(set (match_dup 3) (match_dup 2))]
5755 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5757 REAL_VALUE_TYPE value;
5759 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5760 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5762 if (HOST_BITS_PER_WIDE_INT >= 64)
5763 operands[2] = immed_double_const ((unsigned long) values[endian]
5764 | ((HOST_WIDE_INT) values[1 - endian]
5768 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5769 operands[2] = immed_double_const (values[endian], values[1 - endian],
5773 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5776 ;; ??? This should be a define expand.
5778 (define_insn "movdf_k"
5779 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5780 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5782 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5783 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5784 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5785 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5786 && (arith_reg_operand (operands[0], DFmode)
5787 || arith_reg_operand (operands[1], DFmode))"
5788 "* return output_movedouble (insn, operands, DFmode);"
5789 [(set_attr "length" "4")
5790 (set_attr "type" "move,pcload,load,store")])
5792 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5793 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5794 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5795 ;; the d/m/c/X alternative, which is split later into single-precision
5796 ;; instructions. And when not optimizing, no splits are done before fixing
5797 ;; up pcloads, so we need usable length information for that.
5798 (define_insn "movdf_i4"
5799 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5800 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5801 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5802 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5803 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5804 && (arith_reg_operand (operands[0], DFmode)
5805 || arith_reg_operand (operands[1], DFmode))"
5807 switch (which_alternative)
5811 return "fmov %1,%0";
5812 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5813 return "fmov %R1,%R0\n\tfmov %S1,%S0";
5815 return "fmov %S1,%S0\n\tfmov %R1,%R0";
5818 return "fmov.d %1,%0";
5823 [(set_attr_alternative "length"
5824 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
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))
5828 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5830 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5831 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5832 ;; increment or decrement r15 explicitly.
5834 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5835 (const_int 10) (const_int 8))
5837 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5838 (const_int 10) (const_int 8))])
5839 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5840 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5841 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5842 (const_string "double")
5843 (const_string "none")))])
5845 ;; Moving DFmode between fp/general registers through memory
5846 ;; (the top of the stack) is faster than moving through fpul even for
5847 ;; little endian. Because the type of an instruction is important for its
5848 ;; scheduling, it is beneficial to split these operations, rather than
5849 ;; emitting them in one single chunk, even if this will expose a stack
5850 ;; use that will prevent scheduling of other stack accesses beyond this
5853 [(set (match_operand:DF 0 "register_operand" "")
5854 (match_operand:DF 1 "register_operand" ""))
5855 (use (match_operand:PSI 2 "fpscr_operand" ""))
5856 (clobber (match_scratch:SI 3 "=X"))]
5857 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5858 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5864 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5866 emit_move_insn (stack_pointer_rtx,
5867 plus_constant (stack_pointer_rtx, -8));
5868 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5871 tos = gen_tmp_stack_mem (DFmode,
5872 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5873 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5874 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5875 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5876 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5877 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5879 tos = gen_tmp_stack_mem (DFmode,
5880 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5881 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5882 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5883 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5885 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5889 ;; local-alloc sometimes allocates scratch registers even when not required,
5890 ;; so we must be prepared to handle these.
5892 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5894 [(set (match_operand:DF 0 "general_movdst_operand" "")
5895 (match_operand:DF 1 "general_movsrc_operand" ""))
5896 (use (match_operand:PSI 2 "fpscr_operand" ""))
5897 (clobber (match_scratch:SI 3 ""))]
5898 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5900 && true_regnum (operands[0]) < 16
5901 && true_regnum (operands[1]) < 16"
5902 [(set (match_dup 0) (match_dup 1))]
5905 /* If this was a reg <-> mem operation with base + index reg addressing,
5906 we have to handle this in a special way. */
5907 rtx mem = operands[0];
5909 if (! memory_operand (mem, DFmode))
5914 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5915 mem = SUBREG_REG (mem);
5918 rtx addr = XEXP (mem, 0);
5919 if (GET_CODE (addr) == PLUS
5920 && REG_P (XEXP (addr, 0))
5921 && REG_P (XEXP (addr, 1)))
5924 rtx reg0 = gen_rtx_REG (Pmode, 0);
5925 rtx regop = operands[store_p], word0 ,word1;
5927 if (GET_CODE (regop) == SUBREG)
5928 alter_subreg (®op);
5929 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5933 mem = copy_rtx (mem);
5934 PUT_MODE (mem, SImode);
5935 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5936 alter_subreg (&word0);
5937 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5938 alter_subreg (&word1);
5939 if (store_p || ! refers_to_regno_p (REGNO (word0),
5940 REGNO (word0) + 1, addr, 0))
5943 ? gen_movsi_ie (mem, word0)
5944 : gen_movsi_ie (word0, mem));
5945 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5946 mem = copy_rtx (mem);
5948 ? gen_movsi_ie (mem, word1)
5949 : gen_movsi_ie (word1, mem));
5950 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5954 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5955 emit_insn (gen_movsi_ie (word1, mem));
5956 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5957 mem = copy_rtx (mem);
5958 emit_insn (gen_movsi_ie (word0, mem));
5965 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5967 [(set (match_operand:DF 0 "register_operand" "")
5968 (match_operand:DF 1 "memory_operand" ""))
5969 (use (match_operand:PSI 2 "fpscr_operand" ""))
5970 (clobber (reg:SI R0_REG))]
5971 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5972 [(parallel [(set (match_dup 0) (match_dup 1))
5974 (clobber (scratch:SI))])]
5977 (define_expand "reload_indf__frn"
5978 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5979 (match_operand:DF 1 "immediate_operand" "FQ"))
5980 (use (reg:PSI FPSCR_REG))
5981 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5985 (define_expand "reload_outdf__RnFRm"
5986 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5987 (match_operand:DF 1 "register_operand" "af,r"))
5988 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5992 ;; Simplify no-op moves.
5994 [(set (match_operand:SF 0 "register_operand" "")
5995 (match_operand:SF 1 "register_operand" ""))
5996 (use (match_operand:PSI 2 "fpscr_operand" ""))
5997 (clobber (match_scratch:SI 3 ""))]
5998 "TARGET_SH2E && reload_completed
5999 && true_regnum (operands[0]) == true_regnum (operands[1])"
6000 [(set (match_dup 0) (match_dup 0))]
6003 ;; fmovd substitute post-reload splits
6005 [(set (match_operand:DF 0 "register_operand" "")
6006 (match_operand:DF 1 "register_operand" ""))
6007 (use (match_operand:PSI 2 "fpscr_operand" ""))
6008 (clobber (match_scratch:SI 3 ""))]
6009 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6010 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6011 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6015 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6016 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6017 gen_rtx_REG (SFmode, src), operands[2]));
6018 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6019 gen_rtx_REG (SFmode, src + 1), operands[2]));
6024 [(set (match_operand:DF 0 "register_operand" "")
6025 (mem:DF (match_operand:SI 1 "register_operand" "")))
6026 (use (match_operand:PSI 2 "fpscr_operand" ""))
6027 (clobber (match_scratch:SI 3 ""))]
6028 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6029 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6030 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6034 int regno = true_regnum (operands[0]);
6036 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6038 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6039 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6040 regno + !! TARGET_LITTLE_ENDIAN),
6041 mem2, operands[2]));
6042 add_reg_note (insn, REG_INC, operands[1]);
6043 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6044 regno + ! TARGET_LITTLE_ENDIAN),
6045 change_address (mem, SFmode, NULL_RTX),
6051 [(set (match_operand:DF 0 "register_operand" "")
6052 (match_operand:DF 1 "memory_operand" ""))
6053 (use (match_operand:PSI 2 "fpscr_operand" ""))
6054 (clobber (match_scratch:SI 3 ""))]
6055 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6056 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6059 int regno = true_regnum (operands[0]);
6061 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6062 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6063 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6065 operands[1] = copy_rtx (mem2);
6066 addr = XEXP (mem2, 0);
6068 switch (GET_CODE (addr))
6071 /* This is complicated. If the register is an arithmetic register
6072 we can just fall through to the REG+DISP case below. Otherwise
6073 we have to use a combination of POST_INC and REG addressing... */
6074 if (! arith_reg_operand (operands[1], SFmode))
6076 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6077 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6078 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6080 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6082 /* If we have modified the stack pointer, the value that we have
6083 read with post-increment might be modified by an interrupt,
6084 so write it back. */
6085 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6086 emit_insn (gen_push_e (reg0));
6088 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6094 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6095 operands[1] = copy_rtx (operands[1]);
6096 XEXP (operands[1], 0) = plus_constant (addr, 4);
6097 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6101 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6102 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6104 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6105 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6117 [(set (match_operand:DF 0 "memory_operand" "")
6118 (match_operand:DF 1 "register_operand" ""))
6119 (use (match_operand:PSI 2 "fpscr_operand" ""))
6120 (clobber (match_scratch:SI 3 ""))]
6121 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6122 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6125 int regno = true_regnum (operands[1]);
6127 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6128 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6130 operands[0] = copy_rtx (operands[0]);
6131 PUT_MODE (operands[0], SFmode);
6132 addr = XEXP (operands[0], 0);
6134 switch (GET_CODE (addr))
6137 /* This is complicated. If the register is an arithmetic register
6138 we can just fall through to the REG+DISP case below. Otherwise
6139 we have to use a combination of REG and PRE_DEC addressing... */
6140 if (! arith_reg_operand (operands[0], SFmode))
6142 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6143 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6145 operands[0] = copy_rtx (operands[0]);
6146 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6148 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6149 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6155 /* Since REG+DISP addressing has already been decided upon by gcc
6156 we can rely upon it having chosen an arithmetic register as the
6157 register component of the address. Just emit the lower numbered
6158 register first, to the lower address, then the higher numbered
6159 register to the higher address. */
6160 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6162 operands[0] = copy_rtx (operands[0]);
6163 XEXP (operands[0], 0) = plus_constant (addr, 4);
6165 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6169 /* This is easy. Output the word to go to the higher address
6170 first (ie the word in the higher numbered register) then the
6171 word to go to the lower address. */
6173 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6174 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6176 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6177 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6189 ;; If the output is a register and the input is memory or a register, we have
6190 ;; to be careful and see which word needs to be loaded first.
6193 [(set (match_operand:DF 0 "general_movdst_operand" "")
6194 (match_operand:DF 1 "general_movsrc_operand" ""))]
6195 "TARGET_SH1 && reload_completed"
6196 [(set (match_dup 2) (match_dup 3))
6197 (set (match_dup 4) (match_dup 5))]
6202 if ((MEM_P (operands[0])
6203 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6204 || (MEM_P (operands[1])
6205 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6208 switch (GET_CODE (operands[0]))
6211 regno = REGNO (operands[0]);
6214 regno = subreg_regno (operands[0]);
6224 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6226 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6227 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6228 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6229 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6233 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6234 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6235 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6236 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6239 if (operands[2] == 0 || operands[3] == 0
6240 || operands[4] == 0 || operands[5] == 0)
6244 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6245 ;; used only once, let combine add in the index again.
6248 [(set (match_operand:SI 0 "register_operand" "")
6249 (match_operand:SI 1 "" ""))
6250 (clobber (match_operand 2 "register_operand" ""))]
6251 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6252 && ALLOW_INDEXED_ADDRESS"
6253 [(use (reg:SI R0_REG))]
6256 rtx addr, reg, const_int;
6258 if (!MEM_P (operands[1]))
6260 addr = XEXP (operands[1], 0);
6261 if (GET_CODE (addr) != PLUS)
6263 reg = XEXP (addr, 0);
6264 const_int = XEXP (addr, 1);
6265 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6266 && CONST_INT_P (const_int)))
6268 emit_move_insn (operands[2], const_int);
6269 emit_move_insn (operands[0],
6270 change_address (operands[1], VOIDmode,
6271 gen_rtx_PLUS (SImode, reg, operands[2])));
6276 [(set (match_operand:SI 1 "" "")
6277 (match_operand:SI 0 "register_operand" ""))
6278 (clobber (match_operand 2 "register_operand" ""))]
6279 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6280 && ALLOW_INDEXED_ADDRESS"
6281 [(use (reg:SI R0_REG))]
6284 rtx addr, reg, const_int;
6286 if (!MEM_P (operands[1]))
6288 addr = XEXP (operands[1], 0);
6289 if (GET_CODE (addr) != PLUS)
6291 reg = XEXP (addr, 0);
6292 const_int = XEXP (addr, 1);
6293 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6294 && CONST_INT_P (const_int)))
6296 emit_move_insn (operands[2], const_int);
6297 emit_move_insn (change_address (operands[1], VOIDmode,
6298 gen_rtx_PLUS (SImode, reg, operands[2])),
6303 (define_expand "movdf"
6304 [(set (match_operand:DF 0 "general_movdst_operand" "")
6305 (match_operand:DF 1 "general_movsrc_operand" ""))]
6309 if (prepare_move_operands (operands, DFmode)) DONE;
6312 if (TARGET_SHMEDIA_FPU)
6313 emit_insn (gen_movdf_media (operands[0], operands[1]));
6315 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6318 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6320 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6325 ;;This is incompatible with the way gcc uses subregs.
6326 ;;(define_insn "movv2sf_i"
6327 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6328 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6329 ;; "TARGET_SHMEDIA_FPU
6330 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6331 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6335 ;; fst%M0.p %m0, %1"
6336 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6338 (define_insn_and_split "movv2sf_i"
6339 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6340 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6341 "TARGET_SHMEDIA_FPU"
6343 "TARGET_SHMEDIA_FPU && reload_completed"
6344 [(set (match_dup 0) (match_dup 1))]
6347 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6348 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6351 (define_expand "movv2sf"
6352 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6353 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6354 "TARGET_SHMEDIA_FPU"
6357 if (prepare_move_operands (operands, V2SFmode))
6361 (define_expand "addv2sf3"
6362 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6363 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6364 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6365 "TARGET_SHMEDIA_FPU"
6368 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6372 (define_expand "subv2sf3"
6373 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6374 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6375 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6376 "TARGET_SHMEDIA_FPU"
6379 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6383 (define_expand "mulv2sf3"
6384 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6385 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6386 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6387 "TARGET_SHMEDIA_FPU"
6390 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6394 (define_expand "divv2sf3"
6395 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6396 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6397 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6398 "TARGET_SHMEDIA_FPU"
6401 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6405 (define_insn_and_split "*movv4sf_i"
6406 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6407 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6408 "TARGET_SHMEDIA_FPU"
6410 "&& reload_completed"
6416 for (i = 0; i < 4/2; i++)
6420 if (MEM_P (operands[0]))
6421 x = adjust_address (operands[0], V2SFmode,
6422 i * GET_MODE_SIZE (V2SFmode));
6424 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6426 if (MEM_P (operands[1]))
6427 y = adjust_address (operands[1], V2SFmode,
6428 i * GET_MODE_SIZE (V2SFmode));
6430 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6432 emit_insn (gen_movv2sf_i (x, y));
6437 [(set_attr "length" "8")])
6439 (define_expand "movv4sf"
6440 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6441 (match_operand:V4SF 1 "general_operand" ""))]
6442 "TARGET_SHMEDIA_FPU"
6445 if (prepare_move_operands (operands, V4SFmode))
6449 (define_insn_and_split "*movv16sf_i"
6450 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6451 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6452 "TARGET_SHMEDIA_FPU"
6454 "&& reload_completed"
6460 for (i = 0; i < 16/2; i++)
6464 if (MEM_P (operands[0]))
6465 x = adjust_address (operands[0], V2SFmode,
6466 i * GET_MODE_SIZE (V2SFmode));
6469 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6473 if (MEM_P (operands[1]))
6474 y = adjust_address (operands[1], V2SFmode,
6475 i * GET_MODE_SIZE (V2SFmode));
6478 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6482 emit_insn (gen_movv2sf_i (x, y));
6487 [(set_attr "length" "32")])
6489 (define_expand "movv16sf"
6490 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6491 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6492 "TARGET_SHMEDIA_FPU"
6495 if (prepare_move_operands (operands, V16SFmode))
6499 (define_insn "movsf_media"
6500 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6501 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6503 && (register_operand (operands[0], SFmode)
6504 || sh_register_operand (operands[1], SFmode))"
6515 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6516 (set (attr "highpart")
6517 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6518 (const_string "user")]
6519 (const_string "ignore")))])
6521 (define_insn "movsf_media_nofpu"
6522 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6523 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6525 && (register_operand (operands[0], SFmode)
6526 || sh_register_operand (operands[1], SFmode))"
6532 [(set_attr "type" "arith_media,*,load_media,store_media")
6533 (set (attr "highpart")
6534 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6535 (const_string "user")]
6536 (const_string "ignore")))])
6539 [(set (match_operand:SF 0 "arith_reg_dest" "")
6540 (match_operand:SF 1 "immediate_operand" ""))]
6541 "TARGET_SHMEDIA && reload_completed
6542 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6543 [(set (match_dup 3) (match_dup 2))]
6547 REAL_VALUE_TYPE value;
6549 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6550 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6551 operands[2] = GEN_INT (values);
6553 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6556 (define_insn "movsf_i"
6557 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6558 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6561 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6562 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6563 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6564 && (arith_reg_operand (operands[0], SFmode)
6565 || arith_reg_operand (operands[1], SFmode))"
6574 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6576 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6577 ;; update_flow_info would not know where to put REG_EQUAL notes
6578 ;; when the destination changes mode.
6579 (define_insn "movsf_ie"
6580 [(set (match_operand:SF 0 "general_movdst_operand"
6581 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6582 (match_operand:SF 1 "general_movsrc_operand"
6583 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6584 (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"))
6585 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6588 && (arith_reg_operand (operands[0], SFmode)
6589 || arith_reg_operand (operands[1], SFmode)
6590 || arith_reg_operand (operands[3], SImode)
6591 || (fpul_operand (operands[0], SFmode)
6592 && memory_operand (operands[1], SFmode)
6593 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6594 || (fpul_operand (operands[1], SFmode)
6595 && memory_operand (operands[0], SFmode)
6596 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6616 ! move optimized away"
6617 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6618 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6619 (set_attr_alternative "length"
6626 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6627 (const_int 4) (const_int 2))
6629 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6630 (const_int 4) (const_int 2))
6633 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6634 (const_int 4) (const_int 2))
6636 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6637 (const_int 4) (const_int 2))
6647 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6648 (const_string "single")
6649 (const_string "single")))])
6652 [(set (match_operand:SF 0 "register_operand" "")
6653 (match_operand:SF 1 "register_operand" ""))
6654 (use (match_operand:PSI 2 "fpscr_operand" ""))
6655 (clobber (reg:SI FPUL_REG))]
6657 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6659 (clobber (scratch:SI))])
6660 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6662 (clobber (scratch:SI))])]
6665 (define_expand "movsf"
6666 [(set (match_operand:SF 0 "general_movdst_operand" "")
6667 (match_operand:SF 1 "general_movsrc_operand" ""))]
6671 if (prepare_move_operands (operands, SFmode))
6675 if (TARGET_SHMEDIA_FPU)
6676 emit_insn (gen_movsf_media (operands[0], operands[1]));
6678 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6683 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6688 (define_insn "mov_nop"
6689 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6692 [(set_attr "length" "0")
6693 (set_attr "type" "nil")])
6695 (define_expand "reload_insf__frn"
6696 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6697 (match_operand:SF 1 "immediate_operand" "FQ"))
6698 (use (reg:PSI FPSCR_REG))
6699 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6703 (define_expand "reload_insi__i_fpul"
6704 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6705 (match_operand:SI 1 "immediate_operand" "i"))
6706 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6710 (define_expand "ptabs"
6711 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6715 if (!TARGET_PT_FIXED)
6717 rtx eq = operands[1];
6719 /* ??? For canonical RTL we really should remove any CONST from EQ
6720 before wrapping it in the AND, and finally wrap the EQ into a
6721 const if is constant. However, for reload we must expose the
6722 input register or symbolic constant, and we can't have
6723 different insn structures outside of the operands for different
6724 alternatives of the same pattern. */
6725 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6728 = (gen_rtx_IF_THEN_ELSE
6731 gen_rtx_MEM (PDImode, operands[1]),
6732 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6733 PDImode, operands[1])));
6737 ;; expanded by ptabs expander.
6738 (define_insn "*extendsipdi_media"
6739 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6740 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6744 (mem:PDI (match_dup 1))
6745 (sign_extend:PDI (match_dup 1))))]
6746 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6750 [(set_attr "type" "ptabs_media,pt_media")
6751 (set_attr "length" "4,*")])
6753 (define_insn "*truncdipdi_media"
6754 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6755 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6759 (mem:PDI (match_dup 1))
6760 (truncate:PDI (match_dup 1))))]
6761 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6765 [(set_attr "type" "ptabs_media,pt_media")
6766 (set_attr "length" "4,*")])
6768 (define_insn "*movsi_y"
6769 [(set (match_operand:SI 0 "register_operand" "=y,y")
6770 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6771 (clobber (match_scratch:SI 2 "=&z,r"))]
6773 && (reload_in_progress || reload_completed)"
6775 [(set_attr "length" "4")
6776 (set_attr "type" "pcload,move")])
6779 [(set (match_operand:SI 0 "register_operand" "")
6780 (match_operand:SI 1 "immediate_operand" ""))
6781 (clobber (match_operand:SI 2 "register_operand" ""))]
6783 [(set (match_dup 2) (match_dup 1))
6784 (set (match_dup 0) (match_dup 2))]
6788 [(set (match_operand:SI 0 "register_operand" "")
6789 (match_operand:SI 1 "memory_operand" ""))
6790 (clobber (reg:SI R0_REG))]
6792 [(set (match_dup 0) (match_dup 1))]
6795 ;; ------------------------------------------------------------------------
6796 ;; Define the real conditional branch instructions.
6797 ;; ------------------------------------------------------------------------
6799 (define_insn "branch_true"
6800 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6801 (label_ref (match_operand 0 "" ""))
6804 "* return output_branch (1, insn, operands);"
6805 [(set_attr "type" "cbranch")])
6807 (define_insn "branch_false"
6808 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6809 (label_ref (match_operand 0 "" ""))
6812 "* return output_branch (0, insn, operands);"
6813 [(set_attr "type" "cbranch")])
6815 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6816 ;; which destination is too far away.
6817 ;; The const_int_operand is distinct for each branch target; it avoids
6818 ;; unwanted matches with redundant_insn.
6819 (define_insn "block_branch_redirect"
6820 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6823 [(set_attr "length" "0")])
6825 ;; This one has the additional purpose to record a possible scratch register
6826 ;; for the following branch.
6827 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6828 ;; because the insn then might be deemed dead and deleted. And we can't
6829 ;; make the use in the jump insn explicit because that would disable
6830 ;; delay slot scheduling from the target.
6831 (define_insn "indirect_jump_scratch"
6832 [(set (match_operand:SI 0 "register_operand" "=r")
6833 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6834 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6837 [(set_attr "length" "0")])
6839 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6840 ;; being pulled into the delay slot of a condbranch that has been made to
6841 ;; jump around the unconditional jump because it was out of range.
6842 (define_insn "stuff_delay_slot"
6844 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6845 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6848 [(set_attr "length" "0")
6849 (set_attr "cond_delay_slot" "yes")])
6851 ;; Conditional branch insns
6853 (define_expand "cbranchint4_media"
6855 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6856 [(match_operand 1 "" "")
6857 (match_operand 2 "" "")])
6858 (match_operand 3 "" "")
6863 enum machine_mode mode = GET_MODE (operands[1]);
6864 if (mode == VOIDmode)
6865 mode = GET_MODE (operands[2]);
6866 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6868 operands[1] = force_reg (mode, operands[1]);
6869 if (CONSTANT_P (operands[2])
6870 && (! satisfies_constraint_I06 (operands[2])))
6871 operands[2] = force_reg (mode, operands[2]);
6875 if (operands[1] != const0_rtx)
6876 operands[1] = force_reg (mode, operands[1]);
6877 if (operands[2] != const0_rtx)
6878 operands[2] = force_reg (mode, operands[2]);
6880 switch (GET_CODE (operands[0]))
6886 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6887 VOIDmode, operands[2], operands[1]);
6888 operands[1] = XEXP (operands[0], 0);
6889 operands[2] = XEXP (operands[0], 1);
6892 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6893 VOIDmode, operands[1], operands[2]);
6896 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6899 (define_expand "cbranchfp4_media"
6901 (if_then_else (match_operator 0 "sh_float_comparison_operator"
6902 [(match_operand 1 "" "")
6903 (match_operand 2 "" "")])
6904 (match_operand 3 "" "")
6909 rtx tmp = gen_reg_rtx (SImode);
6911 if (GET_CODE (operands[0]) == NE)
6912 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6914 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6915 operands[1], operands[2]);
6917 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6919 if (GET_CODE (cmp) == GET_CODE (operands[0]))
6920 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6922 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6924 operands[2] = const0_rtx;
6925 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6928 (define_insn "*beq_media_i"
6930 (if_then_else (match_operator 3 "equality_comparison_operator"
6931 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6932 (match_operand:DI 2 "arith_operand" "r,I06")])
6933 (match_operand 0 "target_operand" "b,b")
6938 b%o3i%' %1, %2, %0%>"
6939 [(set_attr "type" "cbranch_media")])
6941 (define_insn "*beq_media_i32"
6943 (if_then_else (match_operator 3 "equality_comparison_operator"
6944 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6945 (match_operand:SI 2 "arith_operand" "r,I06")])
6946 (match_operand 0 "target_operand" "b,b")
6951 b%o3i%' %1, %2, %0%>"
6952 [(set_attr "type" "cbranch_media")])
6954 (define_insn "*bgt_media_i"
6956 (if_then_else (match_operator 3 "greater_comparison_operator"
6957 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6958 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6959 (match_operand 0 "target_operand" "b")
6962 "b%o3%' %N1, %N2, %0%>"
6963 [(set_attr "type" "cbranch_media")])
6965 (define_insn "*bgt_media_i32"
6967 (if_then_else (match_operator 3 "greater_comparison_operator"
6968 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6969 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6970 (match_operand 0 "target_operand" "b")
6973 "b%o3%' %N1, %N2, %0%>"
6974 [(set_attr "type" "cbranch_media")])
6976 ;; These are only needed to make invert_jump() happy - otherwise, jump
6977 ;; optimization will be silently disabled.
6978 (define_insn "*blt_media_i"
6980 (if_then_else (match_operator 3 "less_comparison_operator"
6981 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6982 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6983 (match_operand 0 "target_operand" "b")
6986 "b%o3%' %N2, %N1, %0%>"
6987 [(set_attr "type" "cbranch_media")])
6989 (define_insn "*blt_media_i32"
6991 (if_then_else (match_operator 3 "less_comparison_operator"
6992 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6993 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6994 (match_operand 0 "target_operand" "b")
6997 "b%o3%' %N2, %N1, %0%>"
6998 [(set_attr "type" "cbranch_media")])
7000 ;; combiner splitter for test-and-branch on single bit in register. This
7001 ;; is endian dependent because the non-paradoxical subreg looks different
7006 (match_operator 3 "equality_comparison_operator"
7007 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7008 "extend_reg_operand" "")
7012 "const_int_operand" "")) 0)
7014 (match_operand 0 "target_operand" "")
7016 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7017 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7018 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7019 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7023 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7024 operands[6] = (GET_CODE (operands[3]) == EQ
7025 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7026 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7029 ; operand 0 is the loop count pseudo register
7030 ; operand 1 is the number of loop iterations or 0 if it is unknown
7031 ; operand 2 is the maximum number of loop iterations
7032 ; operand 3 is the number of levels of enclosed loops
7033 ; operand 4 is the label to jump to at the top of the loop
7035 (define_expand "doloop_end"
7036 [(parallel [(set (pc) (if_then_else
7037 (ne:SI (match_operand:SI 0 "" "")
7039 (label_ref (match_operand 4 "" ""))
7042 (plus:SI (match_dup 0) (const_int -1)))
7043 (clobber (reg:SI T_REG))])]
7047 if (GET_MODE (operands[0]) != SImode)
7052 (define_insn_and_split "doloop_end_split"
7054 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
7056 (label_ref (match_operand 1 "" ""))
7058 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7059 (plus (match_dup 2) (const_int -1)))
7060 (clobber (reg:SI T_REG))]
7064 [(parallel [(set (reg:SI T_REG)
7065 (eq:SI (match_dup 2) (const_int 1)))
7066 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7067 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7068 (label_ref (match_dup 1))
7071 [(set_attr "type" "cbranch")])
7074 ;; ------------------------------------------------------------------------
7075 ;; Jump and linkage insns
7076 ;; ------------------------------------------------------------------------
7078 (define_insn "jump_compact"
7080 (label_ref (match_operand 0 "" "")))]
7081 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7084 /* The length is 16 if the delay slot is unfilled. */
7085 if (get_attr_length(insn) > 4)
7086 return output_far_jump(insn, operands[0]);
7088 return \"bra %l0%#\";
7090 [(set_attr "type" "jump")
7091 (set_attr "needs_delay_slot" "yes")])
7093 ;; ??? It would be much saner to explicitly use the scratch register
7094 ;; in the jump insn, and have indirect_jump_scratch only set it,
7095 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7096 ;; from the target then, as it uses simplejump_p.
7097 ;;(define_insn "jump_compact_far"
7099 ;; (label_ref (match_operand 0 "" "")))
7100 ;; (use (match_operand 1 "register_operand" "r")]
7102 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7103 ;; [(set_attr "type" "jump")
7104 ;; (set_attr "needs_delay_slot" "yes")])
7106 (define_insn "jump_media"
7108 (match_operand 0 "target_operand" "b"))]
7111 [(set_attr "type" "jump_media")])
7113 (define_expand "jump"
7115 (label_ref (match_operand 0 "" "")))]
7120 emit_jump_insn (gen_jump_compact (operands[0]));
7121 else if (TARGET_SHMEDIA)
7123 if (reload_in_progress || reload_completed)
7125 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7131 (define_insn "force_mode_for_call"
7132 [(use (reg:PSI FPSCR_REG))]
7135 [(set_attr "length" "0")
7136 (set (attr "fp_mode")
7137 (if_then_else (eq_attr "fpu_single" "yes")
7138 (const_string "single") (const_string "double")))])
7140 (define_insn "calli"
7141 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7142 (match_operand 1 "" ""))
7143 (use (reg:PSI FPSCR_REG))
7144 (clobber (reg:SI PR_REG))]
7148 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7149 return \"jsr/n\\t@%0\";
7151 return \"jsr\\t@%0%#\";
7154 [(set_attr "type" "call")
7155 (set (attr "fp_mode")
7156 (if_then_else (eq_attr "fpu_single" "yes")
7157 (const_string "single") (const_string "double")))
7158 (set_attr "needs_delay_slot" "yes")
7159 (set_attr "fp_set" "unknown")])
7161 ;; This is TBR relative jump instruction for SH2A architecture.
7162 ;; Its use is enabled assigning an attribute "function_vector"
7163 ;; and the vector number to a function during its declaration.
7165 (define_insn "calli_tbr_rel"
7166 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7167 (match_operand 1 "" ""))
7168 (use (reg:PSI FPSCR_REG))
7169 (clobber (reg:SI PR_REG))]
7170 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7173 unsigned HOST_WIDE_INT vect_num;
7174 vect_num = sh2a_get_function_vector_number (operands[0]);
7175 operands[2] = GEN_INT (vect_num * 4);
7177 return \"jsr/n\\t@@(%O2,tbr)\";
7179 [(set_attr "type" "call")
7180 (set (attr "fp_mode")
7181 (if_then_else (eq_attr "fpu_single" "yes")
7182 (const_string "single") (const_string "double")))
7183 (set_attr "needs_delay_slot" "no")
7184 (set_attr "fp_set" "unknown")])
7186 ;; This is a pc-rel call, using bsrf, for use with PIC.
7188 (define_insn "calli_pcrel"
7189 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7190 (match_operand 1 "" ""))
7191 (use (reg:PSI FPSCR_REG))
7192 (use (reg:SI PIC_REG))
7193 (use (match_operand 2 "" ""))
7194 (clobber (reg:SI PR_REG))]
7197 [(set_attr "type" "call")
7198 (set (attr "fp_mode")
7199 (if_then_else (eq_attr "fpu_single" "yes")
7200 (const_string "single") (const_string "double")))
7201 (set_attr "needs_delay_slot" "yes")
7202 (set_attr "fp_set" "unknown")])
7204 (define_insn_and_split "call_pcrel"
7205 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7206 (match_operand 1 "" ""))
7207 (use (reg:PSI FPSCR_REG))
7208 (use (reg:SI PIC_REG))
7209 (clobber (reg:SI PR_REG))
7210 (clobber (match_scratch:SI 2 "=r"))]
7217 rtx lab = PATTERN (gen_call_site ());
7219 if (SYMBOL_REF_LOCAL_P (operands[0]))
7220 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7222 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7223 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7226 [(set_attr "type" "call")
7227 (set (attr "fp_mode")
7228 (if_then_else (eq_attr "fpu_single" "yes")
7229 (const_string "single") (const_string "double")))
7230 (set_attr "needs_delay_slot" "yes")
7231 (set_attr "fp_set" "unknown")])
7233 (define_insn "call_compact"
7234 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7235 (match_operand 1 "" ""))
7236 (match_operand 2 "immediate_operand" "n")
7237 (use (reg:SI R0_REG))
7238 (use (reg:SI R1_REG))
7239 (use (reg:PSI FPSCR_REG))
7240 (clobber (reg:SI PR_REG))]
7241 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7243 [(set_attr "type" "call")
7244 (set (attr "fp_mode")
7245 (if_then_else (eq_attr "fpu_single" "yes")
7246 (const_string "single") (const_string "double")))
7247 (set_attr "needs_delay_slot" "yes")])
7249 (define_insn "call_compact_rettramp"
7250 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7251 (match_operand 1 "" ""))
7252 (match_operand 2 "immediate_operand" "n")
7253 (use (reg:SI R0_REG))
7254 (use (reg:SI R1_REG))
7255 (use (reg:PSI FPSCR_REG))
7256 (clobber (reg:SI R10_REG))
7257 (clobber (reg:SI PR_REG))]
7258 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7260 [(set_attr "type" "call")
7261 (set (attr "fp_mode")
7262 (if_then_else (eq_attr "fpu_single" "yes")
7263 (const_string "single") (const_string "double")))
7264 (set_attr "needs_delay_slot" "yes")])
7266 (define_insn "call_media"
7267 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7268 (match_operand 1 "" ""))
7269 (clobber (reg:DI PR_MEDIA_REG))]
7272 [(set_attr "type" "jump_media")])
7274 (define_insn "call_valuei"
7275 [(set (match_operand 0 "" "=rf")
7276 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7277 (match_operand 2 "" "")))
7278 (use (reg:PSI FPSCR_REG))
7279 (clobber (reg:SI PR_REG))]
7283 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7284 return \"jsr/n\\t@%1\";
7286 return \"jsr\\t@%1%#\";
7288 [(set_attr "type" "call")
7289 (set (attr "fp_mode")
7290 (if_then_else (eq_attr "fpu_single" "yes")
7291 (const_string "single") (const_string "double")))
7292 (set_attr "needs_delay_slot" "yes")
7293 (set_attr "fp_set" "unknown")])
7295 ;; This is TBR relative jump instruction for SH2A architecture.
7296 ;; Its use is enabled assigning an attribute "function_vector"
7297 ;; and the vector number to a function during its declaration.
7299 (define_insn "call_valuei_tbr_rel"
7300 [(set (match_operand 0 "" "=rf")
7301 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7302 (match_operand 2 "" "")))
7303 (use (reg:PSI FPSCR_REG))
7304 (clobber (reg:SI PR_REG))]
7305 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7308 unsigned HOST_WIDE_INT vect_num;
7309 vect_num = sh2a_get_function_vector_number (operands[1]);
7310 operands[3] = GEN_INT (vect_num * 4);
7312 return \"jsr/n\\t@@(%O3,tbr)\";
7314 [(set_attr "type" "call")
7315 (set (attr "fp_mode")
7316 (if_then_else (eq_attr "fpu_single" "yes")
7317 (const_string "single") (const_string "double")))
7318 (set_attr "needs_delay_slot" "no")
7319 (set_attr "fp_set" "unknown")])
7321 (define_insn "call_valuei_pcrel"
7322 [(set (match_operand 0 "" "=rf")
7323 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7324 (match_operand 2 "" "")))
7325 (use (reg:PSI FPSCR_REG))
7326 (use (reg:SI PIC_REG))
7327 (use (match_operand 3 "" ""))
7328 (clobber (reg:SI PR_REG))]
7331 [(set_attr "type" "call")
7332 (set (attr "fp_mode")
7333 (if_then_else (eq_attr "fpu_single" "yes")
7334 (const_string "single") (const_string "double")))
7335 (set_attr "needs_delay_slot" "yes")
7336 (set_attr "fp_set" "unknown")])
7338 (define_insn_and_split "call_value_pcrel"
7339 [(set (match_operand 0 "" "=rf")
7340 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7341 (match_operand 2 "" "")))
7342 (use (reg:PSI FPSCR_REG))
7343 (use (reg:SI PIC_REG))
7344 (clobber (reg:SI PR_REG))
7345 (clobber (match_scratch:SI 3 "=r"))]
7352 rtx lab = PATTERN (gen_call_site ());
7354 if (SYMBOL_REF_LOCAL_P (operands[1]))
7355 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7357 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7358 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7359 operands[2], copy_rtx (lab)));
7362 [(set_attr "type" "call")
7363 (set (attr "fp_mode")
7364 (if_then_else (eq_attr "fpu_single" "yes")
7365 (const_string "single") (const_string "double")))
7366 (set_attr "needs_delay_slot" "yes")
7367 (set_attr "fp_set" "unknown")])
7369 (define_insn "call_value_compact"
7370 [(set (match_operand 0 "" "=rf")
7371 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7372 (match_operand 2 "" "")))
7373 (match_operand 3 "immediate_operand" "n")
7374 (use (reg:SI R0_REG))
7375 (use (reg:SI R1_REG))
7376 (use (reg:PSI FPSCR_REG))
7377 (clobber (reg:SI PR_REG))]
7378 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7380 [(set_attr "type" "call")
7381 (set (attr "fp_mode")
7382 (if_then_else (eq_attr "fpu_single" "yes")
7383 (const_string "single") (const_string "double")))
7384 (set_attr "needs_delay_slot" "yes")])
7386 (define_insn "call_value_compact_rettramp"
7387 [(set (match_operand 0 "" "=rf")
7388 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7389 (match_operand 2 "" "")))
7390 (match_operand 3 "immediate_operand" "n")
7391 (use (reg:SI R0_REG))
7392 (use (reg:SI R1_REG))
7393 (use (reg:PSI FPSCR_REG))
7394 (clobber (reg:SI R10_REG))
7395 (clobber (reg:SI PR_REG))]
7396 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7398 [(set_attr "type" "call")
7399 (set (attr "fp_mode")
7400 (if_then_else (eq_attr "fpu_single" "yes")
7401 (const_string "single") (const_string "double")))
7402 (set_attr "needs_delay_slot" "yes")])
7404 (define_insn "call_value_media"
7405 [(set (match_operand 0 "" "=rf")
7406 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7407 (match_operand 2 "" "")))
7408 (clobber (reg:DI PR_MEDIA_REG))]
7411 [(set_attr "type" "jump_media")])
7413 (define_expand "call"
7414 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7415 (match_operand 1 "" ""))
7416 (match_operand 2 "" "")
7417 (use (reg:PSI FPSCR_REG))
7418 (clobber (reg:SI PR_REG))])]
7424 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7425 emit_call_insn (gen_call_media (operands[0], operands[1]));
7428 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7430 rtx cookie_rtx = operands[2];
7431 long cookie = INTVAL (cookie_rtx);
7432 rtx func = XEXP (operands[0], 0);
7437 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7439 rtx reg = gen_reg_rtx (Pmode);
7441 emit_insn (gen_symGOTPLT2reg (reg, func));
7445 func = legitimize_pic_address (func, Pmode, 0);
7448 r0 = gen_rtx_REG (SImode, R0_REG);
7449 r1 = gen_rtx_REG (SImode, R1_REG);
7451 /* Since such a call function may use all call-clobbered
7452 registers, we force a mode switch earlier, so that we don't
7453 run out of registers when adjusting fpscr for the call. */
7454 emit_insn (gen_force_mode_for_call ());
7457 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7459 operands[0] = force_reg (SImode, operands[0]);
7461 emit_move_insn (r0, func);
7462 emit_move_insn (r1, cookie_rtx);
7464 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7465 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7468 emit_call_insn (gen_call_compact (operands[0], operands[1],
7473 else if (TARGET_SHCOMPACT && flag_pic
7474 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7475 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7477 rtx reg = gen_reg_rtx (Pmode);
7479 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7480 XEXP (operands[0], 0) = reg;
7482 if (!flag_pic && TARGET_SH2A
7483 && MEM_P (operands[0])
7484 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7486 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7488 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7493 if (flag_pic && TARGET_SH2
7494 && MEM_P (operands[0])
7495 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7497 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7502 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7503 operands[1] = operands[2];
7506 emit_call_insn (gen_calli (operands[0], operands[1]));
7510 (define_insn "call_pop_compact"
7511 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7512 (match_operand 1 "" ""))
7513 (match_operand 2 "immediate_operand" "n")
7514 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7515 (match_operand 3 "immediate_operand" "n")))
7516 (use (reg:SI R0_REG))
7517 (use (reg:SI R1_REG))
7518 (use (reg:PSI FPSCR_REG))
7519 (clobber (reg:SI PR_REG))]
7520 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")])
7528 (define_insn "call_pop_compact_rettramp"
7529 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7530 (match_operand 1 "" ""))
7531 (match_operand 2 "immediate_operand" "n")
7532 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533 (match_operand 3 "immediate_operand" "n")))
7534 (use (reg:SI R0_REG))
7535 (use (reg:SI R1_REG))
7536 (use (reg:PSI FPSCR_REG))
7537 (clobber (reg:SI R10_REG))
7538 (clobber (reg:SI PR_REG))]
7539 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7541 [(set_attr "type" "call")
7542 (set (attr "fp_mode")
7543 (if_then_else (eq_attr "fpu_single" "yes")
7544 (const_string "single") (const_string "double")))
7545 (set_attr "needs_delay_slot" "yes")])
7547 (define_expand "call_pop"
7548 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7549 (match_operand 1 "" ""))
7550 (match_operand 2 "" "")
7551 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7552 (match_operand 3 "" "")))])]
7561 gcc_assert (operands[2] && INTVAL (operands[2]));
7562 cookie_rtx = operands[2];
7563 cookie = INTVAL (cookie_rtx);
7564 func = XEXP (operands[0], 0);
7568 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7570 rtx reg = gen_reg_rtx (Pmode);
7571 emit_insn (gen_symGOTPLT2reg (reg, func));
7575 func = legitimize_pic_address (func, Pmode, 0);
7578 r0 = gen_rtx_REG (SImode, R0_REG);
7579 r1 = gen_rtx_REG (SImode, R1_REG);
7581 /* Since such a call function may use all call-clobbered
7582 registers, we force a mode switch earlier, so that we don't
7583 run out of registers when adjusting fpscr for the call. */
7584 emit_insn (gen_force_mode_for_call ());
7586 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7588 operands[0] = force_reg (SImode, operands[0]);
7590 emit_move_insn (r0, func);
7591 emit_move_insn (r1, cookie_rtx);
7593 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7594 emit_call_insn (gen_call_pop_compact_rettramp
7595 (operands[0], operands[1], operands[2], operands[3]));
7597 emit_call_insn (gen_call_pop_compact
7598 (operands[0], operands[1], operands[2], operands[3]));
7603 (define_expand "call_value"
7604 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7605 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7606 (match_operand 2 "" "")))
7607 (match_operand 3 "" "")
7608 (use (reg:PSI FPSCR_REG))
7609 (clobber (reg:SI PR_REG))])]
7615 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7616 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7620 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7622 rtx cookie_rtx = operands[3];
7623 long cookie = INTVAL (cookie_rtx);
7624 rtx func = XEXP (operands[1], 0);
7629 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7631 rtx reg = gen_reg_rtx (Pmode);
7633 emit_insn (gen_symGOTPLT2reg (reg, func));
7637 func = legitimize_pic_address (func, Pmode, 0);
7640 r0 = gen_rtx_REG (SImode, R0_REG);
7641 r1 = gen_rtx_REG (SImode, R1_REG);
7643 /* Since such a call function may use all call-clobbered
7644 registers, we force a mode switch earlier, so that we don't
7645 run out of registers when adjusting fpscr for the call. */
7646 emit_insn (gen_force_mode_for_call ());
7649 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7651 operands[1] = force_reg (SImode, operands[1]);
7653 emit_move_insn (r0, func);
7654 emit_move_insn (r1, cookie_rtx);
7656 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7657 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7662 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7663 operands[2], operands[3]));
7667 else if (TARGET_SHCOMPACT && flag_pic
7668 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7669 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7671 rtx reg = gen_reg_rtx (Pmode);
7673 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7674 XEXP (operands[1], 0) = reg;
7676 if (!flag_pic && TARGET_SH2A
7677 && MEM_P (operands[1])
7678 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7680 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7682 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7683 XEXP (operands[1], 0), operands[2]));
7687 if (flag_pic && TARGET_SH2
7688 && MEM_P (operands[1])
7689 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7691 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7696 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7698 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7702 (define_insn "sibcalli"
7703 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7704 (match_operand 1 "" ""))
7705 (use (reg:PSI FPSCR_REG))
7709 [(set_attr "needs_delay_slot" "yes")
7710 (set (attr "fp_mode")
7711 (if_then_else (eq_attr "fpu_single" "yes")
7712 (const_string "single") (const_string "double")))
7713 (set_attr "type" "jump_ind")])
7715 (define_insn "sibcalli_pcrel"
7716 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7717 (match_operand 1 "" ""))
7718 (use (match_operand 2 "" ""))
7719 (use (reg:PSI FPSCR_REG))
7723 [(set_attr "needs_delay_slot" "yes")
7724 (set (attr "fp_mode")
7725 (if_then_else (eq_attr "fpu_single" "yes")
7726 (const_string "single") (const_string "double")))
7727 (set_attr "type" "jump_ind")])
7729 ;; This uses an unspec to describe that the symbol_ref is very close.
7730 (define_insn "sibcalli_thunk"
7731 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7733 (match_operand 1 "" ""))
7734 (use (reg:PSI FPSCR_REG))
7738 [(set_attr "needs_delay_slot" "yes")
7739 (set (attr "fp_mode")
7740 (if_then_else (eq_attr "fpu_single" "yes")
7741 (const_string "single") (const_string "double")))
7742 (set_attr "type" "jump")
7743 (set_attr "length" "2")])
7745 (define_insn_and_split "sibcall_pcrel"
7746 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7747 (match_operand 1 "" ""))
7748 (use (reg:PSI FPSCR_REG))
7749 (clobber (match_scratch:SI 2 "=k"))
7757 rtx lab = PATTERN (gen_call_site ());
7760 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7761 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7763 SIBLING_CALL_P (call_insn) = 1;
7766 [(set_attr "needs_delay_slot" "yes")
7767 (set (attr "fp_mode")
7768 (if_then_else (eq_attr "fpu_single" "yes")
7769 (const_string "single") (const_string "double")))
7770 (set_attr "type" "jump_ind")])
7772 (define_insn "sibcall_compact"
7773 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7774 (match_operand 1 "" ""))
7776 (use (match_operand:SI 2 "register_operand" "z,x"))
7777 (use (reg:SI R1_REG))
7778 (use (reg:PSI FPSCR_REG))
7779 ;; We want to make sure the `x' above will only match MACH_REG
7780 ;; because sibcall_epilogue may clobber MACL_REG.
7781 (clobber (reg:SI MACL_REG))]
7785 jmp @%0\\n sts %2, r0"
7786 [(set_attr "needs_delay_slot" "yes,no")
7787 (set_attr "length" "2,4")
7788 (set (attr "fp_mode") (const_string "single"))
7789 (set_attr "type" "jump_ind")])
7791 (define_insn "sibcall_media"
7792 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7793 (match_operand 1 "" ""))
7794 (use (reg:SI PR_MEDIA_REG))
7798 [(set_attr "type" "jump_media")])
7800 (define_expand "sibcall"
7802 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7803 (match_operand 1 "" ""))
7804 (match_operand 2 "" "")
7805 (use (reg:PSI FPSCR_REG))
7812 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7813 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7816 else if (TARGET_SHCOMPACT && operands[2]
7817 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7819 rtx cookie_rtx = operands[2];
7820 long cookie = INTVAL (cookie_rtx);
7821 rtx func = XEXP (operands[0], 0);
7826 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7828 rtx reg = gen_reg_rtx (Pmode);
7830 emit_insn (gen_symGOT2reg (reg, func));
7834 func = legitimize_pic_address (func, Pmode, 0);
7837 /* FIXME: if we could tell whether all argument registers are
7838 already taken, we could decide whether to force the use of
7839 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7840 simple way to tell. We could use the CALL_COOKIE, but we
7841 can't currently tell a register used for regular argument
7842 passing from one that is unused. If we leave it up to reload
7843 to decide which register to use, it seems to always choose
7844 R0_REG, which leaves no available registers in SIBCALL_REGS
7845 to hold the address of the trampoline. */
7846 mach = gen_rtx_REG (SImode, MACH_REG);
7847 r1 = gen_rtx_REG (SImode, R1_REG);
7849 /* Since such a call function may use all call-clobbered
7850 registers, we force a mode switch earlier, so that we don't
7851 run out of registers when adjusting fpscr for the call. */
7852 emit_insn (gen_force_mode_for_call ());
7855 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7857 operands[0] = force_reg (SImode, operands[0]);
7859 /* We don't need a return trampoline, since the callee will
7860 return directly to the upper caller. */
7861 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7863 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7864 cookie_rtx = GEN_INT (cookie);
7867 emit_move_insn (mach, func);
7868 emit_move_insn (r1, cookie_rtx);
7870 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7873 else if (TARGET_SHCOMPACT && flag_pic
7874 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7875 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7877 rtx reg = gen_reg_rtx (Pmode);
7879 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7880 XEXP (operands[0], 0) = reg;
7882 if (flag_pic && TARGET_SH2
7883 && MEM_P (operands[0])
7884 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7885 /* The PLT needs the PIC register, but the epilogue would have
7886 to restore it, so we can only use PC-relative PIC calls for
7887 static functions. */
7888 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7890 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7894 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7896 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7900 (define_insn "sibcall_valuei"
7901 [(set (match_operand 0 "" "=rf")
7902 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7903 (match_operand 2 "" "")))
7904 (use (reg:PSI FPSCR_REG))
7908 [(set_attr "needs_delay_slot" "yes")
7909 (set (attr "fp_mode")
7910 (if_then_else (eq_attr "fpu_single" "yes")
7911 (const_string "single") (const_string "double")))
7912 (set_attr "type" "jump_ind")])
7914 (define_insn "sibcall_valuei_pcrel"
7915 [(set (match_operand 0 "" "=rf")
7916 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7917 (match_operand 2 "" "")))
7918 (use (match_operand 3 "" ""))
7919 (use (reg:PSI FPSCR_REG))
7923 [(set_attr "needs_delay_slot" "yes")
7924 (set (attr "fp_mode")
7925 (if_then_else (eq_attr "fpu_single" "yes")
7926 (const_string "single") (const_string "double")))
7927 (set_attr "type" "jump_ind")])
7929 (define_insn_and_split "sibcall_value_pcrel"
7930 [(set (match_operand 0 "" "=rf")
7931 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7932 (match_operand 2 "" "")))
7933 (use (reg:PSI FPSCR_REG))
7934 (clobber (match_scratch:SI 3 "=k"))
7942 rtx lab = PATTERN (gen_call_site ());
7945 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7946 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7950 SIBLING_CALL_P (call_insn) = 1;
7953 [(set_attr "needs_delay_slot" "yes")
7954 (set (attr "fp_mode")
7955 (if_then_else (eq_attr "fpu_single" "yes")
7956 (const_string "single") (const_string "double")))
7957 (set_attr "type" "jump_ind")])
7959 (define_insn "sibcall_value_compact"
7960 [(set (match_operand 0 "" "=rf,rf")
7961 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7962 (match_operand 2 "" "")))
7964 (use (match_operand:SI 3 "register_operand" "z,x"))
7965 (use (reg:SI R1_REG))
7966 (use (reg:PSI FPSCR_REG))
7967 ;; We want to make sure the `x' above will only match MACH_REG
7968 ;; because sibcall_epilogue may clobber MACL_REG.
7969 (clobber (reg:SI MACL_REG))]
7973 jmp @%1\\n sts %3, r0"
7974 [(set_attr "needs_delay_slot" "yes,no")
7975 (set_attr "length" "2,4")
7976 (set (attr "fp_mode") (const_string "single"))
7977 (set_attr "type" "jump_ind")])
7979 (define_insn "sibcall_value_media"
7980 [(set (match_operand 0 "" "=rf")
7981 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7982 (match_operand 2 "" "")))
7983 (use (reg:SI PR_MEDIA_REG))
7987 [(set_attr "type" "jump_media")])
7989 (define_expand "sibcall_value"
7991 [(set (match_operand 0 "arith_reg_operand" "")
7992 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7993 (match_operand 2 "" "")))
7994 (match_operand 3 "" "")
7995 (use (reg:PSI FPSCR_REG))
8002 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8003 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8007 else if (TARGET_SHCOMPACT && operands[3]
8008 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8010 rtx cookie_rtx = operands[3];
8011 long cookie = INTVAL (cookie_rtx);
8012 rtx func = XEXP (operands[1], 0);
8017 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8019 rtx reg = gen_reg_rtx (Pmode);
8021 emit_insn (gen_symGOT2reg (reg, func));
8025 func = legitimize_pic_address (func, Pmode, 0);
8028 /* FIXME: if we could tell whether all argument registers are
8029 already taken, we could decide whether to force the use of
8030 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8031 simple way to tell. We could use the CALL_COOKIE, but we
8032 can't currently tell a register used for regular argument
8033 passing from one that is unused. If we leave it up to reload
8034 to decide which register to use, it seems to always choose
8035 R0_REG, which leaves no available registers in SIBCALL_REGS
8036 to hold the address of the trampoline. */
8037 mach = gen_rtx_REG (SImode, MACH_REG);
8038 r1 = gen_rtx_REG (SImode, R1_REG);
8040 /* Since such a call function may use all call-clobbered
8041 registers, we force a mode switch earlier, so that we don't
8042 run out of registers when adjusting fpscr for the call. */
8043 emit_insn (gen_force_mode_for_call ());
8046 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8048 operands[1] = force_reg (SImode, operands[1]);
8050 /* We don't need a return trampoline, since the callee will
8051 return directly to the upper caller. */
8052 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8054 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8055 cookie_rtx = GEN_INT (cookie);
8058 emit_move_insn (mach, func);
8059 emit_move_insn (r1, cookie_rtx);
8061 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8062 operands[2], mach));
8065 else if (TARGET_SHCOMPACT && flag_pic
8066 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8067 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8069 rtx reg = gen_reg_rtx (Pmode);
8071 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8072 XEXP (operands[1], 0) = reg;
8074 if (flag_pic && TARGET_SH2
8075 && MEM_P (operands[1])
8076 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8077 /* The PLT needs the PIC register, but the epilogue would have
8078 to restore it, so we can only use PC-relative PIC calls for
8079 static functions. */
8080 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8082 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8083 XEXP (operands[1], 0),
8088 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8090 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8094 (define_insn "call_value_pop_compact"
8095 [(set (match_operand 0 "" "=rf")
8096 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8097 (match_operand 2 "" "")))
8098 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8099 (match_operand 4 "immediate_operand" "n")))
8100 (match_operand 3 "immediate_operand" "n")
8101 (use (reg:SI R0_REG))
8102 (use (reg:SI R1_REG))
8103 (use (reg:PSI FPSCR_REG))
8104 (clobber (reg:SI PR_REG))]
8105 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8107 [(set_attr "type" "call")
8108 (set (attr "fp_mode")
8109 (if_then_else (eq_attr "fpu_single" "yes")
8110 (const_string "single") (const_string "double")))
8111 (set_attr "needs_delay_slot" "yes")])
8113 (define_insn "call_value_pop_compact_rettramp"
8114 [(set (match_operand 0 "" "=rf")
8115 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8116 (match_operand 2 "" "")))
8117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8118 (match_operand 4 "immediate_operand" "n")))
8119 (match_operand 3 "immediate_operand" "n")
8120 (use (reg:SI R0_REG))
8121 (use (reg:SI R1_REG))
8122 (use (reg:PSI FPSCR_REG))
8123 (clobber (reg:SI R10_REG))
8124 (clobber (reg:SI PR_REG))]
8125 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8127 [(set_attr "type" "call")
8128 (set (attr "fp_mode")
8129 (if_then_else (eq_attr "fpu_single" "yes")
8130 (const_string "single") (const_string "double")))
8131 (set_attr "needs_delay_slot" "yes")])
8133 (define_expand "call_value_pop"
8134 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8135 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8136 (match_operand 2 "" "")))
8137 (match_operand 3 "" "")
8138 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8139 (match_operand 4 "" "")))])]
8148 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8149 cookie_rtx = operands[3];
8150 cookie = INTVAL (cookie_rtx);
8151 func = XEXP (operands[1], 0);
8155 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8157 rtx reg = gen_reg_rtx (Pmode);
8159 emit_insn (gen_symGOTPLT2reg (reg, func));
8163 func = legitimize_pic_address (func, Pmode, 0);
8166 r0 = gen_rtx_REG (SImode, R0_REG);
8167 r1 = gen_rtx_REG (SImode, R1_REG);
8169 /* Since such a call function may use all call-clobbered
8170 registers, we force a mode switch earlier, so that we don't
8171 run out of registers when adjusting fpscr for the call. */
8172 emit_insn (gen_force_mode_for_call ());
8174 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8176 operands[1] = force_reg (SImode, operands[1]);
8178 emit_move_insn (r0, func);
8179 emit_move_insn (r1, cookie_rtx);
8181 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8182 emit_call_insn (gen_call_value_pop_compact_rettramp
8183 (operands[0], operands[1], operands[2],
8184 operands[3], operands[4]));
8186 emit_call_insn (gen_call_value_pop_compact
8187 (operands[0], operands[1], operands[2],
8188 operands[3], operands[4]));
8193 (define_expand "sibcall_epilogue"
8198 sh_expand_epilogue (1);
8199 if (TARGET_SHCOMPACT)
8203 /* If epilogue clobbers r0, preserve it in macl. */
8204 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8205 if ((set = single_set (insn))
8206 && REG_P (SET_DEST (set))
8207 && REGNO (SET_DEST (set)) == R0_REG)
8209 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8210 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8212 /* We can't tell at this point whether the sibcall is a
8213 sibcall_compact and, if it is, whether it uses r0 or
8214 mach as operand 2, so let the instructions that
8215 preserve r0 be optimized away if r0 turns out to be
8217 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8218 emit_move_insn (r0, tmp);
8225 (define_insn "indirect_jump_compact"
8227 (match_operand:SI 0 "arith_reg_operand" "r"))]
8230 [(set_attr "needs_delay_slot" "yes")
8231 (set_attr "type" "jump_ind")])
8233 (define_expand "indirect_jump"
8235 (match_operand 0 "register_operand" ""))]
8239 if (GET_MODE (operands[0]) != Pmode)
8240 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8243 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8244 ;; which can be present in structured code from indirect jumps which can not
8245 ;; be present in structured code. This allows -fprofile-arcs to work.
8247 ;; For SH1 processors.
8248 (define_insn "casesi_jump_1"
8250 (match_operand:SI 0 "register_operand" "r"))
8251 (use (label_ref (match_operand 1 "" "")))]
8254 [(set_attr "needs_delay_slot" "yes")
8255 (set_attr "type" "jump_ind")])
8257 ;; For all later processors.
8258 (define_insn "casesi_jump_2"
8259 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8260 (label_ref (match_operand 1 "" ""))))
8261 (use (label_ref (match_operand 2 "" "")))]
8263 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8265 [(set_attr "needs_delay_slot" "yes")
8266 (set_attr "type" "jump_ind")])
8268 (define_insn "casesi_jump_media"
8269 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8270 (use (label_ref (match_operand 1 "" "")))]
8273 [(set_attr "type" "jump_media")])
8275 ;; Call subroutine returning any type.
8276 ;; ??? This probably doesn't work.
8278 (define_expand "untyped_call"
8279 [(parallel [(call (match_operand 0 "" "")
8281 (match_operand 1 "" "")
8282 (match_operand 2 "" "")])]
8283 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8288 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8290 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8292 rtx set = XVECEXP (operands[2], 0, i);
8293 emit_move_insn (SET_DEST (set), SET_SRC (set));
8296 /* The optimizer does not know that the call sets the function value
8297 registers we stored in the result block. We avoid problems by
8298 claiming that all hard registers are used and clobbered at this
8300 emit_insn (gen_blockage ());
8305 ;; ------------------------------------------------------------------------
8307 ;; ------------------------------------------------------------------------
8310 [(set (reg:SI T_REG)
8311 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8312 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8313 (plus:SI (match_dup 1) (const_int -1)))]
8316 [(set_attr "type" "arith")])
8323 ;; Load address of a label. This is only generated by the casesi expand,
8324 ;; and by machine_dependent_reorg (fixing up fp moves).
8325 ;; This must use unspec, because this only works for labels that are
8329 [(set (reg:SI R0_REG)
8330 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8333 [(set_attr "in_delay_slot" "no")
8334 (set_attr "type" "arith")])
8336 ;; machine_dependent_reorg will make this a `mova'.
8337 (define_insn "mova_const"
8338 [(set (reg:SI R0_REG)
8339 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8342 [(set_attr "in_delay_slot" "no")
8343 (set_attr "type" "arith")])
8345 (define_expand "GOTaddr2picreg"
8346 [(set (reg:SI R0_REG)
8347 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8349 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8350 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8353 if (TARGET_VXWORKS_RTP)
8355 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8356 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8357 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8361 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8362 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8366 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8367 rtx pic = operands[0];
8368 rtx lab = PATTERN (gen_call_site ());
8371 equiv = operands[1];
8372 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8373 UNSPEC_PCREL_SYMOFF);
8374 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8376 if (Pmode == SImode)
8378 emit_insn (gen_movsi_const (pic, operands[1]));
8379 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8383 emit_insn (gen_movdi_const (pic, operands[1]));
8384 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8387 insn = emit_move_insn (operands[0], tr);
8389 set_unique_reg_note (insn, REG_EQUAL, equiv);
8396 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8399 (define_expand "vxworks_picreg"
8400 [(set (reg:SI PIC_REG)
8401 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8402 (set (reg:SI R0_REG)
8403 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8404 (set (reg:SI PIC_REG)
8405 (mem:SI (reg:SI PIC_REG)))
8406 (set (reg:SI PIC_REG)
8407 (mem:SI (plus:SI (reg:SI PIC_REG)
8409 "TARGET_VXWORKS_RTP")
8412 [(set (match_operand 0 "target_reg_operand" "=b")
8413 (const (unspec [(match_operand 1 "" "Csy")]
8414 UNSPEC_DATALABEL)))]
8415 "TARGET_SHMEDIA && flag_pic
8416 && satisfies_constraint_Csy (operands[1])"
8417 "ptb/u datalabel %1, %0"
8418 [(set_attr "type" "ptabs_media")
8419 (set_attr "length" "*")])
8421 (define_insn "ptrel_si"
8422 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8423 (plus:SI (match_operand:SI 1 "register_operand" "r")
8425 (match_operand:SI 2 "" "")]
8427 "%O2: ptrel/u %1, %0"
8428 [(set_attr "type" "ptabs_media")])
8430 (define_insn "ptrel_di"
8431 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8432 (plus:DI (match_operand:DI 1 "register_operand" "r")
8434 (match_operand:DI 2 "" "")]
8436 "%O2: ptrel/u %1, %0"
8437 [(set_attr "type" "ptabs_media")])
8439 (define_expand "builtin_setjmp_receiver"
8440 [(match_operand 0 "" "")]
8444 emit_insn (gen_GOTaddr2picreg ());
8448 (define_expand "call_site"
8449 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8453 static HOST_WIDE_INT i = 0;
8454 operands[0] = GEN_INT (i);
8458 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
8459 ;; in symGOT_load expand.
8461 (define_insn_and_split "chk_guard_add"
8462 [(set (match_operand:SI 0 "register_operand" "=&r")
8463 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8468 "TARGET_SH1 && reload_completed"
8469 [(set (match_dup 0) (reg:SI PIC_REG))
8470 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8472 [(set_attr "type" "arith")])
8474 (define_expand "sym_label2reg"
8475 [(set (match_operand:SI 0 "" "")
8476 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8477 (const (plus:SI (match_operand:SI 2 "" "")
8482 (define_expand "symGOT_load"
8483 [(set (match_dup 2) (match_operand 1 "" ""))
8484 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8485 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8491 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8492 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8496 rtx reg = operands[2];
8498 if (Pmode == DImode)
8501 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8503 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8508 emit_insn (gen_movsi_const (reg, operands[1]));
8510 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8514 emit_move_insn (operands[2], operands[1]);
8516 /* When stack protector inserts codes after the result is set to
8517 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
8518 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8519 when rX is a GOT address for the guard symbol. Ugly but doesn't
8520 matter because this is a rare situation. */
8522 && flag_stack_protect
8523 && GET_CODE (operands[1]) == CONST
8524 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8525 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8526 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8527 \"__stack_chk_guard\") == 0)
8528 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8530 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8531 gen_rtx_REG (Pmode, PIC_REG)));
8533 /* N.B. This is not constant for a GOTPLT relocation. */
8534 mem = gen_rtx_MEM (Pmode, operands[3]);
8535 MEM_NOTRAP_P (mem) = 1;
8536 /* ??? Should we have a special alias set for the GOT? */
8537 emit_move_insn (operands[0], mem);
8542 (define_expand "sym2GOT"
8543 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8547 (define_expand "symGOT2reg"
8548 [(match_operand 0 "" "") (match_operand 1 "" "")]
8554 gotsym = gen_sym2GOT (operands[1]);
8555 PUT_MODE (gotsym, Pmode);
8556 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8558 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8563 (define_expand "symGOTPLT2reg"
8564 [(match_operand 0 "" "") (match_operand 1 "" "")]
8568 rtx pltsym = gen_rtx_CONST (Pmode,
8569 gen_rtx_UNSPEC (Pmode,
8570 gen_rtvec (1, operands[1]),
8572 emit_insn (gen_symGOT_load (operands[0], pltsym));
8576 (define_expand "sym2GOTOFF"
8577 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8581 (define_expand "symGOTOFF2reg"
8582 [(match_operand 0 "" "") (match_operand 1 "" "")]
8586 rtx gotoffsym, insn;
8587 rtx t = (!can_create_pseudo_p ()
8589 : gen_reg_rtx (GET_MODE (operands[0])));
8591 gotoffsym = gen_sym2GOTOFF (operands[1]);
8592 PUT_MODE (gotoffsym, Pmode);
8593 emit_move_insn (t, gotoffsym);
8594 insn = emit_move_insn (operands[0],
8595 gen_rtx_PLUS (Pmode, t,
8596 gen_rtx_REG (Pmode, PIC_REG)));
8598 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8603 (define_expand "symPLT_label2reg"
8604 [(set (match_operand:SI 0 "" "")
8607 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8608 (const:SI (plus:SI (match_operand:SI 2 "" "")
8609 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8610 ;; Even though the PIC register is not really used by the call
8611 ;; sequence in which this is expanded, the PLT code assumes the PIC
8612 ;; register is set, so we must not skip its initialization. Since
8613 ;; we only use this expand as part of calling sequences, and never
8614 ;; to take the address of a function, this is the best point to
8615 ;; insert the (use). Using the PLT to take the address of a
8616 ;; function would be wrong, not only because the PLT entry could
8617 ;; then be called from a function that doesn't initialize the PIC
8618 ;; register to the proper GOT, but also because pointers to the
8619 ;; same function might not compare equal, should they be set by
8620 ;; different shared libraries.
8621 (use (reg:SI PIC_REG))]
8625 (define_expand "sym2PIC"
8626 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8630 ;; TLS code generation.
8631 ;; ??? this should be a define_insn_and_split
8632 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8633 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8636 (define_insn "tls_global_dynamic"
8637 [(set (match_operand:SI 0 "register_operand" "=&z")
8638 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8641 (use (reg:PSI FPSCR_REG))
8642 (use (reg:SI PIC_REG))
8643 (clobber (reg:SI PR_REG))
8644 (clobber (scratch:SI))]
8650 \\tmova\\t2f,r0\\n\\
8651 \\tmov.l\\t2f,r1\\n\\
8654 \\tadd\\tr12,r4\\n\\
8658 1:\\t.long\\t%a1@TLSGD\\n\\
8659 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8662 [(set_attr "type" "tls_load")
8663 (set_attr "length" "26")])
8665 (define_insn "tls_local_dynamic"
8666 [(set (match_operand:SI 0 "register_operand" "=&z")
8667 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8670 (use (reg:PSI FPSCR_REG))
8671 (use (reg:SI PIC_REG))
8672 (clobber (reg:SI PR_REG))
8673 (clobber (scratch:SI))]
8679 \\tmova\\t2f,r0\\n\\
8680 \\tmov.l\\t2f,r1\\n\\
8683 \\tadd\\tr12,r4\\n\\
8687 1:\\t.long\\t%a1@TLSLDM\\n\\
8688 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8691 [(set_attr "type" "tls_load")
8692 (set_attr "length" "26")])
8694 (define_expand "sym2DTPOFF"
8695 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8699 (define_expand "symDTPOFF2reg"
8700 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8705 rtx t = (!can_create_pseudo_p ()
8707 : gen_reg_rtx (GET_MODE (operands[0])));
8709 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8710 PUT_MODE (dtpoffsym, Pmode);
8711 emit_move_insn (t, dtpoffsym);
8712 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8716 (define_expand "sym2GOTTPOFF"
8717 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8721 (define_insn "tls_initial_exec"
8722 [(set (match_operand:SI 0 "register_operand" "=&r")
8723 (unspec:SI [(match_operand:SI 1 "" "")]
8725 (use (reg:SI GBR_REG))
8726 (use (reg:SI PIC_REG))
8727 (clobber (reg:SI R0_REG))]
8733 \\tstc\\tgbr,%0\\n\\
8734 \\tmov.l\\t@(r0,r12),r0\\n\\
8738 1:\\t.long\\t%a1\\n\\
8741 [(set_attr "type" "tls_load")
8742 (set_attr "length" "16")])
8744 (define_expand "sym2TPOFF"
8745 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8749 (define_expand "symTPOFF2reg"
8750 [(match_operand 0 "" "") (match_operand 1 "" "")]
8756 tpoffsym = gen_sym2TPOFF (operands[1]);
8757 PUT_MODE (tpoffsym, Pmode);
8758 emit_move_insn (operands[0], tpoffsym);
8762 (define_insn "load_gbr"
8763 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8764 (use (reg:SI GBR_REG))]
8767 [(set_attr "type" "tls_load")])
8769 ;; case instruction for switch statements.
8771 ;; Operand 0 is index
8772 ;; operand 1 is the minimum bound
8773 ;; operand 2 is the maximum bound - minimum bound + 1
8774 ;; operand 3 is CODE_LABEL for the table;
8775 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8777 (define_expand "casesi"
8778 [(match_operand:SI 0 "arith_reg_operand" "")
8779 (match_operand:SI 1 "arith_reg_operand" "")
8780 (match_operand:SI 2 "arith_reg_operand" "")
8781 (match_operand 3 "" "") (match_operand 4 "" "")]
8785 rtx reg = gen_reg_rtx (SImode);
8786 rtx reg2 = gen_reg_rtx (SImode);
8789 rtx reg = gen_reg_rtx (DImode);
8790 rtx reg2 = gen_reg_rtx (DImode);
8791 rtx reg3 = gen_reg_rtx (Pmode);
8792 rtx reg4 = gen_reg_rtx (Pmode);
8793 rtx reg5 = gen_reg_rtx (Pmode);
8796 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8797 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8798 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8800 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8801 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8802 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8803 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8804 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8805 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8806 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8807 (Pmode, operands[3])));
8808 /* Messy: can we subreg to clean this up? */
8809 if (Pmode == DImode)
8810 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8812 load = gen_casesi_load_media (reg4,
8813 gen_rtx_SUBREG (DImode, reg3, 0),
8815 PUT_MODE (SET_SRC (load), Pmode);
8817 /* ??? The following add could be eliminated if we used ptrel. */
8818 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8819 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8823 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8824 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8825 /* If optimizing, casesi_worker depends on the mode of the instruction
8826 before label it 'uses' - operands[3]. */
8827 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8829 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8831 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8833 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8834 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8835 operands[3], but to lab. We will fix this up in
8836 machine_dependent_reorg. */
8841 (define_expand "casesi_0"
8842 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8843 (set (match_dup 4) (minus:SI (match_dup 4)
8844 (match_operand:SI 1 "arith_operand" "")))
8846 (gtu:SI (match_dup 4)
8847 (match_operand:SI 2 "arith_reg_operand" "")))
8849 (if_then_else (ne (reg:SI T_REG)
8851 (label_ref (match_operand 3 "" ""))
8856 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8857 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8858 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8860 (define_insn "casesi_worker_0"
8861 [(set (match_operand:SI 0 "register_operand" "=r,r")
8862 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8863 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8864 (clobber (match_scratch:SI 3 "=X,1"))
8865 (clobber (match_scratch:SI 4 "=&z,z"))]
8870 [(set (match_operand:SI 0 "register_operand" "")
8871 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8872 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8873 (clobber (match_scratch:SI 3 ""))
8874 (clobber (match_scratch:SI 4 ""))]
8875 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8876 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8877 (parallel [(set (match_dup 0)
8878 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8879 (label_ref (match_dup 2))] UNSPEC_CASESI))
8880 (clobber (match_dup 3))])
8881 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8882 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8885 [(set (match_operand:SI 0 "register_operand" "")
8886 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8887 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8888 (clobber (match_scratch:SI 3 ""))
8889 (clobber (match_scratch:SI 4 ""))]
8890 "TARGET_SH2 && reload_completed"
8891 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8892 (parallel [(set (match_dup 0)
8893 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8894 (label_ref (match_dup 2))] UNSPEC_CASESI))
8895 (clobber (match_dup 3))])]
8896 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8898 (define_insn "casesi_worker_1"
8899 [(set (match_operand:SI 0 "register_operand" "=r,r")
8900 (unspec:SI [(reg:SI R0_REG)
8901 (match_operand:SI 1 "register_operand" "0,r")
8902 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8903 (clobber (match_scratch:SI 3 "=X,1"))]
8907 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8909 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8911 switch (GET_MODE (diff_vec))
8914 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8916 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8918 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8919 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8920 return \"mov.b @(r0,%1),%0\";
8925 [(set_attr "length" "4")])
8927 (define_insn "casesi_worker_2"
8928 [(set (match_operand:SI 0 "register_operand" "=r,r")
8929 (unspec:SI [(reg:SI R0_REG)
8930 (match_operand:SI 1 "register_operand" "0,r")
8931 (label_ref (match_operand 2 "" ""))
8932 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8933 (clobber (match_operand:SI 4 "" "=X,1"))]
8934 "TARGET_SH2 && reload_completed && flag_pic"
8937 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8940 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8942 switch (GET_MODE (diff_vec))
8945 output_asm_insn (\"shll2 %1\", operands);
8946 load = \"mov.l @(r0,%1),%0\"; break;
8948 output_asm_insn (\"add %1,%1\", operands);
8949 load = \"mov.w @(r0,%1),%0\"; break;
8951 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8952 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8954 load = \"mov.b @(r0,%1),%0\";
8959 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8962 [(set_attr "length" "8")])
8964 (define_insn "casesi_shift_media"
8965 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8966 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8967 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8972 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8974 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8976 switch (GET_MODE (diff_vec))
8979 return \"shlli %1, 2, %0\";
8981 return \"shlli %1, 1, %0\";
8983 if (rtx_equal_p (operands[0], operands[1]))
8985 return \"add %1, r63, %0\";
8990 [(set_attr "type" "arith_media")])
8992 (define_insn "casesi_load_media"
8993 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8994 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8995 (match_operand:DI 2 "arith_reg_operand" "r")
8996 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9000 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9002 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9004 switch (GET_MODE (diff_vec))
9007 return \"ldx.l %1, %2, %0\";
9010 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9011 return \"ldx.uw %1, %2, %0\";
9013 return \"ldx.w %1, %2, %0\";
9015 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9016 return \"ldx.ub %1, %2, %0\";
9017 return \"ldx.b %1, %2, %0\";
9022 [(set_attr "type" "load_media")])
9024 (define_expand "return"
9026 "reload_completed && ! sh_need_epilogue ()"
9031 emit_jump_insn (gen_return_media ());
9035 if (TARGET_SHCOMPACT
9036 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9038 emit_jump_insn (gen_shcompact_return_tramp ());
9043 (define_insn "*return_i"
9045 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9046 && (crtl->args.info.call_cookie
9047 & CALL_COOKIE_RET_TRAMP (1)))
9049 && lookup_attribute (\"trap_exit\",
9050 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9053 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9054 && !current_function_interrupt)
9059 [(set_attr "type" "return")
9060 (set_attr "needs_delay_slot" "yes")])
9062 ;; trapa has no delay slot.
9063 (define_insn "*return_trapa"
9065 "TARGET_SH1 && !TARGET_SHCOMPACT
9066 && reload_completed"
9068 [(set_attr "type" "return")])
9070 (define_expand "shcompact_return_tramp"
9073 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9076 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9078 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9079 emit_jump_insn (gen_shcompact_return_tramp_i ());
9083 (define_insn "shcompact_return_tramp_i"
9084 [(parallel [(return) (use (reg:SI R0_REG))])]
9086 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9088 [(set_attr "type" "jump_ind")
9089 (set_attr "needs_delay_slot" "yes")])
9091 (define_insn "return_media_i"
9092 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9093 "TARGET_SHMEDIA && reload_completed"
9095 [(set_attr "type" "jump_media")])
9097 (define_insn "return_media_rte"
9099 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9101 [(set_attr "type" "jump_media")])
9103 (define_expand "return_media"
9105 "TARGET_SHMEDIA && reload_completed"
9108 int tr_regno = sh_media_register_for_return ();
9111 if (current_function_interrupt)
9113 emit_jump_insn (gen_return_media_rte ());
9118 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9120 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9122 tr = gen_rtx_REG (Pmode, tr_regno);
9123 emit_move_insn (tr, r18);
9126 tr = gen_rtx_REG (Pmode, tr_regno);
9128 emit_jump_insn (gen_return_media_i (tr));
9132 (define_insn "shcompact_preserve_incoming_args"
9133 [(set (match_operand:SI 0 "register_operand" "+r")
9134 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9137 [(set_attr "length" "0")])
9139 (define_insn "shcompact_incoming_args"
9140 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9141 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9142 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9143 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9144 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9145 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9146 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9147 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9148 (set (mem:BLK (reg:SI MACL_REG))
9149 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9150 (use (reg:SI R0_REG))
9151 (clobber (reg:SI R0_REG))
9152 (clobber (reg:SI MACL_REG))
9153 (clobber (reg:SI MACH_REG))
9154 (clobber (reg:SI PR_REG))]
9157 [(set_attr "needs_delay_slot" "yes")])
9159 (define_insn "shmedia_save_restore_regs_compact"
9160 [(set (reg:SI SP_REG)
9161 (plus:SI (reg:SI SP_REG)
9162 (match_operand:SI 0 "immediate_operand" "i")))
9163 (use (reg:SI R0_REG))
9164 (clobber (reg:SI PR_REG))]
9166 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9167 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9169 [(set_attr "needs_delay_slot" "yes")])
9171 (define_expand "prologue"
9174 "sh_expand_prologue (); DONE;")
9176 (define_expand "epilogue"
9181 sh_expand_epilogue (0);
9182 emit_jump_insn (gen_return ());
9186 (define_expand "eh_return"
9187 [(use (match_operand 0 "register_operand" ""))]
9190 rtx ra = operands[0];
9192 if (TARGET_SHMEDIA64)
9193 emit_insn (gen_eh_set_ra_di (ra));
9195 emit_insn (gen_eh_set_ra_si (ra));
9200 ;; Clobber the return address on the stack. We can't expand this
9201 ;; until we know where it will be put in the stack frame.
9203 (define_insn "eh_set_ra_si"
9204 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9206 (clobber (match_scratch:SI 1 "=&r"))]
9207 "! TARGET_SHMEDIA64"
9210 (define_insn "eh_set_ra_di"
9211 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9213 (clobber (match_scratch:DI 1 "=&r"))]
9218 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9220 (clobber (match_scratch 1 ""))]
9225 sh_set_return_address (operands[0], operands[1]);
9229 (define_insn "blockage"
9230 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9233 [(set_attr "length" "0")])
9235 ;; Define movml instructions for SH2A target. Currently they are
9236 ;; used to push and pop all banked registers only.
9238 (define_insn "movml_push_banked"
9239 [(set (match_operand:SI 0 "register_operand" "=r")
9240 (plus (match_dup 0) (const_int -32)))
9241 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9242 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9243 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9244 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9245 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9246 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9247 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9248 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9249 "TARGET_SH2A && REGNO (operands[0]) == 15"
9251 [(set_attr "in_delay_slot" "no")])
9253 (define_insn "movml_pop_banked"
9254 [(set (match_operand:SI 0 "register_operand" "=r")
9255 (plus (match_dup 0) (const_int 32)))
9256 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9257 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9258 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9259 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9260 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9261 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9262 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9263 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9264 "TARGET_SH2A && REGNO (operands[0]) == 15"
9266 [(set_attr "in_delay_slot" "no")])
9268 ;; ------------------------------------------------------------------------
9270 ;; ------------------------------------------------------------------------
9273 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9274 (eq:SI (reg:SI T_REG) (const_int 1)))]
9277 [(set_attr "type" "arith")])
9279 (define_expand "cstore4_media"
9280 [(set (match_operand:SI 0 "register_operand" "=r")
9281 (match_operator:SI 1 "sh_float_comparison_operator"
9282 [(match_operand 2 "logical_operand" "")
9283 (match_operand 3 "cmp_operand" "")]))]
9287 enum machine_mode mode = GET_MODE (operands[2]);
9288 enum rtx_code code = GET_CODE (operands[1]);
9290 if (mode == VOIDmode)
9291 mode = GET_MODE (operands[3]);
9292 if (operands[2] == const0_rtx)
9294 if (code == EQ || code == NE)
9295 operands[2] = operands[3], operands[3] = const0_rtx;
9298 operands[2] = force_reg (mode, operands[2]);
9299 if (operands[3] != const0_rtx)
9300 operands[3] = force_reg (mode, operands[3]);
9306 swap = invert = !FLOAT_MODE_P (mode);
9311 swap = FLOAT_MODE_P (mode), invert = !swap;
9316 swap = true, invert = false;
9323 swap = invert = false;
9327 swap = invert = true;
9336 rtx tem = operands[2];
9337 operands[2] = operands[3];
9339 code = swap_condition (code);
9344 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9345 code = reverse_condition (code);
9346 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9347 emit_insn (gen_cstore4_media (tem, operands[1],
9348 operands[2], operands[3]));
9351 operands[3] = const0_rtx;
9354 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9357 (define_expand "cstoresi4"
9358 [(set (match_operand:SI 0 "register_operand" "=r")
9359 (match_operator:SI 1 "comparison_operator"
9360 [(match_operand:SI 2 "cmpsi_operand" "")
9361 (match_operand:SI 3 "arith_operand" "")]))]
9362 "TARGET_SH1 || TARGET_SHMEDIA"
9363 "if (TARGET_SHMEDIA)
9365 emit_insn (gen_cstore4_media (operands[0], operands[1],
9366 operands[2], operands[3]));
9370 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9371 && sh_expand_t_scc (operands))
9374 if (! currently_expanding_to_rtl)
9377 sh_emit_compare_and_set (operands, SImode);
9381 (define_expand "cstoredi4"
9382 [(set (match_operand:SI 0 "register_operand" "=r")
9383 (match_operator:SI 1 "comparison_operator"
9384 [(match_operand:DI 2 "arith_operand" "")
9385 (match_operand:DI 3 "arith_operand" "")]))]
9386 "TARGET_SH2 || TARGET_SHMEDIA"
9387 "if (TARGET_SHMEDIA)
9389 emit_insn (gen_cstore4_media (operands[0], operands[1],
9390 operands[2], operands[3]));
9394 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9395 && sh_expand_t_scc (operands))
9398 if (! currently_expanding_to_rtl)
9401 sh_emit_compare_and_set (operands, DImode);
9407 ;; sne moves the complement of the T reg to DEST like this:
9411 ;; This is better than xoring compare result with 1 because it does
9412 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9415 (define_expand "movnegt"
9416 [(set (match_dup 1) (const_int -1))
9417 (parallel [(set (match_operand:SI 0 "" "")
9418 (neg:SI (plus:SI (reg:SI T_REG)
9421 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9426 operands[1] = gen_reg_rtx (SImode);
9430 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9431 ;; This prevents a regression that occurred when we switched from xor to
9435 [(set (match_operand:SI 0 "arith_reg_dest" "")
9436 (plus:SI (reg:SI T_REG)
9439 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9440 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9443 (define_expand "cstoresf4"
9444 [(set (match_operand:SI 0 "register_operand" "=r")
9445 (match_operator:SI 1 "sh_float_comparison_operator"
9446 [(match_operand:SF 2 "arith_operand" "")
9447 (match_operand:SF 3 "arith_operand" "")]))]
9448 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9449 "if (TARGET_SHMEDIA)
9451 emit_insn (gen_cstore4_media (operands[0], operands[1],
9452 operands[2], operands[3]));
9456 if (! currently_expanding_to_rtl)
9459 sh_emit_compare_and_set (operands, SFmode);
9463 (define_expand "cstoredf4"
9464 [(set (match_operand:SI 0 "register_operand" "=r")
9465 (match_operator:SI 1 "sh_float_comparison_operator"
9466 [(match_operand:DF 2 "arith_operand" "")
9467 (match_operand:DF 3 "arith_operand" "")]))]
9468 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9469 "if (TARGET_SHMEDIA)
9471 emit_insn (gen_cstore4_media (operands[0], operands[1],
9472 operands[2], operands[3]));
9476 if (! currently_expanding_to_rtl)
9479 sh_emit_compare_and_set (operands, DFmode);
9484 ;; -------------------------------------------------------------------------
9485 ;; Instructions to cope with inline literal tables
9486 ;; -------------------------------------------------------------------------
9488 ; 2 byte integer in line
9490 (define_insn "consttable_2"
9491 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9492 (match_operand 1 "" "")]
9497 if (operands[1] != const0_rtx)
9498 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9501 [(set_attr "length" "2")
9502 (set_attr "in_delay_slot" "no")])
9504 ; 4 byte integer in line
9506 (define_insn "consttable_4"
9507 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9508 (match_operand 1 "" "")]
9513 if (operands[1] != const0_rtx)
9515 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9516 mark_symbol_refs_as_used (operands[0]);
9520 [(set_attr "length" "4")
9521 (set_attr "in_delay_slot" "no")])
9523 ; 8 byte integer in line
9525 (define_insn "consttable_8"
9526 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9527 (match_operand 1 "" "")]
9532 if (operands[1] != const0_rtx)
9533 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9536 [(set_attr "length" "8")
9537 (set_attr "in_delay_slot" "no")])
9539 ; 4 byte floating point
9541 (define_insn "consttable_sf"
9542 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9543 (match_operand 1 "" "")]
9548 if (operands[1] != const0_rtx)
9551 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9552 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9556 [(set_attr "length" "4")
9557 (set_attr "in_delay_slot" "no")])
9559 ; 8 byte floating point
9561 (define_insn "consttable_df"
9562 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9563 (match_operand 1 "" "")]
9568 if (operands[1] != const0_rtx)
9571 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9572 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9576 [(set_attr "length" "8")
9577 (set_attr "in_delay_slot" "no")])
9579 ;; Alignment is needed for some constant tables; it may also be added for
9580 ;; Instructions at the start of loops, or after unconditional branches.
9581 ;; ??? We would get more accurate lengths if we did instruction
9582 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9583 ;; here is too conservative.
9585 ; align to a two byte boundary
9587 (define_expand "align_2"
9588 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9592 ; align to a four byte boundary
9593 ;; align_4 and align_log are instructions for the starts of loops, or
9594 ;; after unconditional branches, which may take up extra room.
9596 (define_expand "align_4"
9597 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9601 ; align to a cache line boundary
9603 (define_insn "align_log"
9604 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9607 [(set_attr "length" "0")
9608 (set_attr "in_delay_slot" "no")])
9610 ; emitted at the end of the literal table, used to emit the
9611 ; 32bit branch labels if needed.
9613 (define_insn "consttable_end"
9614 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9616 "* return output_jump_label_table ();"
9617 [(set_attr "in_delay_slot" "no")])
9619 ; emitted at the end of the window in the literal table.
9621 (define_insn "consttable_window_end"
9622 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9625 [(set_attr "length" "0")
9626 (set_attr "in_delay_slot" "no")])
9628 ;; -------------------------------------------------------------------------
9630 ;; -------------------------------------------------------------------------
9632 ;; String/block move insn.
9634 (define_expand "movmemsi"
9635 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9636 (mem:BLK (match_operand:BLK 1 "" "")))
9637 (use (match_operand:SI 2 "nonmemory_operand" ""))
9638 (use (match_operand:SI 3 "immediate_operand" ""))
9639 (clobber (reg:SI PR_REG))
9640 (clobber (reg:SI R4_REG))
9641 (clobber (reg:SI R5_REG))
9642 (clobber (reg:SI R0_REG))])]
9643 "TARGET_SH1 && ! TARGET_SH5"
9646 if(expand_block_move (operands))
9651 (define_insn "block_move_real"
9652 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9653 (mem:BLK (reg:SI R5_REG)))
9654 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9655 (clobber (reg:SI PR_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_lump_real"
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 (use (reg:SI R6_REG))
9667 (clobber (reg:SI PR_REG))
9668 (clobber (reg:SI T_REG))
9669 (clobber (reg:SI R4_REG))
9670 (clobber (reg:SI R5_REG))
9671 (clobber (reg:SI R6_REG))
9672 (clobber (reg:SI R0_REG))])]
9673 "TARGET_SH1 && ! TARGET_HARD_SH4"
9675 [(set_attr "type" "sfunc")
9676 (set_attr "needs_delay_slot" "yes")])
9678 (define_insn "block_move_real_i4"
9679 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9680 (mem:BLK (reg:SI R5_REG)))
9681 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9682 (clobber (reg:SI PR_REG))
9683 (clobber (reg:SI R0_REG))
9684 (clobber (reg:SI R1_REG))
9685 (clobber (reg:SI R2_REG))])]
9688 [(set_attr "type" "sfunc")
9689 (set_attr "needs_delay_slot" "yes")])
9691 (define_insn "block_lump_real_i4"
9692 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9693 (mem:BLK (reg:SI R5_REG)))
9694 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9695 (use (reg:SI R6_REG))
9696 (clobber (reg:SI PR_REG))
9697 (clobber (reg:SI T_REG))
9698 (clobber (reg:SI R4_REG))
9699 (clobber (reg:SI R5_REG))
9700 (clobber (reg:SI R6_REG))
9701 (clobber (reg:SI R0_REG))
9702 (clobber (reg:SI R1_REG))
9703 (clobber (reg:SI R2_REG))
9704 (clobber (reg:SI R3_REG))])]
9707 [(set_attr "type" "sfunc")
9708 (set_attr "needs_delay_slot" "yes")])
9710 ;; -------------------------------------------------------------------------
9711 ;; Floating point instructions.
9712 ;; -------------------------------------------------------------------------
9714 ;; ??? All patterns should have a type attribute.
9716 (define_expand "movpsi"
9717 [(set (match_operand:PSI 0 "register_operand" "")
9718 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9719 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9722 ;; The c / m alternative is a fake to guide reload to load directly into
9723 ;; fpscr, since reload doesn't know how to use post-increment.
9724 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9725 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9726 ;; predicate after reload.
9727 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9728 ;; like a mac -> gpr move.
9729 (define_insn "fpu_switch"
9730 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9731 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9733 && (! reload_completed
9734 || true_regnum (operands[0]) != FPSCR_REG
9735 || !MEM_P (operands[1])
9736 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9738 ! precision stays the same
9747 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9748 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9751 [(set (reg:PSI FPSCR_REG)
9752 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9753 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9756 rtx fpscr, mem, new_insn;
9758 fpscr = SET_DEST (PATTERN (curr_insn));
9759 mem = SET_SRC (PATTERN (curr_insn));
9760 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9762 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9763 add_reg_note (new_insn, REG_INC, operands[0]);
9768 [(set (reg:PSI FPSCR_REG)
9769 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9770 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9771 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9774 rtx fpscr, mem, new_insn;
9776 fpscr = SET_DEST (PATTERN (curr_insn));
9777 mem = SET_SRC (PATTERN (curr_insn));
9778 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9780 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9781 add_reg_note (new_insn, REG_INC, operands[0]);
9783 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9784 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9788 ;; ??? This uses the fp unit, but has no type indicating that.
9789 ;; If we did that, this would either give a bogus latency or introduce
9790 ;; a bogus FIFO constraint.
9791 ;; Since this insn is currently only used for prologues/epilogues,
9792 ;; it is probably best to claim no function unit, which matches the
9794 (define_insn "toggle_sz"
9795 [(set (reg:PSI FPSCR_REG)
9796 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9797 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9799 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9801 ;; There's no way we can use it today, since optimize mode switching
9802 ;; doesn't enable us to know from which mode we're switching to the
9803 ;; mode it requests, to tell whether we can use a relative mode switch
9804 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9806 (define_insn "toggle_pr"
9807 [(set (reg:PSI FPSCR_REG)
9808 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9809 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9811 [(set_attr "type" "fpscr_toggle")])
9813 (define_expand "addsf3"
9814 [(set (match_operand:SF 0 "arith_reg_operand" "")
9815 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9816 (match_operand:SF 2 "arith_reg_operand" "")))]
9817 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9822 expand_sf_binop (&gen_addsf3_i, operands);
9827 (define_insn "*addsf3_media"
9828 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9829 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9830 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9831 "TARGET_SHMEDIA_FPU"
9833 [(set_attr "type" "fparith_media")])
9835 (define_insn_and_split "unary_sf_op"
9836 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9841 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9842 (match_operator:SF 2 "unary_float_operator"
9843 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9844 (parallel [(match_operand 4
9845 "const_int_operand" "n")]))]))
9846 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9847 "TARGET_SHMEDIA_FPU"
9849 "TARGET_SHMEDIA_FPU && reload_completed"
9850 [(set (match_dup 5) (match_dup 6))]
9853 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9854 rtx op1 = gen_rtx_REG (SFmode,
9855 (true_regnum (operands[1])
9856 + (INTVAL (operands[4]) ^ endian)));
9858 operands[7] = gen_rtx_REG (SFmode,
9859 (true_regnum (operands[0])
9860 + (INTVAL (operands[3]) ^ endian)));
9861 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9863 [(set_attr "type" "fparith_media")])
9865 (define_insn_and_split "binary_sf_op0"
9866 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9868 (match_operator:SF 3 "binary_float_operator"
9869 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9870 (parallel [(const_int 0)]))
9871 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9872 (parallel [(const_int 0)]))])
9875 (parallel [(const_int 1)]))))]
9876 "TARGET_SHMEDIA_FPU"
9878 "&& reload_completed"
9879 [(set (match_dup 4) (match_dup 5))]
9882 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9883 rtx op1 = gen_rtx_REG (SFmode,
9884 true_regnum (operands[1]) + endian);
9885 rtx op2 = gen_rtx_REG (SFmode,
9886 true_regnum (operands[2]) + endian);
9888 operands[4] = gen_rtx_REG (SFmode,
9889 true_regnum (operands[0]) + endian);
9890 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9892 [(set_attr "type" "fparith_media")])
9894 (define_insn_and_split "binary_sf_op1"
9895 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9899 (parallel [(const_int 0)]))
9900 (match_operator:SF 3 "binary_float_operator"
9901 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9902 (parallel [(const_int 1)]))
9903 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9904 (parallel [(const_int 1)]))])))]
9905 "TARGET_SHMEDIA_FPU"
9907 "&& reload_completed"
9908 [(set (match_dup 4) (match_dup 5))]
9911 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9912 rtx op1 = gen_rtx_REG (SFmode,
9913 true_regnum (operands[1]) + (1 ^ endian));
9914 rtx op2 = gen_rtx_REG (SFmode,
9915 true_regnum (operands[2]) + (1 ^ endian));
9917 operands[4] = gen_rtx_REG (SFmode,
9918 true_regnum (operands[0]) + (1 ^ endian));
9919 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9921 [(set_attr "type" "fparith_media")])
9923 (define_insn "addsf3_i"
9924 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9925 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9926 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9927 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9930 [(set_attr "type" "fp")
9931 (set_attr "fp_mode" "single")])
9933 (define_expand "subsf3"
9934 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9935 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9936 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9937 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9942 expand_sf_binop (&gen_subsf3_i, operands);
9947 (define_insn "*subsf3_media"
9948 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9949 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9950 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9951 "TARGET_SHMEDIA_FPU"
9953 [(set_attr "type" "fparith_media")])
9955 (define_insn "subsf3_i"
9956 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9957 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9958 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9959 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9962 [(set_attr "type" "fp")
9963 (set_attr "fp_mode" "single")])
9965 (define_expand "mulsf3"
9966 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9967 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9968 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9969 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9972 (define_insn "*mulsf3_media"
9973 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9974 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9975 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9976 "TARGET_SHMEDIA_FPU"
9978 [(set_attr "type" "fparith_media")])
9980 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9981 ;; register in feeding fp instructions. Thus, in order to generate fmac,
9982 ;; we start out with a mulsf pattern that does not depend on fpscr.
9983 ;; This is split after combine to introduce the dependency, in order to
9984 ;; get mode switching and scheduling right.
9985 (define_insn_and_split "mulsf3_ie"
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")))]
9991 "TARGET_SH4 || TARGET_SH2A_SINGLE"
9995 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9999 [(set_attr "type" "fp")])
10001 (define_insn "mulsf3_i4"
10002 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10003 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10004 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10005 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10008 [(set_attr "type" "fp")
10009 (set_attr "fp_mode" "single")])
10011 (define_insn "mac_media"
10012 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10013 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10014 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10015 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10016 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10017 "fmac.s %1, %2, %0"
10018 [(set_attr "type" "fparith_media")])
10020 (define_insn "*macsf3"
10021 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10022 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10023 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10024 (match_operand:SF 3 "arith_reg_operand" "0")))
10025 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10026 "TARGET_SH2E && TARGET_FMAC"
10028 [(set_attr "type" "fp")
10029 (set_attr "fp_mode" "single")])
10031 (define_expand "divsf3"
10032 [(set (match_operand:SF 0 "arith_reg_operand" "")
10033 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10034 (match_operand:SF 2 "arith_reg_operand" "")))]
10035 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10040 expand_sf_binop (&gen_divsf3_i, operands);
10045 (define_insn "*divsf3_media"
10046 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10047 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10048 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10049 "TARGET_SHMEDIA_FPU"
10050 "fdiv.s %1, %2, %0"
10051 [(set_attr "type" "fdiv_media")])
10053 (define_insn "divsf3_i"
10054 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10055 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10056 (match_operand:SF 2 "arith_reg_operand" "f")))
10057 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10060 [(set_attr "type" "fdiv")
10061 (set_attr "fp_mode" "single")])
10063 (define_insn "floatdisf2"
10064 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10065 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10066 "TARGET_SHMEDIA_FPU"
10068 [(set_attr "type" "fpconv_media")])
10070 (define_expand "floatsisf2"
10071 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10072 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10073 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10076 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10078 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10083 (define_insn "*floatsisf2_media"
10084 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10085 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10086 "TARGET_SHMEDIA_FPU"
10088 [(set_attr "type" "fpconv_media")])
10090 (define_insn "floatsisf2_i4"
10091 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10092 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10093 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10094 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10096 [(set_attr "type" "fp")
10097 (set_attr "fp_mode" "single")])
10099 (define_insn "*floatsisf2_ie"
10100 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10101 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10102 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10104 [(set_attr "type" "fp")])
10106 (define_insn "fix_truncsfdi2"
10107 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10108 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10109 "TARGET_SHMEDIA_FPU"
10111 [(set_attr "type" "fpconv_media")])
10113 (define_expand "fix_truncsfsi2"
10114 [(set (match_operand:SI 0 "fpul_operand" "=y")
10115 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10116 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10119 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10121 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10126 (define_insn "*fix_truncsfsi2_media"
10127 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10128 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10129 "TARGET_SHMEDIA_FPU"
10131 [(set_attr "type" "fpconv_media")])
10133 (define_insn "fix_truncsfsi2_i4"
10134 [(set (match_operand:SI 0 "fpul_operand" "=y")
10135 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10136 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10137 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10139 [(set_attr "type" "ftrc_s")
10140 (set_attr "fp_mode" "single")])
10142 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10143 ;; fix_truncsfsi2_i4.
10144 ;; (define_insn "fix_truncsfsi2_i4_2"
10145 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10146 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10147 ;; (use (reg:PSI FPSCR_REG))
10148 ;; (clobber (reg:SI FPUL_REG))]
10151 ;; [(set_attr "length" "4")
10152 ;; (set_attr "fp_mode" "single")])
10155 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10156 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10157 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10158 ;; (clobber (reg:SI FPUL_REG))]
10160 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10161 ;; (use (match_dup 2))])
10162 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10164 (define_insn "*fixsfsi"
10165 [(set (match_operand:SI 0 "fpul_operand" "=y")
10166 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10167 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10169 [(set_attr "type" "fp")])
10171 (define_insn "cmpgtsf_t"
10172 [(set (reg:SI T_REG)
10173 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10174 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10175 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10177 [(set_attr "type" "fp_cmp")
10178 (set_attr "fp_mode" "single")])
10180 (define_insn "cmpeqsf_t"
10181 [(set (reg:SI T_REG)
10182 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10183 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10184 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10186 [(set_attr "type" "fp_cmp")
10187 (set_attr "fp_mode" "single")])
10189 (define_insn "ieee_ccmpeqsf_t"
10190 [(set (reg:SI T_REG)
10191 (ior:SI (reg:SI T_REG)
10192 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10193 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10194 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10195 "* return output_ieee_ccmpeq (insn, operands);"
10196 [(set_attr "length" "4")])
10199 (define_insn "cmpgtsf_t_i4"
10200 [(set (reg:SI T_REG)
10201 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10202 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10203 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10204 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10206 [(set_attr "type" "fp_cmp")
10207 (set_attr "fp_mode" "single")])
10209 (define_insn "cmpeqsf_t_i4"
10210 [(set (reg:SI T_REG)
10211 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10212 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10213 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10214 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10216 [(set_attr "type" "fp_cmp")
10217 (set_attr "fp_mode" "single")])
10219 (define_insn "*ieee_ccmpeqsf_t_4"
10220 [(set (reg:SI T_REG)
10221 (ior:SI (reg:SI T_REG)
10222 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10223 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10224 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10225 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10226 "* return output_ieee_ccmpeq (insn, operands);"
10227 [(set_attr "length" "4")
10228 (set_attr "fp_mode" "single")])
10230 (define_insn "cmpeqsf_media"
10231 [(set (match_operand:SI 0 "register_operand" "=r")
10232 (eq: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 "fcmpeq.s %1, %2, %0"
10236 [(set_attr "type" "fcmp_media")])
10238 (define_insn "cmpgtsf_media"
10239 [(set (match_operand:SI 0 "register_operand" "=r")
10240 (gt: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 "fcmpgt.s %1, %2, %0"
10244 [(set_attr "type" "fcmp_media")])
10246 (define_insn "cmpgesf_media"
10247 [(set (match_operand:SI 0 "register_operand" "=r")
10248 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10249 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10250 "TARGET_SHMEDIA_FPU"
10251 "fcmpge.s %1, %2, %0"
10252 [(set_attr "type" "fcmp_media")])
10254 (define_insn "cmpunsf_media"
10255 [(set (match_operand:SI 0 "register_operand" "=r")
10256 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10257 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10258 "TARGET_SHMEDIA_FPU"
10259 "fcmpun.s %1, %2, %0"
10260 [(set_attr "type" "fcmp_media")])
10262 (define_expand "cbranchsf4"
10264 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10265 [(match_operand:SF 1 "arith_operand" "")
10266 (match_operand:SF 2 "arith_operand" "")])
10267 (match_operand 3 "" "")
10269 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10272 if (TARGET_SHMEDIA)
10273 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10276 sh_emit_compare_and_branch (operands, SFmode);
10280 (define_expand "negsf2"
10281 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10282 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10283 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10288 expand_sf_unop (&gen_negsf2_i, operands);
10293 (define_insn "*negsf2_media"
10294 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10295 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10296 "TARGET_SHMEDIA_FPU"
10298 [(set_attr "type" "fmove_media")])
10300 (define_insn "negsf2_i"
10301 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10302 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10303 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10306 [(set_attr "type" "fmove")
10307 (set_attr "fp_mode" "single")])
10309 (define_expand "sqrtsf2"
10310 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10311 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10312 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10317 expand_sf_unop (&gen_sqrtsf2_i, operands);
10322 (define_insn "*sqrtsf2_media"
10323 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10324 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10325 "TARGET_SHMEDIA_FPU"
10327 [(set_attr "type" "fdiv_media")])
10329 (define_insn "sqrtsf2_i"
10330 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10331 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10332 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10335 [(set_attr "type" "fdiv")
10336 (set_attr "fp_mode" "single")])
10338 (define_insn "rsqrtsf2"
10339 [(set (match_operand:SF 0 "register_operand" "=f")
10340 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10341 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10342 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10343 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10344 && operands[1] == CONST1_RTX (SFmode)"
10346 [(set_attr "type" "fsrra")
10347 (set_attr "fp_mode" "single")])
10349 (define_insn "fsca"
10350 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10352 (unspec:SF [(mult:SF
10353 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10354 (match_operand:SF 2 "immediate_operand" "i"))
10356 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10358 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10359 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10360 && operands[2] == sh_fsca_int2sf ()"
10362 [(set_attr "type" "fsca")
10363 (set_attr "fp_mode" "single")])
10365 (define_expand "sinsf2"
10366 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10367 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10369 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10372 rtx scaled = gen_reg_rtx (SFmode);
10373 rtx truncated = gen_reg_rtx (SImode);
10374 rtx fsca = gen_reg_rtx (V2SFmode);
10375 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10377 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10378 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10379 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10380 get_fpscr_rtx ()));
10381 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10385 (define_expand "cossf2"
10386 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10387 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10389 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10392 rtx scaled = gen_reg_rtx (SFmode);
10393 rtx truncated = gen_reg_rtx (SImode);
10394 rtx fsca = gen_reg_rtx (V2SFmode);
10395 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10397 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10398 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10399 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10400 get_fpscr_rtx ()));
10401 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10405 (define_expand "sindf2"
10406 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10407 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10409 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10412 rtx scaled = gen_reg_rtx (DFmode);
10413 rtx truncated = gen_reg_rtx (SImode);
10414 rtx fsca = gen_reg_rtx (V2SFmode);
10415 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10416 rtx sfresult = gen_reg_rtx (SFmode);
10418 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10419 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10420 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10421 get_fpscr_rtx ()));
10422 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10423 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10427 (define_expand "cosdf2"
10428 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10429 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10431 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10434 rtx scaled = gen_reg_rtx (DFmode);
10435 rtx truncated = gen_reg_rtx (SImode);
10436 rtx fsca = gen_reg_rtx (V2SFmode);
10437 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10438 rtx sfresult = gen_reg_rtx (SFmode);
10440 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10441 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10442 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10443 get_fpscr_rtx ()));
10444 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10445 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10449 (define_expand "abssf2"
10450 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10451 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10452 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10457 expand_sf_unop (&gen_abssf2_i, operands);
10462 (define_insn "*abssf2_media"
10463 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10464 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10465 "TARGET_SHMEDIA_FPU"
10467 [(set_attr "type" "fmove_media")])
10469 (define_insn "abssf2_i"
10470 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10471 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10472 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10475 [(set_attr "type" "fmove")
10476 (set_attr "fp_mode" "single")])
10478 (define_expand "adddf3"
10479 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10480 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10481 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10482 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10485 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10487 expand_df_binop (&gen_adddf3_i, operands);
10492 (define_insn "*adddf3_media"
10493 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10494 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10495 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10496 "TARGET_SHMEDIA_FPU"
10497 "fadd.d %1, %2, %0"
10498 [(set_attr "type" "dfparith_media")])
10500 (define_insn "adddf3_i"
10501 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10502 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10503 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10504 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10505 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10507 [(set_attr "type" "dfp_arith")
10508 (set_attr "fp_mode" "double")])
10510 (define_expand "subdf3"
10511 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10512 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10513 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10514 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10517 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10519 expand_df_binop (&gen_subdf3_i, operands);
10524 (define_insn "*subdf3_media"
10525 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10526 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10527 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10528 "TARGET_SHMEDIA_FPU"
10529 "fsub.d %1, %2, %0"
10530 [(set_attr "type" "dfparith_media")])
10532 (define_insn "subdf3_i"
10533 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10534 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10535 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10536 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10537 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10539 [(set_attr "type" "dfp_arith")
10540 (set_attr "fp_mode" "double")])
10542 (define_expand "muldf3"
10543 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10544 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10545 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10546 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10549 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10551 expand_df_binop (&gen_muldf3_i, operands);
10556 (define_insn "*muldf3_media"
10557 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10558 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10559 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10560 "TARGET_SHMEDIA_FPU"
10561 "fmul.d %1, %2, %0"
10562 [(set_attr "type" "dfmul_media")])
10564 (define_insn "muldf3_i"
10565 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10566 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10567 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10568 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10569 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10571 [(set_attr "type" "dfp_mul")
10572 (set_attr "fp_mode" "double")])
10574 (define_expand "divdf3"
10575 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10576 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10577 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10578 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10581 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10583 expand_df_binop (&gen_divdf3_i, operands);
10588 (define_insn "*divdf3_media"
10589 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10590 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10591 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10592 "TARGET_SHMEDIA_FPU"
10593 "fdiv.d %1, %2, %0"
10594 [(set_attr "type" "dfdiv_media")])
10596 (define_insn "divdf3_i"
10597 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10598 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10599 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10600 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10601 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10603 [(set_attr "type" "dfdiv")
10604 (set_attr "fp_mode" "double")])
10606 (define_insn "floatdidf2"
10607 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10608 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10609 "TARGET_SHMEDIA_FPU"
10611 [(set_attr "type" "dfpconv_media")])
10613 (define_expand "floatsidf2"
10614 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10615 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10616 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10619 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10621 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10622 get_fpscr_rtx ()));
10627 (define_insn "*floatsidf2_media"
10628 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10629 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10630 "TARGET_SHMEDIA_FPU"
10632 [(set_attr "type" "dfpconv_media")])
10634 (define_insn "floatsidf2_i"
10635 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10636 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10637 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10638 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10640 [(set_attr "type" "dfp_conv")
10641 (set_attr "fp_mode" "double")])
10643 (define_insn "fix_truncdfdi2"
10644 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10645 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10646 "TARGET_SHMEDIA_FPU"
10648 [(set_attr "type" "dfpconv_media")])
10650 (define_expand "fix_truncdfsi2"
10651 [(set (match_operand:SI 0 "fpul_operand" "")
10652 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10653 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10656 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10658 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10659 get_fpscr_rtx ()));
10664 (define_insn "*fix_truncdfsi2_media"
10665 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10666 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10667 "TARGET_SHMEDIA_FPU"
10669 [(set_attr "type" "dfpconv_media")])
10671 (define_insn "fix_truncdfsi2_i"
10672 [(set (match_operand:SI 0 "fpul_operand" "=y")
10673 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10674 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10675 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10677 [(set_attr "type" "dfp_conv")
10678 (set_attr "dfp_comp" "no")
10679 (set_attr "fp_mode" "double")])
10681 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10682 ;; fix_truncdfsi2_i.
10683 ;; (define_insn "fix_truncdfsi2_i4"
10684 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10685 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10686 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10687 ;; (clobber (reg:SI FPUL_REG))]
10690 ;; [(set_attr "length" "4")
10691 ;; (set_attr "fp_mode" "double")])
10694 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10695 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10696 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10697 ;; (clobber (reg:SI FPUL_REG))]
10699 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10700 ;; (use (match_dup 2))])
10701 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10703 (define_insn "cmpgtdf_t"
10704 [(set (reg:SI T_REG)
10705 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10706 (match_operand:DF 1 "arith_reg_operand" "f")))
10707 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10708 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10710 [(set_attr "type" "dfp_cmp")
10711 (set_attr "fp_mode" "double")])
10713 (define_insn "cmpeqdf_t"
10714 [(set (reg:SI T_REG)
10715 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10716 (match_operand:DF 1 "arith_reg_operand" "f")))
10717 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10718 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10720 [(set_attr "type" "dfp_cmp")
10721 (set_attr "fp_mode" "double")])
10723 (define_insn "*ieee_ccmpeqdf_t"
10724 [(set (reg:SI T_REG)
10725 (ior:SI (reg:SI T_REG)
10726 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10727 (match_operand:DF 1 "arith_reg_operand" "f"))))
10728 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10729 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10730 "* return output_ieee_ccmpeq (insn, operands);"
10731 [(set_attr "length" "4")
10732 (set_attr "fp_mode" "double")])
10734 (define_insn "cmpeqdf_media"
10735 [(set (match_operand:SI 0 "register_operand" "=r")
10736 (eq: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 "fcmpeq.d %1,%2,%0"
10740 [(set_attr "type" "fcmp_media")])
10742 (define_insn "cmpgtdf_media"
10743 [(set (match_operand:SI 0 "register_operand" "=r")
10744 (gt: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 "fcmpgt.d %1,%2,%0"
10748 [(set_attr "type" "fcmp_media")])
10750 (define_insn "cmpgedf_media"
10751 [(set (match_operand:SI 0 "register_operand" "=r")
10752 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10753 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10754 "TARGET_SHMEDIA_FPU"
10755 "fcmpge.d %1,%2,%0"
10756 [(set_attr "type" "fcmp_media")])
10758 (define_insn "cmpundf_media"
10759 [(set (match_operand:SI 0 "register_operand" "=r")
10760 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10761 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10762 "TARGET_SHMEDIA_FPU"
10763 "fcmpun.d %1,%2,%0"
10764 [(set_attr "type" "fcmp_media")])
10766 (define_expand "cbranchdf4"
10768 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10769 [(match_operand:DF 1 "arith_operand" "")
10770 (match_operand:DF 2 "arith_operand" "")])
10771 (match_operand 3 "" "")
10773 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10776 if (TARGET_SHMEDIA)
10777 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10780 sh_emit_compare_and_branch (operands, DFmode);
10785 (define_expand "negdf2"
10786 [(set (match_operand:DF 0 "arith_reg_operand" "")
10787 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10788 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10791 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10793 expand_df_unop (&gen_negdf2_i, operands);
10798 (define_insn "*negdf2_media"
10799 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10800 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10801 "TARGET_SHMEDIA_FPU"
10803 [(set_attr "type" "fmove_media")])
10805 (define_insn "negdf2_i"
10806 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10807 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10808 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10809 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10811 [(set_attr "type" "fmove")
10812 (set_attr "fp_mode" "double")])
10814 (define_expand "sqrtdf2"
10815 [(set (match_operand:DF 0 "arith_reg_operand" "")
10816 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10817 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10820 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10822 expand_df_unop (&gen_sqrtdf2_i, operands);
10827 (define_insn "*sqrtdf2_media"
10828 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10829 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10830 "TARGET_SHMEDIA_FPU"
10832 [(set_attr "type" "dfdiv_media")])
10834 (define_insn "sqrtdf2_i"
10835 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10836 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10837 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10838 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10840 [(set_attr "type" "dfdiv")
10841 (set_attr "fp_mode" "double")])
10843 (define_expand "absdf2"
10844 [(set (match_operand:DF 0 "arith_reg_operand" "")
10845 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10846 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10849 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10851 expand_df_unop (&gen_absdf2_i, operands);
10856 (define_insn "*absdf2_media"
10857 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10858 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10859 "TARGET_SHMEDIA_FPU"
10861 [(set_attr "type" "fmove_media")])
10863 (define_insn "absdf2_i"
10864 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10865 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10866 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10867 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10869 [(set_attr "type" "fmove")
10870 (set_attr "fp_mode" "double")])
10872 (define_expand "extendsfdf2"
10873 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10874 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10875 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10878 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10880 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10881 get_fpscr_rtx ()));
10886 (define_insn "*extendsfdf2_media"
10887 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10888 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10889 "TARGET_SHMEDIA_FPU"
10891 [(set_attr "type" "dfpconv_media")])
10893 (define_insn "extendsfdf2_i4"
10894 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10895 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10896 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10897 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10899 [(set_attr "type" "fp")
10900 (set_attr "fp_mode" "double")])
10902 (define_expand "truncdfsf2"
10903 [(set (match_operand:SF 0 "fpul_operand" "")
10904 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10905 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10908 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10910 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10911 get_fpscr_rtx ()));
10916 (define_insn "*truncdfsf2_media"
10917 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10918 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10919 "TARGET_SHMEDIA_FPU"
10921 [(set_attr "type" "dfpconv_media")])
10923 (define_insn "truncdfsf2_i4"
10924 [(set (match_operand:SF 0 "fpul_operand" "=y")
10925 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10926 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10927 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10929 [(set_attr "type" "fp")
10930 (set_attr "fp_mode" "double")])
10932 ;; Bit field extract patterns. These give better code for packed bitfields,
10933 ;; because they allow auto-increment addresses to be generated.
10935 (define_expand "insv"
10936 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10937 (match_operand:SI 1 "immediate_operand" "")
10938 (match_operand:SI 2 "immediate_operand" ""))
10939 (match_operand:SI 3 "general_operand" ""))]
10940 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10943 rtx addr_target, orig_address, shift_reg, qi_val;
10944 HOST_WIDE_INT bitsize, size, v = 0;
10945 rtx x = operands[3];
10947 if (TARGET_SH2A && TARGET_BITOPS
10948 && (satisfies_constraint_Sbw (operands[0])
10949 || satisfies_constraint_Sbv (operands[0]))
10950 && satisfies_constraint_M (operands[1])
10951 && satisfies_constraint_K03 (operands[2]))
10953 if (satisfies_constraint_N (operands[3]))
10955 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10958 else if (satisfies_constraint_M (operands[3]))
10960 emit_insn (gen_bset_m2a (operands[0], operands[2]));
10963 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10964 && satisfies_constraint_M (operands[1]))
10966 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10969 else if (REG_P (operands[3])
10970 && satisfies_constraint_M (operands[1]))
10972 emit_insn (gen_bld_reg (operands[3], const0_rtx));
10973 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10977 /* ??? expmed doesn't care for non-register predicates. */
10978 if (! memory_operand (operands[0], VOIDmode)
10979 || ! immediate_operand (operands[1], VOIDmode)
10980 || ! immediate_operand (operands[2], VOIDmode)
10981 || ! general_operand (x, VOIDmode))
10983 /* If this isn't a 16 / 24 / 32 bit field, or if
10984 it doesn't start on a byte boundary, then fail. */
10985 bitsize = INTVAL (operands[1]);
10986 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10987 || (INTVAL (operands[2]) % 8) != 0)
10990 size = bitsize / 8;
10991 orig_address = XEXP (operands[0], 0);
10992 shift_reg = gen_reg_rtx (SImode);
10993 if (CONST_INT_P (x))
10996 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11000 emit_insn (gen_movsi (shift_reg, operands[3]));
11001 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11003 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11005 operands[0] = replace_equiv_address (operands[0], addr_target);
11006 emit_insn (gen_movqi (operands[0], qi_val));
11010 if (CONST_INT_P (x))
11012 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11015 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11016 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11018 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11019 emit_insn (gen_movqi (operands[0], qi_val));
11025 (define_insn "movua"
11026 [(set (match_operand:SI 0 "register_operand" "=z")
11027 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11031 [(set_attr "type" "movua")])
11033 ;; We shouldn't need this, but cse replaces increments with references
11034 ;; to other regs before flow has a chance to create post_inc
11035 ;; addressing modes, and only postreload's cse_move2add brings the
11036 ;; increments back to a usable form.
11038 [(set (match_operand:SI 0 "register_operand" "")
11039 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11040 (const_int 32) (const_int 0)))
11041 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11042 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11043 [(set (match_operand:SI 0 "register_operand" "")
11044 (sign_extract:SI (mem:SI (post_inc:SI
11045 (match_operand:SI 1 "register_operand" "")))
11046 (const_int 32) (const_int 0)))]
11049 (define_expand "extv"
11050 [(set (match_operand:SI 0 "register_operand" "")
11051 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11052 (match_operand 2 "const_int_operand" "")
11053 (match_operand 3 "const_int_operand" "")))]
11054 "TARGET_SH4A_ARCH || TARGET_SH2A"
11056 if (TARGET_SH2A && TARGET_BITOPS
11057 && (satisfies_constraint_Sbw (operands[1])
11058 || satisfies_constraint_Sbv (operands[1]))
11059 && satisfies_constraint_M (operands[2])
11060 && satisfies_constraint_K03 (operands[3]))
11062 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11063 if (REGNO (operands[0]) != T_REG)
11064 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11067 if (TARGET_SH4A_ARCH
11068 && INTVAL (operands[2]) == 32
11069 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11070 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11072 rtx src = adjust_address (operands[1], BLKmode, 0);
11073 set_mem_size (src, 4);
11074 emit_insn (gen_movua (operands[0], src));
11081 (define_expand "extzv"
11082 [(set (match_operand:SI 0 "register_operand" "")
11083 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11084 (match_operand 2 "const_int_operand" "")
11085 (match_operand 3 "const_int_operand" "")))]
11086 "TARGET_SH4A_ARCH || TARGET_SH2A"
11088 if (TARGET_SH2A && TARGET_BITOPS
11089 && (satisfies_constraint_Sbw (operands[1])
11090 || satisfies_constraint_Sbv (operands[1]))
11091 && satisfies_constraint_M (operands[2])
11092 && satisfies_constraint_K03 (operands[3]))
11094 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11095 if (REGNO (operands[0]) != T_REG)
11096 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11099 if (TARGET_SH4A_ARCH
11100 && INTVAL (operands[2]) == 32
11101 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11102 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11104 rtx src = adjust_address (operands[1], BLKmode, 0);
11105 set_mem_size (src, 4);
11106 emit_insn (gen_movua (operands[0], src));
11113 ;; SH2A instructions for bitwise operations.
11115 ;; Clear a bit in a memory location.
11116 (define_insn "bclr_m2a"
11117 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11119 (not:QI (ashift:QI (const_int 1)
11120 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11122 "TARGET_SH2A && TARGET_BITOPS"
11125 bclr.b\\t%1,@(0,%t0)"
11126 [(set_attr "length" "4,4")])
11128 (define_insn "bclrmem_m2a"
11129 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11130 (and:QI (match_dup 0)
11131 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11132 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11135 bclr.b\\t%W1,@(0,%t0)"
11136 [(set_attr "length" "4,4")])
11138 ;; Set a bit in a memory location.
11139 (define_insn "bset_m2a"
11140 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11142 (ashift:QI (const_int 1)
11143 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11145 "TARGET_SH2A && TARGET_BITOPS"
11148 bset.b\\t%1,@(0,%t0)"
11149 [(set_attr "length" "4,4")])
11151 (define_insn "bsetmem_m2a"
11152 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11153 (ior:QI (match_dup 0)
11154 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11155 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11158 bset.b\\t%V1,@(0,%t0)"
11159 [(set_attr "length" "4,4")])
11161 ;;; Transfer the contents of the T bit to a specified bit of memory.
11162 (define_insn "bst_m2a"
11163 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11164 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11166 (not:QI (ashift:QI (const_int 1)
11167 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11170 (ashift:QI (const_int 1) (match_dup 1))
11172 "TARGET_SH2A && TARGET_BITOPS"
11175 bst.b\\t%1,@(0,%t0)"
11176 [(set_attr "length" "4")])
11178 ;; Store a specified bit of memory in the T bit.
11179 (define_insn "bld_m2a"
11180 [(set (reg:SI T_REG)
11182 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11184 (match_operand 1 "const_int_operand" "K03,K03")))]
11185 "TARGET_SH2A && TARGET_BITOPS"
11188 bld.b\\t%1,@(0,%t0)"
11189 [(set_attr "length" "4,4")])
11191 ;; Store a specified bit of memory in the T bit.
11192 (define_insn "bldsign_m2a"
11193 [(set (reg:SI T_REG)
11195 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11197 (match_operand 1 "const_int_operand" "K03,K03")))]
11198 "TARGET_SH2A && TARGET_BITOPS"
11201 bld.b\\t%1,@(0,%t0)"
11202 [(set_attr "length" "4,4")])
11204 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11205 (define_insn "bld_reg"
11206 [(set (reg:SI T_REG)
11207 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11209 (match_operand 1 "const_int_operand" "K03")))]
11213 (define_insn "*bld_regqi"
11214 [(set (reg:SI T_REG)
11215 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11217 (match_operand 1 "const_int_operand" "K03")))]
11221 ;; Take logical and of a specified bit of memory with the T bit and
11222 ;; store its result in the T bit.
11223 (define_insn "band_m2a"
11224 [(set (reg:SI T_REG)
11225 (and:SI (reg:SI T_REG)
11227 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11229 (match_operand 1 "const_int_operand" "K03,K03"))))]
11230 "TARGET_SH2A && TARGET_BITOPS"
11233 band.b\\t%1,@(0,%t0)"
11234 [(set_attr "length" "4,4")])
11236 (define_insn "bandreg_m2a"
11237 [(set (match_operand:SI 0 "register_operand" "=r,r")
11238 (and:SI (zero_extract:SI
11239 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11241 (match_operand 2 "const_int_operand" "K03,K03"))
11242 (match_operand:SI 3 "register_operand" "r,r")))]
11243 "TARGET_SH2A && TARGET_BITOPS"
11245 band.b\\t%2,%1\;movt\\t%0
11246 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11247 [(set_attr "length" "6,6")])
11249 ;; Take logical or of a specified bit of memory with the T bit and
11250 ;; store its result in the T bit.
11251 (define_insn "bor_m2a"
11252 [(set (reg:SI T_REG)
11253 (ior:SI (reg:SI T_REG)
11255 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11257 (match_operand 1 "const_int_operand" "K03,K03"))))]
11258 "TARGET_SH2A && TARGET_BITOPS"
11261 bor.b\\t%1,@(0,%t0)"
11262 [(set_attr "length" "4,4")])
11264 (define_insn "borreg_m2a"
11265 [(set (match_operand:SI 0 "register_operand" "=r,r")
11266 (ior:SI (zero_extract:SI
11267 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11269 (match_operand 2 "const_int_operand" "K03,K03"))
11270 (match_operand:SI 3 "register_operand" "=r,r")))]
11271 "TARGET_SH2A && TARGET_BITOPS"
11273 bor.b\\t%2,%1\;movt\\t%0
11274 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11275 [(set_attr "length" "6,6")])
11277 ;; Take exclusive or of a specified bit of memory with the T bit and
11278 ;; store its result in the T bit.
11279 (define_insn "bxor_m2a"
11280 [(set (reg:SI T_REG)
11281 (xor:SI (reg:SI T_REG)
11283 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11285 (match_operand 1 "const_int_operand" "K03,K03"))))]
11286 "TARGET_SH2A && TARGET_BITOPS"
11289 bxor.b\\t%1,@(0,%t0)"
11290 [(set_attr "length" "4,4")])
11292 (define_insn "bxorreg_m2a"
11293 [(set (match_operand:SI 0 "register_operand" "=r,r")
11294 (xor:SI (zero_extract:SI
11295 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11297 (match_operand 2 "const_int_operand" "K03,K03"))
11298 (match_operand:SI 3 "register_operand" "=r,r")))]
11299 "TARGET_SH2A && TARGET_BITOPS"
11301 bxor.b\\t%2,%1\;movt\\t%0
11302 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11303 [(set_attr "length" "6,6")])
11306 ;; -------------------------------------------------------------------------
11308 ;; -------------------------------------------------------------------------
11309 ;; This matches cases where the bit in a memory location is set.
11311 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11312 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11314 (ior:SI (match_dup 0)
11315 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11317 (match_operand 3 "arith_reg_operand" "r,r"))]
11318 "TARGET_SH2A && TARGET_BITOPS
11319 && satisfies_constraint_Pso (operands[2])
11320 && REGNO (operands[0]) == REGNO (operands[3])"
11321 [(set (match_dup 1)
11322 (ior:QI (match_dup 1)
11326 ;; This matches cases where the bit in a memory location is cleared.
11328 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11329 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11331 (and:SI (match_dup 0)
11332 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11334 (match_operand 3 "arith_reg_operand" "r,r"))]
11335 "TARGET_SH2A && TARGET_BITOPS
11336 && satisfies_constraint_Psz (operands[2])
11337 && REGNO (operands[0]) == REGNO (operands[3])"
11338 [(set (match_dup 1)
11339 (and:QI (match_dup 1)
11343 ;; This matches cases where a stack pointer increment at the start of the
11344 ;; epilogue combines with a stack slot read loading the return value.
11347 [(set (match_operand:SI 0 "arith_reg_operand" "")
11348 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11349 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11350 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11353 ;; See the comment on the dt combiner pattern above.
11356 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11357 (plus:SI (match_dup 0)
11359 (set (reg:SI T_REG)
11360 (eq:SI (match_dup 0)
11365 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11366 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11367 ;; reload when the constant is too large for a reg+offset address.
11369 ;; ??? We would get much better code if this was done in reload. This would
11370 ;; require modifying find_reloads_address to recognize that if the constant
11371 ;; is out-of-range for an immediate add, then we get better code by reloading
11372 ;; the constant into a register than by reloading the sum into a register,
11373 ;; since the former is one instruction shorter if the address does not need
11374 ;; to be offsettable. Unfortunately this does not work, because there is
11375 ;; only one register, r0, that can be used as an index register. This register
11376 ;; is also the function return value register. So, if we try to force reload
11377 ;; to use double-reg addresses, then we end up with some instructions that
11378 ;; need to use r0 twice. The only way to fix this is to change the calling
11379 ;; convention so that r0 is not used to return values.
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:SI (match_dup 0))
11385 (match_operand:SI 2 "general_movsrc_operand" ""))]
11386 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11387 "mov.l %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:SI 2 "general_movdst_operand" "")
11393 (mem:SI (match_dup 0)))]
11394 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11395 "mov.l @(%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:HI (match_dup 0))
11401 (match_operand:HI 2 "general_movsrc_operand" ""))]
11402 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11403 "mov.w %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:HI 2 "general_movdst_operand" "")
11409 (mem:HI (match_dup 0)))]
11410 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11411 "mov.w @(%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:QI (match_dup 0))
11417 (match_operand:QI 2 "general_movsrc_operand" ""))]
11418 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11419 "mov.b %2,@(%0,%1)")
11422 [(set (match_operand:SI 0 "register_operand" "=r")
11423 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11424 (set (match_operand:QI 2 "general_movdst_operand" "")
11425 (mem:QI (match_dup 0)))]
11426 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11427 "mov.b @(%0,%1),%2")
11430 [(set (match_operand:SI 0 "register_operand" "=r")
11431 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11432 (set (mem:SF (match_dup 0))
11433 (match_operand:SF 2 "general_movsrc_operand" ""))]
11434 "TARGET_SH1 && REGNO (operands[0]) == 0
11435 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11436 || (GET_CODE (operands[2]) == SUBREG
11437 && REGNO (SUBREG_REG (operands[2])) < 16))
11438 && reg_unused_after (operands[0], insn)"
11439 "mov.l %2,@(%0,%1)")
11442 [(set (match_operand:SI 0 "register_operand" "=r")
11443 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11444 (set (match_operand:SF 2 "general_movdst_operand" "")
11446 (mem:SF (match_dup 0)))]
11447 "TARGET_SH1 && REGNO (operands[0]) == 0
11448 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11449 || (GET_CODE (operands[2]) == SUBREG
11450 && REGNO (SUBREG_REG (operands[2])) < 16))
11451 && reg_unused_after (operands[0], insn)"
11452 "mov.l @(%0,%1),%2")
11455 [(set (match_operand:SI 0 "register_operand" "=r")
11456 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11457 (set (mem:SF (match_dup 0))
11458 (match_operand:SF 2 "general_movsrc_operand" ""))]
11459 "TARGET_SH2E && REGNO (operands[0]) == 0
11460 && ((REG_P (operands[2])
11461 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11462 || (GET_CODE (operands[2]) == SUBREG
11463 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11464 && reg_unused_after (operands[0], insn)"
11465 "fmov{.s|} %2,@(%0,%1)")
11468 [(set (match_operand:SI 0 "register_operand" "=r")
11469 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11470 (set (match_operand:SF 2 "general_movdst_operand" "")
11472 (mem:SF (match_dup 0)))]
11473 "TARGET_SH2E && REGNO (operands[0]) == 0
11474 && ((REG_P (operands[2])
11475 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11476 || (GET_CODE (operands[2]) == SUBREG
11477 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11478 && reg_unused_after (operands[0], insn)"
11479 "fmov{.s|} @(%0,%1),%2")
11481 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11482 (define_insn "sp_switch_1"
11483 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11487 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11488 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11489 return \"mov r0,r15\";
11491 [(set_attr "length" "10")])
11493 ;; Switch back to the original stack for interrupt functions with the
11494 ;; sp_switch attribute. */
11495 (define_insn "sp_switch_2"
11498 "mov.l @r15+,r15\;mov.l @r15+,r0"
11499 [(set_attr "length" "4")])
11501 ;; Integer vector moves
11503 (define_expand "movv8qi"
11504 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11505 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11507 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11509 (define_insn "movv8qi_i"
11510 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11511 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11513 && (register_operand (operands[0], V8QImode)
11514 || sh_register_operand (operands[1], V8QImode))"
11521 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11522 (set_attr "length" "4,4,16,4,4")])
11525 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11526 (subreg:V8QI (const_int 0) 0))]
11528 [(set (match_dup 0)
11529 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11530 (const_int 0) (const_int 0) (const_int 0)
11531 (const_int 0) (const_int 0)]))])
11534 [(set (match_operand 0 "arith_reg_dest" "")
11535 (match_operand 1 "sh_rep_vec" ""))]
11536 "TARGET_SHMEDIA && reload_completed
11537 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11538 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11539 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11540 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11541 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11542 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11543 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11544 [(set (match_dup 0) (match_dup 1))
11548 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11549 rtx elt1 = XVECEXP (operands[1], 0, 1);
11552 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11556 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11557 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11559 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11560 operands[1] = XVECEXP (operands[1], 0, 0);
11563 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11565 = GEN_INT (TARGET_LITTLE_ENDIAN
11566 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11567 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11570 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11572 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11578 [(set (match_operand 0 "arith_reg_dest" "")
11579 (match_operand 1 "sh_const_vec" ""))]
11580 "TARGET_SHMEDIA && reload_completed
11581 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11582 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11583 [(set (match_dup 0) (match_dup 1))]
11586 rtx v = operands[1];
11587 enum machine_mode new_mode
11588 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11590 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11592 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11595 (define_expand "movv2hi"
11596 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11597 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11599 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11601 (define_insn "movv2hi_i"
11602 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11603 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11605 && (register_operand (operands[0], V2HImode)
11606 || sh_register_operand (operands[1], V2HImode))"
11613 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11614 (set_attr "length" "4,4,16,4,4")
11615 (set (attr "highpart")
11616 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11617 (const_string "user")]
11618 (const_string "ignore")))])
11620 (define_expand "movv4hi"
11621 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11622 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11624 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11626 (define_insn "movv4hi_i"
11627 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11628 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11630 && (register_operand (operands[0], V4HImode)
11631 || sh_register_operand (operands[1], V4HImode))"
11638 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11639 (set_attr "length" "4,4,16,4,4")
11640 (set_attr "highpart" "depend")])
11642 (define_expand "movv2si"
11643 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11644 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11646 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11648 (define_insn "movv2si_i"
11649 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11650 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11652 && (register_operand (operands[0], V2SImode)
11653 || sh_register_operand (operands[1], V2SImode))"
11660 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11661 (set_attr "length" "4,4,16,4,4")
11662 (set_attr "highpart" "depend")])
11664 ;; Multimedia Intrinsics
11666 (define_insn "absv2si2"
11667 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11668 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11671 [(set_attr "type" "mcmp_media")
11672 (set_attr "highpart" "depend")])
11674 (define_insn "absv4hi2"
11675 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11676 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11679 [(set_attr "type" "mcmp_media")
11680 (set_attr "highpart" "depend")])
11682 (define_insn "addv2si3"
11683 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11684 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11685 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11687 "madd.l %1, %2, %0"
11688 [(set_attr "type" "arith_media")
11689 (set_attr "highpart" "depend")])
11691 (define_insn "addv4hi3"
11692 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11693 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11694 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11696 "madd.w %1, %2, %0"
11697 [(set_attr "type" "arith_media")
11698 (set_attr "highpart" "depend")])
11700 (define_insn_and_split "addv2hi3"
11701 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11702 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11703 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11710 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11711 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11712 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11713 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11714 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11716 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11717 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11720 [(set_attr "highpart" "must_split")])
11722 (define_insn "ssaddv2si3"
11723 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11724 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11725 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11727 "madds.l %1, %2, %0"
11728 [(set_attr "type" "mcmp_media")
11729 (set_attr "highpart" "depend")])
11731 (define_insn "usaddv8qi3"
11732 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11733 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11734 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11736 "madds.ub %1, %2, %0"
11737 [(set_attr "type" "mcmp_media")
11738 (set_attr "highpart" "depend")])
11740 (define_insn "ssaddv4hi3"
11741 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11742 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11743 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11745 "madds.w %1, %2, %0"
11746 [(set_attr "type" "mcmp_media")
11747 (set_attr "highpart" "depend")])
11749 (define_insn "negcmpeqv8qi"
11750 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11751 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11752 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11754 "mcmpeq.b %N1, %N2, %0"
11755 [(set_attr "type" "mcmp_media")
11756 (set_attr "highpart" "depend")])
11758 (define_insn "negcmpeqv2si"
11759 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11760 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11761 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11763 "mcmpeq.l %N1, %N2, %0"
11764 [(set_attr "type" "mcmp_media")
11765 (set_attr "highpart" "depend")])
11767 (define_insn "negcmpeqv4hi"
11768 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11769 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11770 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11772 "mcmpeq.w %N1, %N2, %0"
11773 [(set_attr "type" "mcmp_media")
11774 (set_attr "highpart" "depend")])
11776 (define_insn "negcmpgtuv8qi"
11777 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11778 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11779 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11781 "mcmpgt.ub %N1, %N2, %0"
11782 [(set_attr "type" "mcmp_media")
11783 (set_attr "highpart" "depend")])
11785 (define_insn "negcmpgtv2si"
11786 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11787 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11788 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11790 "mcmpgt.l %N1, %N2, %0"
11791 [(set_attr "type" "mcmp_media")
11792 (set_attr "highpart" "depend")])
11794 (define_insn "negcmpgtv4hi"
11795 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11796 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11797 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11799 "mcmpgt.w %N1, %N2, %0"
11800 [(set_attr "type" "mcmp_media")
11801 (set_attr "highpart" "depend")])
11803 (define_insn "mcmv"
11804 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11805 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11806 (match_operand:DI 2 "arith_reg_operand" "r"))
11807 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11808 (not:DI (match_dup 2)))))]
11811 [(set_attr "type" "arith_media")
11812 (set_attr "highpart" "depend")])
11814 (define_insn "mcnvs_lw"
11815 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11817 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11818 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11820 "mcnvs.lw %N1, %N2, %0"
11821 [(set_attr "type" "mcmp_media")])
11823 (define_insn "mcnvs_wb"
11824 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11826 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11827 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11829 "mcnvs.wb %N1, %N2, %0"
11830 [(set_attr "type" "mcmp_media")])
11832 (define_insn "mcnvs_wub"
11833 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11835 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11836 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11838 "mcnvs.wub %N1, %N2, %0"
11839 [(set_attr "type" "mcmp_media")])
11841 (define_insn "mextr_rl"
11842 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11843 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11844 (match_operand:HI 3 "mextr_bit_offset" "i"))
11845 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11846 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11847 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11850 static char templ[21];
11852 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11853 (int) INTVAL (operands[3]) >> 3);
11856 [(set_attr "type" "arith_media")])
11858 (define_insn "*mextr_lr"
11859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11860 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11861 (match_operand:HI 3 "mextr_bit_offset" "i"))
11862 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11863 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11864 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11867 static char templ[21];
11869 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11870 (int) INTVAL (operands[4]) >> 3);
11873 [(set_attr "type" "arith_media")])
11875 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11876 ; vector then varies depending on endianness.
11877 (define_expand "mextr1"
11878 [(match_operand:DI 0 "arith_reg_dest" "")
11879 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11880 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11884 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11885 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11889 (define_expand "mextr2"
11890 [(match_operand:DI 0 "arith_reg_dest" "")
11891 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11892 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11896 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11897 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11901 (define_expand "mextr3"
11902 [(match_operand:DI 0 "arith_reg_dest" "")
11903 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11904 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11908 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11909 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11913 (define_expand "mextr4"
11914 [(match_operand:DI 0 "arith_reg_dest" "")
11915 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11916 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11920 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11921 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11925 (define_expand "mextr5"
11926 [(match_operand:DI 0 "arith_reg_dest" "")
11927 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11928 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11932 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11933 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11937 (define_expand "mextr6"
11938 [(match_operand:DI 0 "arith_reg_dest" "")
11939 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11940 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11944 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11945 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11949 (define_expand "mextr7"
11950 [(match_operand:DI 0 "arith_reg_dest" "")
11951 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11952 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11956 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11957 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11961 (define_expand "mmacfx_wl"
11962 [(match_operand:V2SI 0 "arith_reg_dest" "")
11963 (match_operand:V2HI 1 "extend_reg_operand" "")
11964 (match_operand:V2HI 2 "extend_reg_operand" "")
11965 (match_operand:V2SI 3 "arith_reg_operand" "")]
11969 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11970 operands[1], operands[2]));
11974 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11976 (define_insn "mmacfx_wl_i"
11977 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11979 (match_operand:V2SI 1 "arith_reg_operand" "0")
11984 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11985 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11988 "mmacfx.wl %2, %3, %0"
11989 [(set_attr "type" "mac_media")
11990 (set_attr "highpart" "depend")])
11992 (define_expand "mmacnfx_wl"
11993 [(match_operand:V2SI 0 "arith_reg_dest" "")
11994 (match_operand:V2HI 1 "extend_reg_operand" "")
11995 (match_operand:V2HI 2 "extend_reg_operand" "")
11996 (match_operand:V2SI 3 "arith_reg_operand" "")]
12000 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12001 operands[1], operands[2]));
12005 (define_insn "mmacnfx_wl_i"
12006 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12008 (match_operand:V2SI 1 "arith_reg_operand" "0")
12013 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12014 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12017 "mmacnfx.wl %2, %3, %0"
12018 [(set_attr "type" "mac_media")
12019 (set_attr "highpart" "depend")])
12021 (define_insn "mulv2si3"
12022 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12023 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12024 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12026 "mmul.l %1, %2, %0"
12027 [(set_attr "type" "d2mpy_media")
12028 (set_attr "highpart" "depend")])
12030 (define_insn "mulv4hi3"
12031 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12032 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12033 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12035 "mmul.w %1, %2, %0"
12036 [(set_attr "type" "dmpy_media")
12037 (set_attr "highpart" "depend")])
12039 (define_insn "mmulfx_l"
12040 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12044 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12045 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12048 "mmulfx.l %1, %2, %0"
12049 [(set_attr "type" "d2mpy_media")
12050 (set_attr "highpart" "depend")])
12052 (define_insn "mmulfx_w"
12053 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12057 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12058 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12061 "mmulfx.w %1, %2, %0"
12062 [(set_attr "type" "dmpy_media")
12063 (set_attr "highpart" "depend")])
12065 (define_insn "mmulfxrp_w"
12066 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12071 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12072 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12076 "mmulfxrp.w %1, %2, %0"
12077 [(set_attr "type" "dmpy_media")
12078 (set_attr "highpart" "depend")])
12081 (define_expand "mmulhi_wl"
12082 [(match_operand:V2SI 0 "arith_reg_dest" "")
12083 (match_operand:V4HI 1 "arith_reg_operand" "")
12084 (match_operand:V4HI 2 "arith_reg_operand" "")]
12088 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12089 (operands[0], operands[1], operands[2]));
12093 (define_expand "mmullo_wl"
12094 [(match_operand:V2SI 0 "arith_reg_dest" "")
12095 (match_operand:V4HI 1 "arith_reg_operand" "")
12096 (match_operand:V4HI 2 "arith_reg_operand" "")]
12100 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12101 (operands[0], operands[1], operands[2]));
12105 (define_insn "mmul23_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 2) (const_int 3)])))]
12113 "* return (TARGET_LITTLE_ENDIAN
12114 ? \"mmulhi.wl %1, %2, %0\"
12115 : \"mmullo.wl %1, %2, %0\");"
12116 [(set_attr "type" "dmpy_media")
12117 (set (attr "highpart")
12118 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12119 (const_string "user")))])
12121 (define_insn "mmul01_wl"
12122 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12125 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12126 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12127 (parallel [(const_int 0) (const_int 1)])))]
12129 "* return (TARGET_LITTLE_ENDIAN
12130 ? \"mmullo.wl %1, %2, %0\"
12131 : \"mmulhi.wl %1, %2, %0\");"
12132 [(set_attr "type" "dmpy_media")
12133 (set (attr "highpart")
12134 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12135 (const_string "user")))])
12138 (define_expand "mmulsum_wq"
12139 [(match_operand:DI 0 "arith_reg_dest" "")
12140 (match_operand:V4HI 1 "arith_reg_operand" "")
12141 (match_operand:V4HI 2 "arith_reg_operand" "")
12142 (match_operand:DI 3 "arith_reg_operand" "")]
12146 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12147 operands[1], operands[2]));
12151 (define_insn "mmulsum_wq_i"
12152 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12153 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12158 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12159 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12160 (parallel [(const_int 0)]))
12161 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12162 (sign_extend:V4DI (match_dup 3)))
12163 (parallel [(const_int 1)])))
12165 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12166 (sign_extend:V4DI (match_dup 3)))
12167 (parallel [(const_int 2)]))
12168 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12169 (sign_extend:V4DI (match_dup 3)))
12170 (parallel [(const_int 3)]))))))]
12172 "mmulsum.wq %2, %3, %0"
12173 [(set_attr "type" "mac_media")])
12175 (define_expand "mperm_w"
12176 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12177 (match_operand:V4HI 1 "arith_reg_operand" "r")
12178 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12182 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12183 (operands[0], operands[1], operands[2]));
12187 ; This use of vec_select isn't exactly correct according to rtl.texi
12188 ; (because not constant), but it seems a straightforward extension.
12189 (define_insn "mperm_w_little"
12190 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12192 (match_operand:V4HI 1 "arith_reg_operand" "r")
12194 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12195 (const_int 2) (const_int 0))
12196 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12197 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12198 (zero_extract:QI (match_dup 2) (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_w_big"
12204 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12206 (match_operand:V4HI 1 "arith_reg_operand" "r")
12208 [(zero_extract:QI (not:QI (match_operand:QI 2
12209 "extend_reg_or_0_operand" "rZ"))
12210 (const_int 2) (const_int 0))
12211 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12212 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12213 (zero_extract:QI (not:QI (match_dup 2))
12214 (const_int 2) (const_int 6))])))]
12215 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12216 "mperm.w %1, %N2, %0"
12217 [(set_attr "type" "arith_media")])
12219 (define_insn "mperm_w0"
12220 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12221 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12222 "trunc_hi_operand" "r"))))]
12224 "mperm.w %1, r63, %0"
12225 [(set_attr "type" "arith_media")
12226 (set_attr "highpart" "ignore")])
12228 (define_expand "msad_ubq"
12229 [(match_operand:DI 0 "arith_reg_dest" "")
12230 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12231 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12232 (match_operand:DI 3 "arith_reg_operand" "")]
12236 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12237 operands[1], operands[2]));
12241 (define_insn "msad_ubq_i"
12242 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12247 (match_operand:DI 1 "arith_reg_operand" "0")
12248 (abs:DI (vec_select:DI
12251 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12253 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12254 (parallel [(const_int 0)]))))
12255 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12256 (zero_extend:V8DI (match_dup 3)))
12257 (parallel [(const_int 1)]))))
12259 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12260 (zero_extend:V8DI (match_dup 3)))
12261 (parallel [(const_int 2)])))
12262 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12263 (zero_extend:V8DI (match_dup 3)))
12264 (parallel [(const_int 3)])))))
12267 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12268 (zero_extend:V8DI (match_dup 3)))
12269 (parallel [(const_int 4)])))
12270 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12271 (zero_extend:V8DI (match_dup 3)))
12272 (parallel [(const_int 5)]))))
12274 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12275 (zero_extend:V8DI (match_dup 3)))
12276 (parallel [(const_int 6)])))
12277 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12278 (zero_extend:V8DI (match_dup 3)))
12279 (parallel [(const_int 7)])))))))]
12281 "msad.ubq %N2, %N3, %0"
12282 [(set_attr "type" "mac_media")])
12284 (define_insn "mshalds_l"
12285 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12288 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12289 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12290 (const_int 31)))))]
12292 "mshalds.l %1, %2, %0"
12293 [(set_attr "type" "mcmp_media")
12294 (set_attr "highpart" "depend")])
12296 (define_insn "mshalds_w"
12297 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12300 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12301 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12302 (const_int 15)))))]
12304 "mshalds.w %1, %2, %0"
12305 [(set_attr "type" "mcmp_media")
12306 (set_attr "highpart" "depend")])
12308 (define_insn "ashrv2si3"
12309 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12310 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12311 (match_operand:DI 2 "arith_reg_operand" "r")))]
12313 "mshard.l %1, %2, %0"
12314 [(set_attr "type" "arith_media")
12315 (set_attr "highpart" "depend")])
12317 (define_insn "ashrv4hi3"
12318 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12319 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12320 (match_operand:DI 2 "arith_reg_operand" "r")))]
12322 "mshard.w %1, %2, %0"
12323 [(set_attr "type" "arith_media")
12324 (set_attr "highpart" "depend")])
12326 (define_insn "mshards_q"
12327 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12329 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12330 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12332 "mshards.q %1, %N2, %0"
12333 [(set_attr "type" "mcmp_media")])
12335 (define_expand "mshfhi_b"
12336 [(match_operand:V8QI 0 "arith_reg_dest" "")
12337 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12338 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12342 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12343 (operands[0], operands[1], operands[2]));
12347 (define_expand "mshflo_b"
12348 [(match_operand:V8QI 0 "arith_reg_dest" "")
12349 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12350 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12354 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12355 (operands[0], operands[1], operands[2]));
12359 (define_insn "mshf4_b"
12361 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12363 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12364 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12365 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12366 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12368 "* return (TARGET_LITTLE_ENDIAN
12369 ? \"mshfhi.b %N1, %N2, %0\"
12370 : \"mshflo.b %N1, %N2, %0\");"
12371 [(set_attr "type" "arith_media")
12372 (set (attr "highpart")
12373 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12374 (const_string "user")))])
12376 (define_insn "mshf0_b"
12378 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12380 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12381 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12382 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12383 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12385 "* return (TARGET_LITTLE_ENDIAN
12386 ? \"mshflo.b %N1, %N2, %0\"
12387 : \"mshfhi.b %N1, %N2, %0\");"
12388 [(set_attr "type" "arith_media")
12389 (set (attr "highpart")
12390 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12391 (const_string "user")))])
12393 (define_expand "mshfhi_l"
12394 [(match_operand:V2SI 0 "arith_reg_dest" "")
12395 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12396 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12400 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12401 (operands[0], operands[1], operands[2]));
12405 (define_expand "mshflo_l"
12406 [(match_operand:V2SI 0 "arith_reg_dest" "")
12407 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12408 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12412 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12413 (operands[0], operands[1], operands[2]));
12417 (define_insn "mshf4_l"
12418 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12420 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12421 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12422 (parallel [(const_int 1) (const_int 3)])))]
12424 "* return (TARGET_LITTLE_ENDIAN
12425 ? \"mshfhi.l %N1, %N2, %0\"
12426 : \"mshflo.l %N1, %N2, %0\");"
12427 [(set_attr "type" "arith_media")
12428 (set (attr "highpart")
12429 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12430 (const_string "user")))])
12432 (define_insn "mshf0_l"
12433 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12435 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12436 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12437 (parallel [(const_int 0) (const_int 2)])))]
12439 "* return (TARGET_LITTLE_ENDIAN
12440 ? \"mshflo.l %N1, %N2, %0\"
12441 : \"mshfhi.l %N1, %N2, %0\");"
12442 [(set_attr "type" "arith_media")
12443 (set (attr "highpart")
12444 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12445 (const_string "user")))])
12447 (define_expand "mshfhi_w"
12448 [(match_operand:V4HI 0 "arith_reg_dest" "")
12449 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12450 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12454 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12455 (operands[0], operands[1], operands[2]));
12459 (define_expand "mshflo_w"
12460 [(match_operand:V4HI 0 "arith_reg_dest" "")
12461 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12462 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12466 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12467 (operands[0], operands[1], operands[2]));
12471 (define_insn "mshf4_w"
12472 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12474 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12475 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12476 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12478 "* return (TARGET_LITTLE_ENDIAN
12479 ? \"mshfhi.w %N1, %N2, %0\"
12480 : \"mshflo.w %N1, %N2, %0\");"
12481 [(set_attr "type" "arith_media")
12482 (set (attr "highpart")
12483 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12484 (const_string "user")))])
12486 (define_insn "mshf0_w"
12487 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12489 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12490 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12491 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12493 "* return (TARGET_LITTLE_ENDIAN
12494 ? \"mshflo.w %N1, %N2, %0\"
12495 : \"mshfhi.w %N1, %N2, %0\");"
12496 [(set_attr "type" "arith_media")
12497 (set (attr "highpart")
12498 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12499 (const_string "user")))])
12501 (define_insn "mshflo_w_x"
12502 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12504 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12505 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12506 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12508 "mshflo.w %N1, %N2, %0"
12509 [(set_attr "type" "arith_media")
12510 (set_attr "highpart" "ignore")])
12512 /* These are useful to expand ANDs and as combiner patterns. */
12513 (define_insn_and_split "mshfhi_l_di"
12514 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12515 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12517 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12518 (const_int -4294967296))))]
12521 mshfhi.l %N1, %N2, %0
12523 "TARGET_SHMEDIA && reload_completed
12524 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12525 [(set (match_dup 3) (match_dup 4))
12526 (set (match_dup 5) (match_dup 6))]
12529 operands[3] = gen_lowpart (SImode, operands[0]);
12530 operands[4] = gen_highpart (SImode, operands[1]);
12531 operands[5] = gen_highpart (SImode, operands[0]);
12532 operands[6] = gen_highpart (SImode, operands[2]);
12534 [(set_attr "type" "arith_media")])
12536 (define_insn "*mshfhi_l_di_rev"
12537 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12538 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12539 (const_int -4294967296))
12540 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12543 "mshfhi.l %N2, %N1, %0"
12544 [(set_attr "type" "arith_media")])
12547 [(set (match_operand:DI 0 "arith_reg_dest" "")
12548 (ior:DI (zero_extend:DI (match_operand:SI 1
12549 "extend_reg_or_0_operand" ""))
12550 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12551 (const_int -4294967296))))
12552 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12557 emit_insn (gen_ashldi3_media (operands[3],
12558 simplify_gen_subreg (DImode, operands[1],
12561 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12565 (define_insn "mshflo_l_di"
12566 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12567 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12568 (const_int 4294967295))
12569 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12573 "mshflo.l %N1, %N2, %0"
12574 [(set_attr "type" "arith_media")
12575 (set_attr "highpart" "ignore")])
12577 (define_insn "*mshflo_l_di_rev"
12578 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12579 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12581 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12582 (const_int 4294967295))))]
12585 "mshflo.l %N2, %N1, %0"
12586 [(set_attr "type" "arith_media")
12587 (set_attr "highpart" "ignore")])
12589 ;; Combiner pattern for trampoline initialization.
12590 (define_insn_and_split "*double_shori"
12591 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12592 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12594 (match_operand:DI 2 "const_int_operand" "n")))]
12596 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12598 "rtx_equal_p (operands[0], operands[1])"
12602 HOST_WIDE_INT v = INTVAL (operands[2]);
12604 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12605 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12608 [(set_attr "highpart" "ignore")])
12611 (define_insn "*mshflo_l_di_x"
12612 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12613 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12615 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12619 "mshflo.l %N1, %N2, %0"
12620 [(set_attr "type" "arith_media")
12621 (set_attr "highpart" "ignore")])
12623 (define_insn_and_split "concat_v2sf"
12624 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12625 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12626 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12627 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12631 mshflo.l %N1, %N2, %0
12634 "TARGET_SHMEDIA && reload_completed
12635 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12636 [(set (match_dup 3) (match_dup 1))
12637 (set (match_dup 4) (match_dup 2))]
12640 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12641 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12643 [(set_attr "type" "arith_media")
12644 (set_attr "highpart" "ignore")])
12646 (define_insn "*mshflo_l_di_x_rev"
12647 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12648 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12650 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12653 "mshflo.l %N2, %N1, %0"
12654 [(set_attr "type" "arith_media")
12655 (set_attr "highpart" "ignore")])
12657 (define_insn "ashlv2si3"
12658 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12659 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12660 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12662 "mshlld.l %1, %2, %0"
12663 [(set_attr "type" "arith_media")
12664 (set_attr "highpart" "depend")])
12667 [(set (match_operand 0 "any_register_operand" "")
12668 (match_operator 3 "shift_operator"
12669 [(match_operand 1 "any_register_operand" "")
12670 (match_operand 2 "shift_count_reg_operand" "")]))]
12671 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12672 [(set (match_dup 0) (match_dup 3))]
12675 rtx count = operands[2];
12676 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12678 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12679 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12680 || GET_CODE (count) == TRUNCATE)
12681 count = XEXP (count, 0);
12682 inner_mode = GET_MODE (count);
12683 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12684 subreg_lowpart_offset (outer_mode, inner_mode));
12685 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12686 operands[1], count);
12689 (define_insn "ashlv4hi3"
12690 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12691 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12692 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12694 "mshlld.w %1, %2, %0"
12695 [(set_attr "type" "arith_media")
12696 (set_attr "highpart" "depend")])
12698 (define_insn "lshrv2si3"
12699 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12700 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12701 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12703 "mshlrd.l %1, %2, %0"
12704 [(set_attr "type" "arith_media")
12705 (set_attr "highpart" "depend")])
12707 (define_insn "lshrv4hi3"
12708 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12709 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12710 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12712 "mshlrd.w %1, %2, %0"
12713 [(set_attr "type" "arith_media")
12714 (set_attr "highpart" "depend")])
12716 (define_insn "subv2si3"
12717 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12718 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12719 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12721 "msub.l %N1, %2, %0"
12722 [(set_attr "type" "arith_media")
12723 (set_attr "highpart" "depend")])
12725 (define_insn "subv4hi3"
12726 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12727 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12728 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12730 "msub.w %N1, %2, %0"
12731 [(set_attr "type" "arith_media")
12732 (set_attr "highpart" "depend")])
12734 (define_insn_and_split "subv2hi3"
12735 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12736 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12737 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12744 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12745 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12746 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12747 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12748 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12750 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12751 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12754 [(set_attr "highpart" "must_split")])
12756 (define_insn "sssubv2si3"
12757 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12758 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12759 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12761 "msubs.l %N1, %2, %0"
12762 [(set_attr "type" "mcmp_media")
12763 (set_attr "highpart" "depend")])
12765 (define_insn "ussubv8qi3"
12766 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12767 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12768 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12770 "msubs.ub %N1, %2, %0"
12771 [(set_attr "type" "mcmp_media")
12772 (set_attr "highpart" "depend")])
12774 (define_insn "sssubv4hi3"
12775 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12776 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12777 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12779 "msubs.w %N1, %2, %0"
12780 [(set_attr "type" "mcmp_media")
12781 (set_attr "highpart" "depend")])
12783 ;; Floating Point Intrinsics
12785 (define_insn "fcosa_s"
12786 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12787 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12791 [(set_attr "type" "atrans_media")])
12793 (define_insn "fsina_s"
12794 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12795 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12799 [(set_attr "type" "atrans_media")])
12801 (define_insn "fipr"
12802 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12803 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12804 "fp_arith_reg_operand" "f")
12805 (match_operand:V4SF 2
12806 "fp_arith_reg_operand" "f"))
12807 (parallel [(const_int 0)]))
12808 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12809 (parallel [(const_int 1)])))
12810 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12811 (parallel [(const_int 2)]))
12812 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12813 (parallel [(const_int 3)])))))]
12815 "fipr.s %1, %2, %0"
12816 [(set_attr "type" "fparith_media")])
12818 (define_insn "fsrra_s"
12819 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12820 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12824 [(set_attr "type" "atrans_media")])
12826 (define_insn "ftrv"
12827 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12831 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12832 (parallel [(const_int 0) (const_int 5)
12833 (const_int 10) (const_int 15)]))
12834 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12836 (vec_select:V4SF (match_dup 1)
12837 (parallel [(const_int 4) (const_int 9)
12838 (const_int 14) (const_int 3)]))
12839 (vec_select:V4SF (match_dup 2)
12840 (parallel [(const_int 1) (const_int 2)
12841 (const_int 3) (const_int 0)]))))
12844 (vec_select:V4SF (match_dup 1)
12845 (parallel [(const_int 8) (const_int 13)
12846 (const_int 2) (const_int 7)]))
12847 (vec_select:V4SF (match_dup 2)
12848 (parallel [(const_int 2) (const_int 3)
12849 (const_int 0) (const_int 1)])))
12851 (vec_select:V4SF (match_dup 1)
12852 (parallel [(const_int 12) (const_int 1)
12853 (const_int 6) (const_int 11)]))
12854 (vec_select:V4SF (match_dup 2)
12855 (parallel [(const_int 3) (const_int 0)
12856 (const_int 1) (const_int 2)]))))))]
12858 "ftrv.s %1, %2, %0"
12859 [(set_attr "type" "fparith_media")])
12861 (define_insn "ldhi_l"
12862 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12864 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12867 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12871 [(set_attr "type" "load_media")])
12873 (define_insn "ldhi_q"
12874 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12876 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12879 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12883 [(set_attr "type" "load_media")])
12885 (define_insn_and_split "*ldhi_q_comb0"
12886 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12888 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12889 "register_operand" "r")
12890 (match_operand:SI 2
12891 "ua_offset" "I06"))
12894 (plus:SI (and:SI (match_dup 1) (const_int 7))
12897 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12901 "emit_insn (gen_ldhi_q (operands[0],
12902 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12906 (define_insn_and_split "*ldhi_q_comb1"
12907 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12909 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12910 "register_operand" "r")
12911 (match_operand:SI 2
12912 "ua_offset" "I06"))
12915 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12916 "ua_offset" "I06"))
12920 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12921 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12925 "emit_insn (gen_ldhi_q (operands[0],
12926 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12930 (define_insn "ldlo_l"
12931 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12933 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12935 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12936 (and:SI (match_dup 1) (const_int 3))))]
12939 [(set_attr "type" "load_media")])
12941 (define_insn "ldlo_q"
12942 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12944 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12946 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12947 (and:SI (match_dup 1) (const_int 7))))]
12950 [(set_attr "type" "load_media")])
12952 (define_insn_and_split "*ldlo_q_comb0"
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) (and:SI (match_dup 1) (const_int 7)))
12959 (and:SI (match_dup 1) (const_int 7))))]
12960 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12964 "emit_insn (gen_ldlo_q (operands[0],
12965 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12968 (define_insn_and_split "*ldlo_q_comb1"
12969 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12971 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12972 (match_operand:SI 2 "ua_offset" "I06"))
12974 (minus:SI (const_int 8)
12975 (and:SI (plus:SI (match_dup 1)
12976 (match_operand:SI 3 "ua_offset" "I06"))
12978 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12979 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12980 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12984 "emit_insn (gen_ldlo_q (operands[0],
12985 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12988 (define_insn "sthi_l"
12989 [(set (zero_extract:SI
12990 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12993 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12995 (match_operand:SI 1 "arith_reg_operand" "r"))]
12998 [(set_attr "type" "ustore_media")])
13000 ;; All unaligned stores are considered to be 'narrow' because they typically
13001 ;; operate on less that a quadword, and when they operate on a full quadword,
13002 ;; the vanilla store high / store low sequence will cause a stall if not
13003 ;; scheduled apart.
13004 (define_insn "sthi_q"
13005 [(set (zero_extract:DI
13006 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13009 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13011 (match_operand:DI 1 "arith_reg_operand" "r"))]
13014 [(set_attr "type" "ustore_media")])
13016 (define_insn_and_split "*sthi_q_comb0"
13017 [(set (zero_extract:DI
13018 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13019 "register_operand" "r")
13020 (match_operand:SI 1 "ua_offset"
13024 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13026 (match_operand:DI 2 "arith_reg_operand" "r"))]
13027 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13031 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13035 (define_insn_and_split "*sthi_q_comb1"
13036 [(set (zero_extract:DI
13037 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13038 "register_operand" "r")
13039 (match_operand:SI 1 "ua_offset"
13043 (plus:SI (and:SI (plus:SI (match_dup 0)
13044 (match_operand:SI 2 "ua_offset" "I06"))
13048 (match_operand:DI 3 "arith_reg_operand" "r"))]
13049 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13050 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13054 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13058 ;; This is highpart user because the address is used as full 64 bit.
13059 (define_insn "stlo_l"
13060 [(set (zero_extract:SI
13061 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13063 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13064 (and:SI (match_dup 0) (const_int 3)))
13065 (match_operand:SI 1 "arith_reg_operand" "r"))]
13068 [(set_attr "type" "ustore_media")])
13070 (define_insn "stlo_q"
13071 [(set (zero_extract:DI
13072 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13074 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13075 (and:SI (match_dup 0) (const_int 7)))
13076 (match_operand:DI 1 "arith_reg_operand" "r"))]
13079 [(set_attr "type" "ustore_media")])
13081 (define_insn_and_split "*stlo_q_comb0"
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 (match_dup 0) (const_int 7)))
13087 (and:SI (match_dup 0) (const_int 7)))
13088 (match_operand:DI 2 "arith_reg_operand" "r"))]
13089 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13093 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13097 (define_insn_and_split "*stlo_q_comb1"
13098 [(set (zero_extract:DI
13099 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13100 (match_operand:SI 1 "ua_offset" "I06"))
13102 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13103 (match_operand:SI 2
13104 "ua_offset" "I06"))
13106 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13107 (match_operand:DI 3 "arith_reg_operand" "r"))]
13108 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13112 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13116 (define_insn "ldhi_l64"
13117 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13119 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13122 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13126 [(set_attr "type" "load_media")])
13128 (define_insn "ldhi_q64"
13129 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13131 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13134 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13138 [(set_attr "type" "load_media")])
13140 (define_insn "ldlo_l64"
13141 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13143 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13145 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13146 (and:DI (match_dup 1) (const_int 3))))]
13149 [(set_attr "type" "load_media")])
13151 (define_insn "ldlo_q64"
13152 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13154 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13156 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13157 (and:DI (match_dup 1) (const_int 7))))]
13160 [(set_attr "type" "load_media")])
13162 (define_insn "sthi_l64"
13163 [(set (zero_extract:SI
13164 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13167 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13169 (match_operand:SI 1 "arith_reg_operand" "r"))]
13172 [(set_attr "type" "ustore_media")])
13174 (define_insn "sthi_q64"
13175 [(set (zero_extract:DI
13176 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13179 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13181 (match_operand:DI 1 "arith_reg_operand" "r"))]
13184 [(set_attr "type" "ustore_media")])
13186 (define_insn "stlo_l64"
13187 [(set (zero_extract:SI
13188 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13190 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13191 (and:DI (match_dup 0) (const_int 3)))
13192 (match_operand:SI 1 "arith_reg_operand" "r"))]
13195 [(set_attr "type" "ustore_media")])
13197 (define_insn "stlo_q64"
13198 [(set (zero_extract:DI
13199 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13201 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13202 (and:DI (match_dup 0) (const_int 7)))
13203 (match_operand:DI 1 "arith_reg_operand" "r"))]
13206 [(set_attr "type" "ustore_media")])
13209 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13210 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13214 [(set_attr "type" "arith_media")])
13216 (define_insn "nsbsi"
13217 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13219 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13223 [(set_attr "type" "arith_media")])
13225 (define_insn "nsbdi"
13226 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13228 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13232 [(set_attr "type" "arith_media")])
13234 (define_expand "ffsdi2"
13235 [(set (match_operand:DI 0 "arith_reg_dest" "")
13236 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13240 rtx scratch = gen_reg_rtx (DImode);
13243 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13244 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13245 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13246 emit_insn (gen_nsbdi (scratch, scratch));
13247 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13248 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13249 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13250 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13255 (define_expand "ffssi2"
13256 [(set (match_operand:SI 0 "arith_reg_dest" "")
13257 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13261 rtx scratch = gen_reg_rtx (SImode);
13262 rtx discratch = gen_reg_rtx (DImode);
13265 emit_insn (gen_adddi3 (discratch,
13266 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13268 emit_insn (gen_andcdi3 (discratch,
13269 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13271 emit_insn (gen_nsbsi (scratch, discratch));
13272 last = emit_insn (gen_subsi3 (operands[0],
13273 force_reg (SImode, GEN_INT (63)), scratch));
13274 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13279 (define_insn "byterev"
13280 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13281 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13282 (parallel [(const_int 7) (const_int 6) (const_int 5)
13283 (const_int 4) (const_int 3) (const_int 2)
13284 (const_int 1) (const_int 0)])))]
13287 [(set_attr "type" "arith_media")])
13289 (define_insn "*prefetch_media"
13290 [(prefetch (match_operand:QI 0 "address_operand" "p")
13291 (match_operand:SI 1 "const_int_operand" "n")
13292 (match_operand:SI 2 "const_int_operand" "n"))]
13296 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13297 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13300 [(set_attr "type" "other")])
13302 (define_insn "*prefetch_i4"
13303 [(prefetch (match_operand:SI 0 "register_operand" "r")
13304 (match_operand:SI 1 "const_int_operand" "n")
13305 (match_operand:SI 2 "const_int_operand" "n"))]
13306 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13309 return \"pref @%0\";
13311 [(set_attr "type" "other")])
13313 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13314 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13315 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13316 (define_expand "prefetch"
13317 [(prefetch (match_operand 0 "address_operand" "p")
13318 (match_operand:SI 1 "const_int_operand" "n")
13319 (match_operand:SI 2 "const_int_operand" "n"))]
13320 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13321 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13324 if (GET_MODE (operands[0]) != Pmode
13325 || !CONST_INT_P (operands[1])
13326 || !CONST_INT_P (operands[2]))
13328 if (! TARGET_SHMEDIA)
13329 operands[0] = force_reg (Pmode, operands[0]);
13332 (define_insn "prefetch_m2a"
13333 [(prefetch (match_operand:SI 0 "register_operand" "r")
13334 (match_operand:SI 1 "const_int_operand" "n")
13335 (match_operand:SI 2 "const_int_operand" "n"))]
13338 [(set_attr "type" "other")])
13340 (define_insn "alloco_i"
13341 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13342 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13348 if (GET_CODE (operands[0]) == PLUS)
13350 xops[0] = XEXP (operands[0], 0);
13351 xops[1] = XEXP (operands[0], 1);
13355 xops[0] = operands[0];
13356 xops[1] = const0_rtx;
13358 output_asm_insn (\"alloco %0, %1\", xops);
13361 [(set_attr "type" "other")])
13364 [(set (match_operand 0 "any_register_operand" "")
13365 (match_operand 1 "" ""))]
13366 "TARGET_SHMEDIA && reload_completed"
13367 [(set (match_dup 0) (match_dup 1))]
13372 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13377 ; Stack Protector Patterns
13379 (define_expand "stack_protect_set"
13380 [(set (match_operand 0 "memory_operand" "")
13381 (match_operand 1 "memory_operand" ""))]
13384 if (TARGET_SHMEDIA)
13386 if (TARGET_SHMEDIA64)
13387 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13389 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13392 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13397 (define_insn "stack_protect_set_si"
13398 [(set (match_operand:SI 0 "memory_operand" "=m")
13399 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13400 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13402 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13403 [(set_attr "type" "other")
13404 (set_attr "length" "6")])
13406 (define_insn "stack_protect_set_si_media"
13407 [(set (match_operand:SI 0 "memory_operand" "=m")
13408 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13409 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13411 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13412 [(set_attr "type" "other")
13413 (set_attr "length" "12")])
13415 (define_insn "stack_protect_set_di_media"
13416 [(set (match_operand:DI 0 "memory_operand" "=m")
13417 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13418 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13420 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13421 [(set_attr "type" "other")
13422 (set_attr "length" "12")])
13424 (define_expand "stack_protect_test"
13425 [(match_operand 0 "memory_operand" "")
13426 (match_operand 1 "memory_operand" "")
13427 (match_operand 2 "" "")]
13430 if (TARGET_SHMEDIA)
13432 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13435 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13436 if (TARGET_SHMEDIA64)
13438 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13440 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13444 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13446 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13451 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13452 emit_jump_insn (gen_branch_true (operands[2]));
13458 (define_insn "stack_protect_test_si"
13459 [(set (reg:SI T_REG)
13460 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13461 (match_operand:SI 1 "memory_operand" "m")]
13463 (set (match_scratch:SI 2 "=&r") (const_int 0))
13464 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13466 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13467 [(set_attr "type" "other")
13468 (set_attr "length" "10")])
13470 (define_insn "stack_protect_test_si_media"
13471 [(set (match_operand:SI 0 "register_operand" "=&r")
13472 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13473 (match_operand:SI 2 "memory_operand" "m")]
13475 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13477 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13478 [(set_attr "type" "other")
13479 (set_attr "length" "16")])
13481 (define_insn "stack_protect_test_di_media"
13482 [(set (match_operand:DI 0 "register_operand" "=&r")
13483 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13484 (match_operand:DI 2 "memory_operand" "m")]
13486 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13488 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13489 [(set_attr "type" "other")
13490 (set_attr "length" "16")])