1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
138 (UNSPEC_EH_RETURN 19)
147 ;; These are used with unspec_volatile.
153 (UNSPECV_WINDOW_END 10)
154 (UNSPECV_CONST_END 11)
157 ;; -------------------------------------------------------------------------
159 ;; -------------------------------------------------------------------------
164 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165 (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
186 ;; cbranch conditional branch instructions
187 ;; jump unconditional jumps
188 ;; arith ordinary arithmetic
189 ;; arith3 a compound insn that behaves similarly to a sequence of
190 ;; three insns of type arith
191 ;; arith3b like above, but might end with a redirected branch
193 ;; load_si Likewise, SImode variant for general register.
194 ;; fload Likewise, but load to fp register.
196 ;; move general purpose register to register
197 ;; mt_group other sh4 mt instructions
198 ;; fmove register to register, floating point
199 ;; smpy word precision integer multiply
200 ;; dmpy longword or doublelongword precision integer multiply
202 ;; pload load of pr reg, which can't be put into delay slot of rts
203 ;; prset copy register to pr reg, ditto
204 ;; pstore store of pr reg, which can't be put into delay slot of jsr
205 ;; prget copy pr to register, ditto
206 ;; pcload pc relative load of constant value
207 ;; pcfload Likewise, but load to fp register.
208 ;; pcload_si Likewise, SImode variant for general register.
209 ;; rte return from exception
210 ;; sfunc special function call with known used registers
211 ;; call function call
213 ;; fdiv floating point divide (or square root)
214 ;; gp_fpul move from general purpose register to fpul
215 ;; fpul_gp move from fpul to general purpose register
216 ;; mac_gp move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s fix_truncsfsi2_i4
219 ;; dfdiv double precision floating point divide (or square root)
220 ;; cwb ic_invalidate_line_i
221 ;; movua SH4a unaligned load
222 ;; fsrra square root reciprocal approximate
223 ;; fsca sine and cosine approximate
224 ;; tls_load load TLS related address
225 ;; arith_media SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media SHmedia compare instructions
228 ;; dfdiv_media SHmedia double precision divide and square root
229 ;; dfmul_media SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media SHmedia longword multiply
233 ;; fcmp_media SHmedia floating point compare instructions
234 ;; fdiv_media SHmedia single precision divide and square root
235 ;; fload_media SHmedia floating point register load instructions
236 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media SHmedia unconditional branch instructions
243 ;; load_media SHmedia general register load instructions
244 ;; pt_media SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media SHmedia ptabs instruction
246 ;; store_media SHmedia general register store instructions
247 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media SHmedia mac-style fixed point operations
249 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
250 ;; atrans SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil no-op move, will be deleted.
255 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,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"
256 (const_string "other"))
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
261 ;; mt_group SH4 "mt" group instructions.
263 ;; ex_group SH4 "ex" group instructions.
265 ;; ls_group SH4 "ls" group instructions.
268 (define_attr "insn_class"
269 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273 (eq_attr "type" "cbranch,jump") (const_string "br_group")
274 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275 (const_string "fe_group")
276 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
277 (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long. Something in the
296 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
301 ;; The maximum range used for SImode constant pool entries is 1018. A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table. That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
319 (define_attr "short_cbranch_p" "no,yes"
320 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
322 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
324 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
326 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
328 ] (const_string "no")))
330 (define_attr "med_branch_p" "no,yes"
331 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
334 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
339 ] (const_string "no")))
341 (define_attr "med_cbranch_p" "no,yes"
342 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
345 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
347 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
350 ] (const_string "no")))
352 (define_attr "braf_branch_p" "no,yes"
353 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
358 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
360 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
363 ] (const_string "no")))
365 (define_attr "braf_cbranch_p" "no,yes"
366 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
368 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
371 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
373 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
376 ] (const_string "no")))
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
385 ; All other instructions are two bytes long by default.
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390 (cond [(eq_attr "type" "cbranch")
391 (cond [(eq_attr "short_cbranch_p" "yes")
393 (eq_attr "med_cbranch_p" "yes")
395 (eq_attr "braf_cbranch_p" "yes")
397 ;; ??? using pc is not computed transitively.
398 (ne (match_dup 0) (match_dup 0))
400 (ne (symbol_ref ("flag_pic")) (const_int 0))
403 (eq_attr "type" "jump")
404 (cond [(eq_attr "med_branch_p" "yes")
406 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
408 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409 (symbol_ref "code_for_indirect_jump_scratch")))
410 (if_then_else (eq_attr "braf_branch_p" "yes")
413 (eq_attr "braf_branch_p" "yes")
415 ;; ??? using pc is not computed transitively.
416 (ne (match_dup 0) (match_dup 0))
418 (ne (symbol_ref ("flag_pic")) (const_int 0))
421 (eq_attr "type" "pt_media")
422 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
423 (const_int 20) (const_int 12))
424 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
428 ;; DFA descriptions for the pipelines
431 (include "shmedia.md")
434 ;; Definitions for filling delay slots
436 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
438 ;; ??? This should be (nil) instead of (const_int 0)
439 (define_attr "hit_stack" "yes,no"
440 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
443 (const_string "yes")))
445 (define_attr "interrupt_function" "no,yes"
446 (const (symbol_ref "current_function_interrupt")))
448 (define_attr "in_delay_slot" "yes,no"
449 (cond [(eq_attr "type" "cbranch") (const_string "no")
450 (eq_attr "type" "pcload,pcload_si") (const_string "no")
451 (eq_attr "needs_delay_slot" "yes") (const_string "no")
452 (eq_attr "length" "2") (const_string "yes")
453 ] (const_string "no")))
455 (define_attr "cond_delay_slot" "yes,no"
456 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
457 ] (const_string "no")))
459 (define_attr "is_sfunc" ""
460 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
462 (define_attr "is_mac_media" ""
463 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
465 (define_attr "branch_zero" "yes,no"
466 (cond [(eq_attr "type" "!cbranch") (const_string "no")
467 (ne (symbol_ref "(next_active_insn (insn)\
468 == (prev_active_insn\
469 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
470 && get_attr_length (next_active_insn (insn)) == 2")
472 (const_string "yes")]
473 (const_string "no")))
475 ;; SH4 Double-precision computation with double-precision result -
476 ;; the two halves are ready at different times.
477 (define_attr "dfp_comp" "yes,no"
478 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
479 (const_string "no")))
481 ;; Insns for which the latency of a preceding fp insn is decreased by one.
482 (define_attr "late_fp_use" "yes,no" (const_string "no"))
483 ;; And feeding insns for which this relevant.
484 (define_attr "any_fp_comp" "yes,no"
485 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
486 (const_string "yes")]
487 (const_string "no")))
489 (define_attr "any_int_load" "yes,no"
490 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
491 (const_string "yes")]
492 (const_string "no")))
495 (eq_attr "needs_delay_slot" "yes")
496 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
498 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
499 ;; and thus we can't put a pop instruction in its delay slot.
500 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
501 ;; instruction can go in the delay slot.
503 ;; Since a normal return (rts) implicitly uses the PR register,
504 ;; we can't allow PR register loads in an rts delay slot.
507 (eq_attr "type" "return")
508 [(and (eq_attr "in_delay_slot" "yes")
509 (ior (and (eq_attr "interrupt_function" "no")
510 (eq_attr "type" "!pload,prset"))
511 (and (eq_attr "interrupt_function" "yes")
513 (ne (symbol_ref "TARGET_SH3") (const_int 0))
514 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
516 ;; Since a call implicitly uses the PR register, we can't allow
517 ;; a PR register store in a jsr delay slot.
520 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
521 [(and (eq_attr "in_delay_slot" "yes")
522 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
524 ;; Say that we have annulled true branches, since this gives smaller and
525 ;; faster code when branches are predicted as not taken.
527 ;; ??? The non-annulled condition should really be "in_delay_slot",
528 ;; but insns that can be filled in non-annulled get priority over insns
529 ;; that can only be filled in anulled.
532 (and (eq_attr "type" "cbranch")
533 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
534 ;; SH2e has a hardware bug that pretty much prohibits the use of
535 ;; annuled delay slots.
536 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
537 (not (eq_attr "cpu" "sh2e"))) (nil)])
539 ;; -------------------------------------------------------------------------
540 ;; SImode signed integer comparisons
541 ;; -------------------------------------------------------------------------
545 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
546 (match_operand:SI 1 "arith_operand" "K08,r"))
550 [(set_attr "type" "mt_group")])
552 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
553 ;; That would still allow reload to create cmpi instructions, but would
554 ;; perhaps allow forcing the constant into a register when that is better.
555 ;; Probably should use r0 for mem/imm compares, but force constant into a
556 ;; register for pseudo/imm compares.
558 (define_insn "cmpeqsi_t"
560 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
561 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
567 [(set_attr "type" "mt_group")])
569 (define_insn "cmpgtsi_t"
571 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
572 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
577 [(set_attr "type" "mt_group")])
579 (define_insn "cmpgesi_t"
581 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
582 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
587 [(set_attr "type" "mt_group")])
589 ;; -------------------------------------------------------------------------
590 ;; SImode unsigned integer comparisons
591 ;; -------------------------------------------------------------------------
593 (define_insn "cmpgeusi_t"
595 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
596 (match_operand:SI 1 "arith_reg_operand" "r")))]
599 [(set_attr "type" "mt_group")])
601 (define_insn "cmpgtusi_t"
603 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
604 (match_operand:SI 1 "arith_reg_operand" "r")))]
607 [(set_attr "type" "mt_group")])
609 ;; We save the compare operands in the cmpxx patterns and use them when
610 ;; we generate the branch.
612 (define_expand "cmpsi"
614 (compare (match_operand:SI 0 "cmpsi_operand" "")
615 (match_operand:SI 1 "arith_operand" "")))]
619 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
620 && GET_CODE (operands[1]) != CONST_INT)
621 operands[0] = copy_to_mode_reg (SImode, operands[0]);
622 sh_compare_op0 = operands[0];
623 sh_compare_op1 = operands[1];
627 ;; -------------------------------------------------------------------------
628 ;; DImode signed integer comparisons
629 ;; -------------------------------------------------------------------------
631 ;; ??? Could get better scheduling by splitting the initial test from the
632 ;; rest of the insn after reload. However, the gain would hardly justify
633 ;; the sh.md size increase necessary to do that.
637 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
638 (match_operand:DI 1 "arith_operand" "r"))
641 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
643 [(set_attr "length" "6")
644 (set_attr "type" "arith3b")])
646 (define_insn "cmpeqdi_t"
648 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
649 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
652 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
653 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
654 [(set_attr "length" "6")
655 (set_attr "type" "arith3b")])
659 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
660 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
661 ;; If we applied this split when not optimizing, it would only be
662 ;; applied during the machine-dependent reorg, when no new basic blocks
664 "TARGET_SH1 && reload_completed && optimize"
665 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
666 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
667 (label_ref (match_dup 6))
669 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
674 = gen_rtx_REG (SImode,
675 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
677 = (operands[1] == const0_rtx
679 : gen_rtx_REG (SImode,
680 true_regnum (operands[1])
681 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
682 operands[4] = gen_lowpart (SImode, operands[0]);
683 operands[5] = gen_lowpart (SImode, operands[1]);
684 operands[6] = gen_label_rtx ();
687 (define_insn "cmpgtdi_t"
689 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
690 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
693 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
694 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
695 [(set_attr "length" "8")
696 (set_attr "type" "arith3")])
698 (define_insn "cmpgedi_t"
700 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
701 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
704 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
706 [(set_attr "length" "8,2")
707 (set_attr "type" "arith3,mt_group")])
709 ;; -------------------------------------------------------------------------
710 ;; DImode unsigned integer comparisons
711 ;; -------------------------------------------------------------------------
713 (define_insn "cmpgeudi_t"
715 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
716 (match_operand:DI 1 "arith_reg_operand" "r")))]
718 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
719 [(set_attr "length" "8")
720 (set_attr "type" "arith3")])
722 (define_insn "cmpgtudi_t"
724 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
725 (match_operand:DI 1 "arith_reg_operand" "r")))]
727 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
728 [(set_attr "length" "8")
729 (set_attr "type" "arith3")])
731 (define_insn "cmpeqdi_media"
732 [(set (match_operand:DI 0 "register_operand" "=r")
733 (eq:DI (match_operand:DI 1 "register_operand" "%r")
734 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
737 [(set_attr "type" "cmp_media")])
739 (define_insn "cmpgtdi_media"
740 [(set (match_operand:DI 0 "register_operand" "=r")
741 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
742 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
745 [(set_attr "type" "cmp_media")])
747 (define_insn "cmpgtudi_media"
748 [(set (match_operand:DI 0 "register_operand" "=r")
749 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
750 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
752 "cmpgtu %N1, %N2, %0"
753 [(set_attr "type" "cmp_media")])
755 ;; We save the compare operands in the cmpxx patterns and use them when
756 ;; we generate the branch.
758 (define_expand "cmpdi"
760 (compare (match_operand:DI 0 "arith_operand" "")
761 (match_operand:DI 1 "arith_operand" "")))]
762 "TARGET_SH2 || TARGET_SHMEDIA"
765 sh_compare_op0 = operands[0];
766 sh_compare_op1 = operands[1];
769 ;; -------------------------------------------------------------------------
770 ;; Conditional move instructions
771 ;; -------------------------------------------------------------------------
773 ;; The insn names may seem reversed, but note that cmveq performs the move
774 ;; if op1 == 0, and cmvne does it if op1 != 0.
776 (define_insn "movdicc_false"
777 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
778 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
780 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
781 (match_operand:DI 3 "arith_reg_operand" "0")))]
784 [(set_attr "type" "arith_media")])
786 (define_insn "movdicc_true"
787 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
788 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
790 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
791 (match_operand:DI 3 "arith_reg_operand" "0")))]
794 [(set_attr "type" "arith_media")])
796 (define_expand "movdicc"
797 [(set (match_operand:DI 0 "register_operand" "")
798 (if_then_else:DI (match_operand 1 "comparison_operator" "")
799 (match_operand:DI 2 "register_operand" "")
800 (match_operand:DI 3 "register_operand" "")))]
804 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
805 && GET_MODE (sh_compare_op0) == DImode
806 && sh_compare_op1 == const0_rtx)
807 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
808 sh_compare_op0, sh_compare_op1);
816 tmp = gen_reg_rtx (DImode);
818 switch (GET_CODE (operands[1]))
821 emit_insn (gen_seq (tmp));
822 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
826 emit_insn (gen_seq (tmp));
827 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
831 emit_insn (gen_sgt (tmp));
832 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
836 emit_insn (gen_slt (tmp));
837 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
841 emit_insn (gen_slt (tmp));
842 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
846 emit_insn (gen_sgt (tmp));
847 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
851 emit_insn (gen_sgtu (tmp));
852 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
856 emit_insn (gen_sltu (tmp));
857 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
861 emit_insn (gen_sltu (tmp));
862 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
866 emit_insn (gen_sgtu (tmp));
867 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
871 emit_insn (gen_sunordered (tmp));
872 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
876 emit_insn (gen_sunordered (tmp));
877 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
894 ;; -------------------------------------------------------------------------
895 ;; Addition instructions
896 ;; -------------------------------------------------------------------------
898 (define_expand "adddi3"
899 [(set (match_operand:DI 0 "arith_reg_operand" "")
900 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
901 (match_operand:DI 2 "arith_operand" "")))]
907 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
909 operands[2] = force_reg (DImode, operands[2]);
910 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
915 (define_insn "*adddi3_media"
916 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
917 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
918 (match_operand:DI 2 "arith_operand" "r,I10")))]
923 [(set_attr "type" "arith_media")])
925 (define_insn "adddi3z_media"
926 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
928 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
929 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
932 [(set_attr "type" "arith_media")])
934 (define_insn "adddi3_compact"
935 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
936 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
937 (match_operand:DI 2 "arith_reg_operand" "r")))
938 (clobber (reg:SI T_REG))]
941 [(set_attr "length" "6")])
944 [(set (match_operand:DI 0 "arith_reg_operand" "")
945 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
946 (match_operand:DI 2 "arith_reg_operand" "")))
947 (clobber (reg:SI T_REG))]
948 "TARGET_SH1 && reload_completed"
952 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
953 high0 = gen_rtx_REG (SImode,
954 true_regnum (operands[0])
955 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
956 high2 = gen_rtx_REG (SImode,
957 true_regnum (operands[2])
958 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959 emit_insn (gen_clrt ());
960 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
961 emit_insn (gen_addc1 (high0, high0, high2));
966 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
967 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
968 (match_operand:SI 2 "arith_reg_operand" "r"))
971 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
974 [(set_attr "type" "arith")])
977 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
978 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
979 (match_operand:SI 2 "arith_reg_operand" "r"))
981 (clobber (reg:SI T_REG))]
984 [(set_attr "type" "arith")])
986 (define_expand "addsi3"
987 [(set (match_operand:SI 0 "arith_reg_operand" "")
988 (plus:SI (match_operand:SI 1 "arith_operand" "")
989 (match_operand:SI 2 "arith_operand" "")))]
994 operands[1] = force_reg (SImode, operands[1]);
997 (define_insn "addsi3_media"
998 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
999 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1000 (match_operand:SI 2 "arith_operand" "r,I10")))]
1005 [(set_attr "type" "arith_media")])
1007 (define_insn "*addsi3_compact"
1008 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1009 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1010 (match_operand:SI 2 "arith_operand" "rI08")))]
1013 [(set_attr "type" "arith")])
1015 ;; -------------------------------------------------------------------------
1016 ;; Subtraction instructions
1017 ;; -------------------------------------------------------------------------
1019 (define_expand "subdi3"
1020 [(set (match_operand:DI 0 "arith_reg_operand" "")
1021 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1022 (match_operand:DI 2 "arith_reg_operand" "")))]
1028 operands[1] = force_reg (DImode, operands[1]);
1029 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1034 (define_insn "*subdi3_media"
1035 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1036 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1037 (match_operand:DI 2 "arith_reg_operand" "r")))]
1040 [(set_attr "type" "arith_media")])
1042 (define_insn "subdi3_compact"
1043 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1044 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1045 (match_operand:DI 2 "arith_reg_operand" "r")))
1046 (clobber (reg:SI T_REG))]
1049 [(set_attr "length" "6")])
1052 [(set (match_operand:DI 0 "arith_reg_operand" "")
1053 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1054 (match_operand:DI 2 "arith_reg_operand" "")))
1055 (clobber (reg:SI T_REG))]
1056 "TARGET_SH1 && reload_completed"
1060 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1061 high0 = gen_rtx_REG (SImode,
1062 true_regnum (operands[0])
1063 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1064 high2 = gen_rtx_REG (SImode,
1065 true_regnum (operands[2])
1066 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067 emit_insn (gen_clrt ());
1068 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1069 emit_insn (gen_subc1 (high0, high0, high2));
1074 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1075 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1076 (match_operand:SI 2 "arith_reg_operand" "r"))
1079 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1084 [(set_attr "type" "arith")])
1086 (define_insn "subc1"
1087 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1088 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1089 (match_operand:SI 2 "arith_reg_operand" "r"))
1091 (clobber (reg:SI T_REG))]
1094 [(set_attr "type" "arith")])
1096 (define_insn "*subsi3_internal"
1097 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1098 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1099 (match_operand:SI 2 "arith_reg_operand" "r")))]
1102 [(set_attr "type" "arith")])
1104 (define_insn "*subsi3_media"
1105 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1106 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1107 (match_operand:SI 2 "extend_reg_operand" "r")))]
1110 [(set_attr "type" "arith_media")])
1112 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1113 ;; will sometimes save one instruction. Otherwise we might get
1114 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1117 (define_expand "subsi3"
1118 [(set (match_operand:SI 0 "arith_reg_operand" "")
1119 (minus:SI (match_operand:SI 1 "arith_operand" "")
1120 (match_operand:SI 2 "arith_reg_operand" "")))]
1124 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1126 emit_insn (gen_negsi2 (operands[0], operands[2]));
1127 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1132 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1134 if (operands[1] != const0_rtx)
1135 operands[1] = force_reg (SImode, operands[1]);
1139 ;; -------------------------------------------------------------------------
1140 ;; Division instructions
1141 ;; -------------------------------------------------------------------------
1143 ;; We take advantage of the library routines which don't clobber as many
1144 ;; registers as a normal function call would.
1146 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1147 ;; also has an effect on the register that holds the address of the sfunc.
1148 ;; To make this work, we have an extra dummy insn that shows the use
1149 ;; of this register for reorg.
1151 (define_insn "use_sfunc_addr"
1152 [(set (reg:SI PR_REG)
1153 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1154 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1156 [(set_attr "length" "0")])
1158 (define_insn "udivsi3_sh2a"
1159 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1160 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1161 (match_operand:SI 2 "arith_reg_operand" "z")))]
1164 [(set_attr "type" "arith")])
1166 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1167 ;; hard register 0. If we used hard register 0, then the next instruction
1168 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1169 ;; gets allocated to a stack slot that needs its address reloaded, then
1170 ;; there is nothing to prevent reload from using r0 to reload the address.
1171 ;; This reload would clobber the value in r0 we are trying to store.
1172 ;; If we let reload allocate r0, then this problem can never happen.
1174 (define_insn "udivsi3_i1"
1175 [(set (match_operand:SI 0 "register_operand" "=z")
1176 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1177 (clobber (reg:SI T_REG))
1178 (clobber (reg:SI PR_REG))
1179 (clobber (reg:SI R4_REG))
1180 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1181 "TARGET_SH1 && ! TARGET_SH4"
1183 [(set_attr "type" "sfunc")
1184 (set_attr "needs_delay_slot" "yes")])
1186 ; Since shmedia-nofpu code could be linked against shcompact code, and
1187 ; the udivsi3 libcall has the same name, we must consider all registers
1188 ; clobbered that are in the union of the registers clobbered by the
1189 ; shmedia and the shcompact implementation. Note, if the shcompact
1190 ; implementation actually used shcompact code, we'd need to clobber
1191 ; also r23 and fr23.
1192 (define_insn "udivsi3_i1_media"
1193 [(set (match_operand:SI 0 "register_operand" "=z")
1194 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1195 (clobber (reg:SI T_MEDIA_REG))
1196 (clobber (reg:SI PR_MEDIA_REG))
1197 (clobber (reg:SI R20_REG))
1198 (clobber (reg:SI R21_REG))
1199 (clobber (reg:SI R22_REG))
1200 (clobber (reg:DI TR0_REG))
1201 (clobber (reg:DI TR1_REG))
1202 (clobber (reg:DI TR2_REG))
1203 (use (match_operand:DI 1 "target_operand" "b"))]
1204 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1206 [(set_attr "type" "sfunc")
1207 (set_attr "needs_delay_slot" "yes")])
1209 (define_expand "udivsi3_i4_media"
1211 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1213 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1214 (set (match_dup 5) (float:DF (match_dup 3)))
1215 (set (match_dup 6) (float:DF (match_dup 4)))
1216 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1217 (set (match_dup 8) (fix:DI (match_dup 7)))
1218 (set (match_operand:SI 0 "register_operand" "")
1219 (truncate:SI (match_dup 8)))]
1220 "TARGET_SHMEDIA_FPU"
1223 operands[3] = gen_reg_rtx (DImode);
1224 operands[4] = gen_reg_rtx (DImode);
1225 operands[5] = gen_reg_rtx (DFmode);
1226 operands[6] = gen_reg_rtx (DFmode);
1227 operands[7] = gen_reg_rtx (DFmode);
1228 operands[8] = gen_reg_rtx (DImode);
1231 (define_insn "udivsi3_i4"
1232 [(set (match_operand:SI 0 "register_operand" "=y")
1233 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1234 (clobber (reg:SI T_REG))
1235 (clobber (reg:SI PR_REG))
1236 (clobber (reg:DF DR0_REG))
1237 (clobber (reg:DF DR2_REG))
1238 (clobber (reg:DF DR4_REG))
1239 (clobber (reg:SI R0_REG))
1240 (clobber (reg:SI R1_REG))
1241 (clobber (reg:SI R4_REG))
1242 (clobber (reg:SI R5_REG))
1243 (use (reg:PSI FPSCR_REG))
1244 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1245 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1247 [(set_attr "type" "sfunc")
1248 (set_attr "fp_mode" "double")
1249 (set_attr "needs_delay_slot" "yes")])
1251 (define_insn "udivsi3_i4_single"
1252 [(set (match_operand:SI 0 "register_operand" "=y")
1253 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1254 (clobber (reg:SI T_REG))
1255 (clobber (reg:SI PR_REG))
1256 (clobber (reg:DF DR0_REG))
1257 (clobber (reg:DF DR2_REG))
1258 (clobber (reg:DF DR4_REG))
1259 (clobber (reg:SI R0_REG))
1260 (clobber (reg:SI R1_REG))
1261 (clobber (reg:SI R4_REG))
1262 (clobber (reg:SI R5_REG))
1263 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1264 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1266 [(set_attr "type" "sfunc")
1267 (set_attr "needs_delay_slot" "yes")])
1269 (define_expand "udivsi3"
1270 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1271 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1272 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1273 (parallel [(set (match_operand:SI 0 "register_operand" "")
1274 (udiv:SI (reg:SI R4_REG)
1276 (clobber (reg:SI T_REG))
1277 (clobber (reg:SI PR_REG))
1278 (clobber (reg:SI R4_REG))
1279 (use (match_dup 3))])]
1285 operands[3] = gen_reg_rtx (Pmode);
1286 /* Emit the move of the address to a pseudo outside of the libcall. */
1287 if (TARGET_HARD_SH4 && TARGET_SH2E)
1289 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1290 if (TARGET_FPU_SINGLE)
1291 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1293 last = gen_udivsi3_i4 (operands[0], operands[3]);
1295 else if (TARGET_SHMEDIA_FPU)
1297 operands[1] = force_reg (SImode, operands[1]);
1298 operands[2] = force_reg (SImode, operands[2]);
1299 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1302 else if (TARGET_SH2A)
1304 operands[1] = force_reg (SImode, operands[1]);
1305 operands[2] = force_reg (SImode, operands[2]);
1306 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1309 else if (TARGET_SH5)
1311 emit_move_insn (operands[3],
1312 function_symbol (TARGET_FPU_ANY
1317 last = gen_udivsi3_i1_media (operands[0],
1320 : gen_rtx_SUBREG (DImode, operands[3],
1322 else if (TARGET_FPU_ANY)
1323 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1325 last = gen_udivsi3_i1 (operands[0], operands[3]);
1329 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1330 last = gen_udivsi3_i1 (operands[0], operands[3]);
1332 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1333 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1334 last = emit_insn (last);
1335 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1336 invariant code motion can move it. */
1337 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1338 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1342 (define_insn "divsi3_sh2a"
1343 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1344 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1345 (match_operand:SI 2 "arith_reg_operand" "z")))]
1348 [(set_attr "type" "arith")])
1350 (define_insn "divsi3_i1"
1351 [(set (match_operand:SI 0 "register_operand" "=z")
1352 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1353 (clobber (reg:SI T_REG))
1354 (clobber (reg:SI PR_REG))
1355 (clobber (reg:SI R1_REG))
1356 (clobber (reg:SI R2_REG))
1357 (clobber (reg:SI R3_REG))
1358 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1359 "TARGET_SH1 && ! TARGET_SH4"
1361 [(set_attr "type" "sfunc")
1362 (set_attr "needs_delay_slot" "yes")])
1364 ; Since shmedia-nofpu code could be linked against shcompact code, and
1365 ; the sdivsi3 libcall has the same name, we must consider all registers
1366 ; clobbered that are in the union of the registers clobbered by the
1367 ; shmedia and the shcompact implementation. Note, if the shcompact
1368 ; implementation actually used shcompact code, we'd need to clobber
1369 ; also r22, r23 and fr23.
1370 (define_insn "divsi3_i1_media"
1371 [(set (match_operand:SI 0 "register_operand" "=z")
1372 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1373 (clobber (reg:SI T_MEDIA_REG))
1374 (clobber (reg:SI PR_MEDIA_REG))
1375 (clobber (reg:SI R1_REG))
1376 (clobber (reg:SI R2_REG))
1377 (clobber (reg:SI R3_REG))
1378 (clobber (reg:SI R20_REG))
1379 (clobber (reg:SI R21_REG))
1380 (clobber (reg:DI TR0_REG))
1381 (clobber (reg:DI TR1_REG))
1382 (clobber (reg:DI TR2_REG))
1383 (use (match_operand:DI 1 "target_operand" "b"))]
1384 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1386 [(set_attr "type" "sfunc")])
1388 (define_expand "divsi3_i4_media"
1389 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1390 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1391 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1392 (set (match_operand:SI 0 "register_operand" "=r")
1393 (fix:SI (match_dup 5)))]
1394 "TARGET_SHMEDIA_FPU"
1397 operands[3] = gen_reg_rtx (DFmode);
1398 operands[4] = gen_reg_rtx (DFmode);
1399 operands[5] = gen_reg_rtx (DFmode);
1402 (define_insn "divsi3_i4"
1403 [(set (match_operand:SI 0 "register_operand" "=y")
1404 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1405 (clobber (reg:SI PR_REG))
1406 (clobber (reg:DF DR0_REG))
1407 (clobber (reg:DF DR2_REG))
1408 (use (reg:PSI FPSCR_REG))
1409 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1410 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1412 [(set_attr "type" "sfunc")
1413 (set_attr "fp_mode" "double")
1414 (set_attr "needs_delay_slot" "yes")])
1416 (define_insn "divsi3_i4_single"
1417 [(set (match_operand:SI 0 "register_operand" "=y")
1418 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419 (clobber (reg:SI PR_REG))
1420 (clobber (reg:DF DR0_REG))
1421 (clobber (reg:DF DR2_REG))
1422 (clobber (reg:SI R2_REG))
1423 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1424 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1426 [(set_attr "type" "sfunc")
1427 (set_attr "needs_delay_slot" "yes")])
1429 (define_expand "divsi3"
1430 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1431 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1432 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1433 (parallel [(set (match_operand:SI 0 "register_operand" "")
1434 (div:SI (reg:SI R4_REG)
1436 (clobber (reg:SI T_REG))
1437 (clobber (reg:SI PR_REG))
1438 (clobber (reg:SI R1_REG))
1439 (clobber (reg:SI R2_REG))
1440 (clobber (reg:SI R3_REG))
1441 (use (match_dup 3))])]
1447 operands[3] = gen_reg_rtx (Pmode);
1448 /* Emit the move of the address to a pseudo outside of the libcall. */
1449 if (TARGET_HARD_SH4 && TARGET_SH2E)
1451 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1452 if (TARGET_FPU_SINGLE)
1453 last = gen_divsi3_i4_single (operands[0], operands[3]);
1455 last = gen_divsi3_i4 (operands[0], operands[3]);
1457 else if (TARGET_SH2A)
1459 operands[1] = force_reg (SImode, operands[1]);
1460 operands[2] = force_reg (SImode, operands[2]);
1461 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1464 else if (TARGET_SHMEDIA_FPU)
1466 operands[1] = force_reg (SImode, operands[1]);
1467 operands[2] = force_reg (SImode, operands[2]);
1468 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1471 else if (TARGET_SH5)
1473 emit_move_insn (operands[3],
1474 function_symbol (TARGET_FPU_ANY
1479 last = gen_divsi3_i1_media (operands[0],
1482 : gen_rtx_SUBREG (DImode, operands[3],
1484 else if (TARGET_FPU_ANY)
1485 last = gen_divsi3_i4_single (operands[0], operands[3]);
1487 last = gen_divsi3_i1 (operands[0], operands[3]);
1491 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1492 last = gen_divsi3_i1 (operands[0], operands[3]);
1494 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1495 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1496 last = emit_insn (last);
1497 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1498 invariant code motion can move it. */
1499 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1500 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1504 ;; -------------------------------------------------------------------------
1505 ;; Multiplication instructions
1506 ;; -------------------------------------------------------------------------
1508 (define_insn "umulhisi3_i"
1509 [(set (reg:SI MACL_REG)
1510 (mult:SI (zero_extend:SI
1511 (match_operand:HI 0 "arith_reg_operand" "r"))
1513 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1516 [(set_attr "type" "smpy")])
1518 (define_insn "mulhisi3_i"
1519 [(set (reg:SI MACL_REG)
1520 (mult:SI (sign_extend:SI
1521 (match_operand:HI 0 "arith_reg_operand" "r"))
1523 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1526 [(set_attr "type" "smpy")])
1528 (define_expand "mulhisi3"
1529 [(set (reg:SI MACL_REG)
1530 (mult:SI (sign_extend:SI
1531 (match_operand:HI 1 "arith_reg_operand" ""))
1533 (match_operand:HI 2 "arith_reg_operand" ""))))
1534 (set (match_operand:SI 0 "arith_reg_operand" "")
1541 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1542 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1543 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1544 invariant code motion can move it. */
1545 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1546 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1547 /* expand_binop can't find a suitable code in umul_widen_optab to
1548 make a REG_EQUAL note from, so make one here.
1549 See also smulsi3_highpart.
1550 ??? Alternatively, we could put this at the calling site of expand_binop,
1551 i.e. expand_expr. */
1553 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1558 (define_expand "umulhisi3"
1559 [(set (reg:SI MACL_REG)
1560 (mult:SI (zero_extend:SI
1561 (match_operand:HI 1 "arith_reg_operand" ""))
1563 (match_operand:HI 2 "arith_reg_operand" ""))))
1564 (set (match_operand:SI 0 "arith_reg_operand" "")
1571 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1572 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1573 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1574 invariant code motion can move it. */
1575 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1576 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1577 /* expand_binop can't find a suitable code in umul_widen_optab to
1578 make a REG_EQUAL note from, so make one here.
1579 See also smulsi3_highpart.
1580 ??? Alternatively, we could put this at the calling site of expand_binop,
1581 i.e. expand_expr. */
1583 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1588 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1589 ;; a call to a routine which clobbers known registers.
1592 [(set (match_operand:SI 1 "register_operand" "=z")
1593 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1594 (clobber (reg:SI MACL_REG))
1595 (clobber (reg:SI T_REG))
1596 (clobber (reg:SI PR_REG))
1597 (clobber (reg:SI R3_REG))
1598 (clobber (reg:SI R2_REG))
1599 (clobber (reg:SI R1_REG))
1600 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1603 [(set_attr "type" "sfunc")
1604 (set_attr "needs_delay_slot" "yes")])
1606 (define_expand "mulsi3_call"
1607 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1608 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1609 (parallel[(set (match_operand:SI 0 "register_operand" "")
1610 (mult:SI (reg:SI R4_REG)
1612 (clobber (reg:SI MACL_REG))
1613 (clobber (reg:SI T_REG))
1614 (clobber (reg:SI PR_REG))
1615 (clobber (reg:SI R3_REG))
1616 (clobber (reg:SI R2_REG))
1617 (clobber (reg:SI R1_REG))
1618 (use (match_operand:SI 3 "register_operand" ""))])]
1622 (define_insn "mul_r"
1623 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1624 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1625 (match_operand:SI 2 "arith_reg_operand" "z")))]
1628 [(set_attr "type" "dmpy")])
1630 (define_insn "mul_l"
1631 [(set (reg:SI MACL_REG)
1632 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1633 (match_operand:SI 1 "arith_reg_operand" "r")))]
1636 [(set_attr "type" "dmpy")])
1638 (define_expand "mulsi3"
1639 [(set (reg:SI MACL_REG)
1640 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1641 (match_operand:SI 2 "arith_reg_operand" "")))
1642 (set (match_operand:SI 0 "arith_reg_operand" "")
1651 /* The address must be set outside the libcall,
1652 since it goes into a pseudo. */
1653 rtx sym = function_symbol (\"__mulsi3\");
1654 rtx addr = force_reg (SImode, sym);
1655 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1658 last = emit_insn (insns);
1662 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1664 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1665 /* consec_sets_giv can only recognize the first insn that sets a
1666 giv as the giv insn. So we must tag this also with a REG_EQUAL
1668 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1670 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1671 invariant code motion can move it. */
1672 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1673 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1677 (define_insn "mulsidi3_i"
1678 [(set (reg:SI MACH_REG)
1682 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1683 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1685 (set (reg:SI MACL_REG)
1686 (mult:SI (match_dup 0)
1690 [(set_attr "type" "dmpy")])
1692 (define_expand "mulsidi3"
1693 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1694 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1695 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1696 "TARGET_SH2 || TARGET_SHMEDIA"
1701 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1707 (define_insn "mulsidi3_media"
1708 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1709 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1710 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1713 [(set_attr "type" "dmpy_media")])
1715 (define_insn "mulsidi3_compact"
1716 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1718 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1719 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1720 (clobber (reg:SI MACH_REG))
1721 (clobber (reg:SI MACL_REG))]
1726 [(set (match_operand:DI 0 "arith_reg_operand" "")
1728 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1729 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1730 (clobber (reg:SI MACH_REG))
1731 (clobber (reg:SI MACL_REG))]
1736 rtx low_dst = gen_lowpart (SImode, operands[0]);
1737 rtx high_dst = gen_highpart (SImode, operands[0]);
1739 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1741 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1742 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1743 /* We need something to tag the possible REG_EQUAL notes on to. */
1744 emit_move_insn (operands[0], operands[0]);
1748 (define_insn "umulsidi3_i"
1749 [(set (reg:SI MACH_REG)
1753 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1754 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1756 (set (reg:SI MACL_REG)
1757 (mult:SI (match_dup 0)
1761 [(set_attr "type" "dmpy")])
1763 (define_expand "umulsidi3"
1764 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1766 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1767 "TARGET_SH2 || TARGET_SHMEDIA"
1772 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1778 (define_insn "umulsidi3_media"
1779 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1780 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1781 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1784 [(set_attr "type" "dmpy_media")])
1786 (define_insn "umulsidi3_compact"
1787 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1789 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1790 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1791 (clobber (reg:SI MACH_REG))
1792 (clobber (reg:SI MACL_REG))]
1797 [(set (match_operand:DI 0 "arith_reg_operand" "")
1798 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1799 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1800 (clobber (reg:SI MACH_REG))
1801 (clobber (reg:SI MACL_REG))]
1806 rtx low_dst = gen_lowpart (SImode, operands[0]);
1807 rtx high_dst = gen_highpart (SImode, operands[0]);
1809 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1811 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1812 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1813 /* We need something to tag the possible REG_EQUAL notes on to. */
1814 emit_move_insn (operands[0], operands[0]);
1818 (define_insn "smulsi3_highpart_i"
1819 [(set (reg:SI MACH_REG)
1823 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1824 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1826 (clobber (reg:SI MACL_REG))]
1829 [(set_attr "type" "dmpy")])
1831 (define_expand "smulsi3_highpart"
1833 [(set (reg:SI MACH_REG)
1837 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1838 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1840 (clobber (reg:SI MACL_REG))])
1841 (set (match_operand:SI 0 "arith_reg_operand" "")
1848 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1849 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1850 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1851 invariant code motion can move it. */
1852 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1853 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1854 /* expand_binop can't find a suitable code in mul_highpart_optab to
1855 make a REG_EQUAL note from, so make one here.
1856 See also {,u}mulhisi.
1857 ??? Alternatively, we could put this at the calling site of expand_binop,
1858 i.e. expand_mult_highpart. */
1860 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1865 (define_insn "umulsi3_highpart_i"
1866 [(set (reg:SI MACH_REG)
1870 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1871 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1873 (clobber (reg:SI MACL_REG))]
1876 [(set_attr "type" "dmpy")])
1878 (define_expand "umulsi3_highpart"
1880 [(set (reg:SI MACH_REG)
1884 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1885 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1887 (clobber (reg:SI MACL_REG))])
1888 (set (match_operand:SI 0 "arith_reg_operand" "")
1895 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1896 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1897 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1898 invariant code motion can move it. */
1899 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1900 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1904 ;; -------------------------------------------------------------------------
1905 ;; Logical operations
1906 ;; -------------------------------------------------------------------------
1908 (define_insn "*andsi3_compact"
1909 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1910 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1911 (match_operand:SI 2 "logical_operand" "r,K08")))]
1914 [(set_attr "type" "arith")])
1916 ;; If the constant is 255, then emit an extu.b instruction instead of an
1917 ;; and, since that will give better code.
1919 (define_expand "andsi3"
1920 [(set (match_operand:SI 0 "arith_reg_operand" "")
1921 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1922 (match_operand:SI 2 "logical_operand" "")))]
1926 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1928 emit_insn (gen_zero_extendqisi2 (operands[0],
1929 gen_lowpart (QImode, operands[1])));
1934 (define_insn_and_split "anddi3"
1935 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1936 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1937 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1944 && ! logical_operand (operands[2], DImode)"
1948 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1949 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1951 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1954 [(set_attr "type" "arith_media")])
1956 (define_insn "andcdi3"
1957 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1958 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1959 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1962 [(set_attr "type" "arith_media")])
1964 (define_insn "iorsi3"
1965 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967 (match_operand:SI 2 "logical_operand" "r,K08")))]
1970 [(set_attr "type" "arith")])
1972 (define_insn "iordi3"
1973 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1974 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1975 (match_operand:DI 2 "logical_operand" "r,I10")))]
1980 [(set_attr "type" "arith_media")])
1982 (define_insn "xorsi3"
1983 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1984 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1985 (match_operand:SI 2 "logical_operand" "K08,r")))]
1988 [(set_attr "type" "arith")])
1990 (define_insn "xordi3"
1991 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1992 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1993 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1998 [(set_attr "type" "arith_media")])
2000 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2001 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2003 [(set (match_operand:DI 0 "arith_reg_operand" "")
2004 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2005 [(match_operand 1 "any_register_operand" "")
2006 (match_operand 2 "any_register_operand" "")])))]
2008 [(set (match_dup 5) (match_dup 4))
2009 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2012 enum machine_mode inmode = GET_MODE (operands[1]);
2015 if (GET_CODE (operands[0]) == SUBREG)
2017 offset = SUBREG_BYTE (operands[0]);
2018 operands[0] = SUBREG_REG (operands[0]);
2020 if (GET_CODE (operands[0]) != REG)
2022 if (! TARGET_LITTLE_ENDIAN)
2023 offset += 8 - GET_MODE_SIZE (inmode);
2024 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2027 ;; -------------------------------------------------------------------------
2028 ;; Shifts and rotates
2029 ;; -------------------------------------------------------------------------
2031 (define_expand "rotldi3"
2032 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2033 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2034 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2036 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2038 (define_insn "rotldi3_mextr"
2039 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2040 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2041 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2045 static char templ[16];
2047 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2048 8 - (int) (INTVAL (operands[2]) >> 3));
2051 [(set_attr "type" "arith_media")])
2053 (define_expand "rotrdi3"
2054 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2055 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2056 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2058 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2060 (define_insn "rotrdi3_mextr"
2061 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2062 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2063 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2067 static char templ[16];
2069 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2072 [(set_attr "type" "arith_media")])
2074 (define_insn "rotlsi3_1"
2075 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2076 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2079 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2082 [(set_attr "type" "arith")])
2084 (define_insn "rotlsi3_31"
2085 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2086 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2088 (clobber (reg:SI T_REG))]
2091 [(set_attr "type" "arith")])
2093 (define_insn "rotlsi3_16"
2094 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2095 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2099 [(set_attr "type" "arith")])
2101 (define_expand "rotlsi3"
2102 [(set (match_operand:SI 0 "arith_reg_operand" "")
2103 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2104 (match_operand:SI 2 "immediate_operand" "")))]
2108 static const char rot_tab[] = {
2109 000, 000, 000, 000, 000, 000, 010, 001,
2110 001, 001, 011, 013, 003, 003, 003, 003,
2111 003, 003, 003, 003, 003, 013, 012, 002,
2112 002, 002, 010, 000, 000, 000, 000, 000,
2117 if (GET_CODE (operands[2]) != CONST_INT)
2119 count = INTVAL (operands[2]);
2120 choice = rot_tab[count];
2121 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2127 emit_move_insn (operands[0], operands[1]);
2128 count -= (count & 16) * 2;
2131 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2138 parts[0] = gen_reg_rtx (SImode);
2139 parts[1] = gen_reg_rtx (SImode);
2140 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2141 emit_move_insn (parts[choice-1], operands[1]);
2142 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2143 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2144 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2145 count = (count & ~16) - 8;
2149 for (; count > 0; count--)
2150 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2151 for (; count < 0; count++)
2152 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2157 (define_insn "*rotlhi3_8"
2158 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2159 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2163 [(set_attr "type" "arith")])
2165 (define_expand "rotlhi3"
2166 [(set (match_operand:HI 0 "arith_reg_operand" "")
2167 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2168 (match_operand:HI 2 "immediate_operand" "")))]
2172 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2179 (define_insn "ashlsi3_sh2a"
2180 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2181 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2182 (match_operand:SI 2 "arith_reg_operand" "r")))]
2185 [(set_attr "type" "arith")
2186 (set_attr "length" "4")])
2188 ;; This pattern is used by init_expmed for computing the costs of shift
2191 (define_insn_and_split "ashlsi3_std"
2192 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2193 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2194 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2195 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2197 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2198 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2206 && GET_CODE (operands[2]) == CONST_INT
2207 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2208 [(set (match_dup 3) (match_dup 2))
2210 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2211 (clobber (match_dup 4))])]
2212 "operands[4] = gen_rtx_SCRATCH (SImode);"
2213 [(set_attr "length" "*,*,*,4")
2214 (set_attr "type" "dyn_shift,arith,arith,arith")])
2216 (define_insn "ashlhi3_k"
2217 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2218 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2219 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2220 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2224 [(set_attr "type" "arith")])
2226 (define_insn "ashlsi3_n"
2227 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2228 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2229 (match_operand:SI 2 "const_int_operand" "n")))
2230 (clobber (reg:SI T_REG))]
2231 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2233 [(set (attr "length")
2234 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2236 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2238 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2240 (const_string "8")))
2241 (set_attr "type" "arith")])
2244 [(set (match_operand:SI 0 "arith_reg_operand" "")
2245 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2246 (match_operand:SI 2 "const_int_operand" "")))
2247 (clobber (reg:SI T_REG))]
2248 "TARGET_SH1 && reload_completed"
2249 [(use (reg:SI R0_REG))]
2252 gen_shifty_op (ASHIFT, operands);
2256 (define_insn "ashlsi3_media"
2257 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2258 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2259 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2264 [(set_attr "type" "arith_media")])
2266 (define_expand "ashlsi3"
2267 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2268 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2269 (match_operand:SI 2 "nonmemory_operand" "")))
2270 (clobber (reg:SI T_REG))])]
2276 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2279 if (GET_CODE (operands[2]) == CONST_INT
2280 && sh_dynamicalize_shift_p (operands[2]))
2281 operands[2] = force_reg (SImode, operands[2]);
2284 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2287 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2291 (define_insn "ashlhi3"
2292 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2293 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2294 (match_operand:HI 2 "const_int_operand" "n")))
2295 (clobber (reg:SI T_REG))]
2298 [(set (attr "length")
2299 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2301 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2303 (const_string "6")))
2304 (set_attr "type" "arith")])
2307 [(set (match_operand:HI 0 "arith_reg_operand" "")
2308 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2309 (match_operand:HI 2 "const_int_operand" "")))
2310 (clobber (reg:SI T_REG))]
2311 "TARGET_SH1 && reload_completed"
2312 [(use (reg:SI R0_REG))]
2315 gen_shifty_hi_op (ASHIFT, operands);
2320 ; arithmetic shift right
2323 (define_insn "ashrsi3_sh2a"
2324 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2325 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2326 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2329 [(set_attr "type" "dyn_shift")
2330 (set_attr "length" "4")])
2332 (define_insn "ashrsi3_k"
2333 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2334 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2335 (match_operand:SI 2 "const_int_operand" "M")))
2336 (clobber (reg:SI T_REG))]
2337 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2339 [(set_attr "type" "arith")])
2341 ;; We can't do HImode right shifts correctly unless we start out with an
2342 ;; explicit zero / sign extension; doing that would result in worse overall
2343 ;; code, so just let the machine independent code widen the mode.
2344 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2347 ;; ??? This should be a define expand.
2349 (define_insn "ashrsi2_16"
2350 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2351 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2355 [(set_attr "length" "4")])
2358 [(set (match_operand:SI 0 "arith_reg_operand" "")
2359 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2362 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2363 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2364 "operands[2] = gen_lowpart (HImode, operands[0]);")
2366 ;; ??? This should be a define expand.
2368 (define_insn "ashrsi2_31"
2369 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2370 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2372 (clobber (reg:SI T_REG))]
2375 [(set_attr "length" "4")])
2378 [(set (match_operand:SI 0 "arith_reg_operand" "")
2379 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2381 (clobber (reg:SI T_REG))]
2386 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2387 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2391 (define_insn "ashlsi_c"
2392 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2393 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2395 (lt:SI (match_dup 1) (const_int 0)))]
2398 [(set_attr "type" "arith")])
2400 (define_insn "ashrsi3_d"
2401 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2402 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2403 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2406 [(set_attr "type" "dyn_shift")])
2408 (define_insn "ashrsi3_n"
2409 [(set (reg:SI R4_REG)
2410 (ashiftrt:SI (reg:SI R4_REG)
2411 (match_operand:SI 0 "const_int_operand" "i")))
2412 (clobber (reg:SI T_REG))
2413 (clobber (reg:SI PR_REG))
2414 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2417 [(set_attr "type" "sfunc")
2418 (set_attr "needs_delay_slot" "yes")])
2420 (define_insn "ashrsi3_media"
2421 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2422 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2423 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2428 [(set_attr "type" "arith_media")])
2430 (define_expand "ashrsi3"
2431 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2432 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2433 (match_operand:SI 2 "nonmemory_operand" "")))
2434 (clobber (reg:SI T_REG))])]
2440 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2443 if (expand_ashiftrt (operands))
2449 ;; logical shift right
2451 (define_insn "lshrsi3_sh2a"
2452 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2453 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2454 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2457 [(set_attr "type" "dyn_shift")
2458 (set_attr "length" "4")])
2460 (define_insn "lshrsi3_d"
2461 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2462 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2463 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2466 [(set_attr "type" "dyn_shift")])
2468 ;; Only the single bit shift clobbers the T bit.
2470 (define_insn "lshrsi3_m"
2471 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2472 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2473 (match_operand:SI 2 "const_int_operand" "M")))
2474 (clobber (reg:SI T_REG))]
2475 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2477 [(set_attr "type" "arith")])
2479 (define_insn "lshrsi3_k"
2480 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2481 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2482 (match_operand:SI 2 "const_int_operand" "P27")))]
2483 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2484 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2486 [(set_attr "type" "arith")])
2488 (define_insn "lshrsi3_n"
2489 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2490 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2491 (match_operand:SI 2 "const_int_operand" "n")))
2492 (clobber (reg:SI T_REG))]
2493 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2495 [(set (attr "length")
2496 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2498 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2500 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2502 (const_string "8")))
2503 (set_attr "type" "arith")])
2506 [(set (match_operand:SI 0 "arith_reg_operand" "")
2507 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2508 (match_operand:SI 2 "const_int_operand" "")))
2509 (clobber (reg:SI T_REG))]
2510 "TARGET_SH1 && reload_completed"
2511 [(use (reg:SI R0_REG))]
2514 gen_shifty_op (LSHIFTRT, operands);
2518 (define_insn "lshrsi3_media"
2519 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2520 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2521 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2526 [(set_attr "type" "arith_media")])
2528 (define_expand "lshrsi3"
2529 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2530 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2531 (match_operand:SI 2 "nonmemory_operand" "")))
2532 (clobber (reg:SI T_REG))])]
2538 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2541 if (GET_CODE (operands[2]) == CONST_INT
2542 && sh_dynamicalize_shift_p (operands[2]))
2543 operands[2] = force_reg (SImode, operands[2]);
2544 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2546 rtx count = copy_to_mode_reg (SImode, operands[2]);
2547 emit_insn (gen_negsi2 (count, count));
2548 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2551 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2555 ;; ??? This should be a define expand.
2557 (define_insn "ashldi3_k"
2558 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2559 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2561 (clobber (reg:SI T_REG))]
2563 "shll %R0\;rotcl %S0"
2564 [(set_attr "length" "4")
2565 (set_attr "type" "arith")])
2567 (define_insn "ashldi3_media"
2568 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2569 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2570 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2575 [(set_attr "type" "arith_media")])
2577 (define_expand "ashldi3"
2578 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2579 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2580 (match_operand:DI 2 "immediate_operand" "")))
2581 (clobber (reg:SI T_REG))])]
2587 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2590 if (GET_CODE (operands[2]) != CONST_INT
2591 || INTVAL (operands[2]) != 1)
2595 ;; ??? This should be a define expand.
2597 (define_insn "lshrdi3_k"
2598 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2599 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2601 (clobber (reg:SI T_REG))]
2603 "shlr %S0\;rotcr %R0"
2604 [(set_attr "length" "4")
2605 (set_attr "type" "arith")])
2607 (define_insn "lshrdi3_media"
2608 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2609 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2610 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2615 [(set_attr "type" "arith_media")])
2617 (define_expand "lshrdi3"
2618 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2619 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2620 (match_operand:DI 2 "immediate_operand" "")))
2621 (clobber (reg:SI T_REG))])]
2627 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2630 if (GET_CODE (operands[2]) != CONST_INT
2631 || INTVAL (operands[2]) != 1)
2635 ;; ??? This should be a define expand.
2637 (define_insn "ashrdi3_k"
2638 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2639 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2641 (clobber (reg:SI T_REG))]
2643 "shar %S0\;rotcr %R0"
2644 [(set_attr "length" "4")
2645 (set_attr "type" "arith")])
2647 (define_insn "ashrdi3_media"
2648 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2649 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2650 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2655 [(set_attr "type" "arith_media")])
2657 (define_expand "ashrdi3"
2658 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2659 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2660 (match_operand:DI 2 "immediate_operand" "")))
2661 (clobber (reg:SI T_REG))])]
2667 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2670 if (GET_CODE (operands[2]) != CONST_INT
2671 || INTVAL (operands[2]) != 1)
2675 ;; combined left/right shift
2678 [(set (match_operand:SI 0 "register_operand" "")
2679 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2680 (match_operand:SI 2 "const_int_operand" ""))
2681 (match_operand:SI 3 "const_int_operand" "")))]
2682 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2683 [(use (reg:SI R0_REG))]
2684 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2688 [(set (match_operand:SI 0 "register_operand" "")
2689 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2690 (match_operand:SI 2 "const_int_operand" ""))
2691 (match_operand:SI 3 "const_int_operand" "")))
2692 (clobber (reg:SI T_REG))]
2693 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2694 [(use (reg:SI R0_REG))]
2695 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2699 [(set (match_operand:SI 0 "register_operand" "=r")
2700 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2701 (match_operand:SI 2 "const_int_operand" "n"))
2702 (match_operand:SI 3 "const_int_operand" "n")))
2703 (clobber (reg:SI T_REG))]
2704 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2706 [(set (attr "length")
2707 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2709 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2711 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2713 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2715 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2717 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2719 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2720 (const_string "16")]
2721 (const_string "18")))
2722 (set_attr "type" "arith")])
2725 [(set (match_operand:SI 0 "register_operand" "=z")
2726 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2727 (match_operand:SI 2 "const_int_operand" "n"))
2728 (match_operand:SI 3 "const_int_operand" "n")))
2729 (clobber (reg:SI T_REG))]
2730 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2732 [(set (attr "length")
2733 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2737 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2739 (const_string "10")))
2740 (set_attr "type" "arith")])
2742 ;; shift left / and combination with a scratch register: The combine pass
2743 ;; does not accept the individual instructions, even though they are
2744 ;; cheap. But it needs a precise description so that it is usable after
2746 (define_insn "and_shl_scratch"
2747 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2751 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2752 (match_operand:SI 2 "const_int_operand" "N,n"))
2753 (match_operand:SI 3 "" "0,r"))
2754 (match_operand:SI 4 "const_int_operand" "n,n"))
2755 (match_operand:SI 5 "const_int_operand" "n,n")))
2756 (clobber (reg:SI T_REG))]
2759 [(set (attr "length")
2760 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2762 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2764 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2766 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2767 (const_string "10")]
2768 (const_string "12")))
2769 (set_attr "type" "arith")])
2772 [(set (match_operand:SI 0 "register_operand" "")
2776 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2777 (match_operand:SI 2 "const_int_operand" ""))
2778 (match_operand:SI 3 "register_operand" ""))
2779 (match_operand:SI 4 "const_int_operand" ""))
2780 (match_operand:SI 5 "const_int_operand" "")))
2781 (clobber (reg:SI T_REG))]
2783 [(use (reg:SI R0_REG))]
2786 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2788 if (INTVAL (operands[2]))
2790 gen_shifty_op (LSHIFTRT, operands);
2792 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2793 operands[2] = operands[4];
2794 gen_shifty_op (ASHIFT, operands);
2795 if (INTVAL (operands[5]))
2797 operands[2] = operands[5];
2798 gen_shifty_op (LSHIFTRT, operands);
2803 ;; signed left/right shift combination.
2805 [(set (match_operand:SI 0 "register_operand" "")
2807 (ashift:SI (match_operand:SI 1 "register_operand" "")
2808 (match_operand:SI 2 "const_int_operand" ""))
2809 (match_operand:SI 3 "const_int_operand" "")
2811 (clobber (reg:SI T_REG))]
2813 [(use (reg:SI R0_REG))]
2814 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2817 (define_insn "shl_sext_ext"
2818 [(set (match_operand:SI 0 "register_operand" "=r")
2820 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2821 (match_operand:SI 2 "const_int_operand" "n"))
2822 (match_operand:SI 3 "const_int_operand" "n")
2824 (clobber (reg:SI T_REG))]
2825 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2827 [(set (attr "length")
2828 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2830 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2832 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2834 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2836 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2838 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2840 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2842 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2843 (const_string "16")]
2844 (const_string "18")))
2845 (set_attr "type" "arith")])
2847 (define_insn "shl_sext_sub"
2848 [(set (match_operand:SI 0 "register_operand" "=z")
2850 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2851 (match_operand:SI 2 "const_int_operand" "n"))
2852 (match_operand:SI 3 "const_int_operand" "n")
2854 (clobber (reg:SI T_REG))]
2855 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2857 [(set (attr "length")
2858 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2860 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2862 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2864 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2865 (const_string "12")]
2866 (const_string "14")))
2867 (set_attr "type" "arith")])
2869 ;; These patterns are found in expansions of DImode shifts by 16, and
2870 ;; allow the xtrct instruction to be generated from C source.
2872 (define_insn "xtrct_left"
2873 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2874 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2876 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2880 [(set_attr "type" "arith")])
2882 (define_insn "xtrct_right"
2883 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2884 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2886 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2890 [(set_attr "type" "arith")])
2892 ;; -------------------------------------------------------------------------
2894 ;; -------------------------------------------------------------------------
2897 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898 (neg:SI (plus:SI (reg:SI T_REG)
2899 (match_operand:SI 1 "arith_reg_operand" "r"))))
2901 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2905 [(set_attr "type" "arith")])
2907 (define_insn "*negdi_media"
2908 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2909 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2912 [(set_attr "type" "arith_media")])
2914 (define_expand "negdi2"
2915 [(set (match_operand:DI 0 "arith_reg_operand" "")
2916 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2922 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2923 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2925 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2926 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2928 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2929 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2931 emit_insn (gen_clrt ());
2932 emit_insn (gen_negc (low_dst, low_src));
2933 emit_insn (gen_negc (high_dst, high_src));
2938 (define_insn "negsi2"
2939 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2940 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2943 [(set_attr "type" "arith")])
2945 (define_insn "one_cmplsi2"
2946 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2947 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2950 [(set_attr "type" "arith")])
2952 (define_expand "one_cmpldi2"
2953 [(set (match_operand:DI 0 "arith_reg_operand" "")
2954 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2956 "TARGET_SHMEDIA" "")
2958 ;; -------------------------------------------------------------------------
2959 ;; Zero extension instructions
2960 ;; -------------------------------------------------------------------------
2962 (define_insn "zero_extendsidi2"
2963 [(set (match_operand:DI 0 "register_operand" "=r")
2964 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2966 "addz.l %1, r63, %0"
2967 [(set_attr "type" "arith_media")])
2969 (define_insn "zero_extendhidi2"
2970 [(set (match_operand:DI 0 "register_operand" "=r,r")
2971 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2976 [(set_attr "type" "*,load_media")])
2979 [(set (match_operand:DI 0 "register_operand" "")
2980 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2981 "TARGET_SHMEDIA && reload_completed"
2982 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2983 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2986 if (GET_CODE (operands[1]) == TRUNCATE)
2987 operands[1] = XEXP (operands[1], 0);
2990 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2991 ;; reload the entire truncate expression.
2992 (define_insn_and_split "*loaddi_trunc"
2993 [(set (match_operand 0 "int_gpr_dest" "=r")
2994 (truncate (match_operand:DI 1 "memory_operand" "m")))]
2995 "TARGET_SHMEDIA && reload_completed"
2997 "TARGET_SHMEDIA && reload_completed"
2998 [(set (match_dup 0) (match_dup 1))]
2999 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3001 (define_insn "zero_extendqidi2"
3002 [(set (match_operand:DI 0 "register_operand" "=r,r")
3003 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3008 [(set_attr "type" "arith_media,load_media")])
3010 (define_expand "zero_extendhisi2"
3011 [(set (match_operand:SI 0 "arith_reg_operand" "")
3012 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3016 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3017 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3020 (define_insn "*zero_extendhisi2_compact"
3021 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3022 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3025 [(set_attr "type" "arith")])
3027 (define_insn "*zero_extendhisi2_media"
3028 [(set (match_operand:SI 0 "register_operand" "=r,r")
3029 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3034 [(set_attr "type" "arith_media,load_media")])
3037 [(set (match_operand:SI 0 "register_operand" "")
3038 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3039 "TARGET_SHMEDIA && reload_completed"
3040 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3041 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3044 if (GET_CODE (operands[1]) == TRUNCATE)
3045 operands[1] = XEXP (operands[1], 0);
3048 (define_expand "zero_extendqisi2"
3049 [(set (match_operand:SI 0 "arith_reg_operand" "")
3050 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3054 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3055 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3058 (define_insn "*zero_extendqisi2_compact"
3059 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3060 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3063 [(set_attr "type" "arith")])
3065 (define_insn "*zero_extendqisi2_media"
3066 [(set (match_operand:SI 0 "register_operand" "=r,r")
3067 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3072 [(set_attr "type" "arith_media,load_media")])
3074 (define_insn "zero_extendqihi2"
3075 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3076 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3079 [(set_attr "type" "arith")])
3081 ;; -------------------------------------------------------------------------
3082 ;; Sign extension instructions
3083 ;; -------------------------------------------------------------------------
3085 ;; ??? This should be a define expand.
3086 ;; ??? Or perhaps it should be dropped?
3088 ;; convert_move generates good code for SH[1-4].
3089 (define_insn "extendsidi2"
3090 [(set (match_operand:DI 0 "register_operand" "=r,r")
3091 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3096 [(set_attr "type" "arith_media,load_media")])
3098 (define_insn "extendhidi2"
3099 [(set (match_operand:DI 0 "register_operand" "=r,r")
3100 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3105 [(set_attr "type" "*,load_media")])
3108 [(set (match_operand:DI 0 "register_operand" "")
3109 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3110 "TARGET_SHMEDIA && reload_completed"
3111 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3112 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3115 if (GET_CODE (operands[1]) == TRUNCATE)
3116 operands[1] = XEXP (operands[1], 0);
3119 (define_insn "extendqidi2"
3120 [(set (match_operand:DI 0 "register_operand" "=r,r")
3121 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3126 [(set_attr "type" "*,load_media")])
3129 [(set (match_operand:DI 0 "register_operand" "")
3130 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3131 "TARGET_SHMEDIA && reload_completed"
3132 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3133 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3136 if (GET_CODE (operands[1]) == TRUNCATE)
3137 operands[1] = XEXP (operands[1], 0);
3140 (define_expand "extendhisi2"
3141 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3142 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3146 (define_insn "*extendhisi2_compact"
3147 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3148 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3153 [(set_attr "type" "arith,load")])
3155 (define_insn "*extendhisi2_media"
3156 [(set (match_operand:SI 0 "register_operand" "=r,r")
3157 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3162 [(set_attr "type" "arith_media,load_media")])
3165 [(set (match_operand:SI 0 "register_operand" "")
3166 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3167 "TARGET_SHMEDIA && reload_completed"
3168 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3169 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3172 if (GET_CODE (operands[1]) == TRUNCATE)
3173 operands[1] = XEXP (operands[1], 0);
3176 (define_expand "extendqisi2"
3177 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3178 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3182 (define_insn "*extendqisi2_compact"
3183 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3184 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3189 [(set_attr "type" "arith,load")])
3191 (define_insn "*extendqisi2_media"
3192 [(set (match_operand:SI 0 "register_operand" "=r,r")
3193 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3198 [(set_attr "type" "arith_media,load_media")])
3201 [(set (match_operand:SI 0 "register_operand" "")
3202 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3203 "TARGET_SHMEDIA && reload_completed"
3204 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3205 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3208 if (GET_CODE (operands[1]) == TRUNCATE)
3209 operands[1] = XEXP (operands[1], 0);
3212 (define_insn "extendqihi2"
3213 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3214 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3219 [(set_attr "type" "arith,load")])
3221 /* It would seem useful to combine the truncXi patterns into the movXi
3222 patterns, but unary operators are ignored when matching constraints,
3223 so we need separate patterns. */
3224 (define_insn "truncdisi2"
3225 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3226 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3235 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3238 (define_insn "truncdihi2"
3239 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3240 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3243 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3245 [(set_attr "type" "arith_media,store_media")
3246 (set_attr "length" "8,4")])
3248 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3249 ; Because we use zero extension, we can't provide signed QImode compares
3250 ; using a simple compare or conditional banch insn.
3251 (define_insn "truncdiqi2"
3252 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3253 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3258 [(set_attr "type" "arith_media,store")])
3260 ;; -------------------------------------------------------------------------
3261 ;; Move instructions
3262 ;; -------------------------------------------------------------------------
3264 ;; define push and pop so it is easy for sh.c
3265 ;; We can't use push and pop on SHcompact because the stack must always
3266 ;; be 8-byte aligned.
3268 (define_expand "push"
3269 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3270 (match_operand:SI 0 "register_operand" "r,l,x"))]
3271 "TARGET_SH1 && ! TARGET_SH5"
3274 (define_expand "pop"
3275 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3276 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3277 "TARGET_SH1 && ! TARGET_SH5"
3280 (define_expand "push_e"
3281 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3282 (match_operand:SF 0 "" ""))
3283 (use (reg:PSI FPSCR_REG))
3284 (clobber (scratch:SI))])]
3285 "TARGET_SH1 && ! TARGET_SH5"
3288 (define_insn "push_fpul"
3289 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3290 "TARGET_SH2E && ! TARGET_SH5"
3292 [(set_attr "type" "store")
3293 (set_attr "late_fp_use" "yes")
3294 (set_attr "hit_stack" "yes")])
3296 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3298 (define_expand "push_4"
3299 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3300 (match_operand:DF 0 "" ""))
3301 (use (reg:PSI FPSCR_REG))
3302 (clobber (scratch:SI))])]
3303 "TARGET_SH1 && ! TARGET_SH5"
3306 (define_expand "pop_e"
3307 [(parallel [(set (match_operand:SF 0 "" "")
3308 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3309 (use (reg:PSI FPSCR_REG))
3310 (clobber (scratch:SI))])]
3311 "TARGET_SH1 && ! TARGET_SH5"
3314 (define_insn "pop_fpul"
3315 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3316 "TARGET_SH2E && ! TARGET_SH5"
3318 [(set_attr "type" "load")
3319 (set_attr "hit_stack" "yes")])
3321 (define_expand "pop_4"
3322 [(parallel [(set (match_operand:DF 0 "" "")
3323 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3324 (use (reg:PSI FPSCR_REG))
3325 (clobber (scratch:SI))])]
3326 "TARGET_SH1 && ! TARGET_SH5"
3329 (define_expand "push_fpscr"
3334 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3335 gen_rtx_PRE_DEC (Pmode,
3336 stack_pointer_rtx)),
3338 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3342 (define_expand "pop_fpscr"
3347 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3348 gen_rtx_MEM (PSImode,
3349 gen_rtx_POST_INC (Pmode,
3350 stack_pointer_rtx))));
3351 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3355 ;; These two patterns can happen as the result of optimization, when
3356 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3357 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3360 [(set (reg:SI T_REG) (const_int 0))]
3365 [(set (reg:SI T_REG) (const_int 1))]
3369 ;; t/r must come after r/r, lest reload will try to reload stuff like
3370 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3371 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3372 (define_insn "movsi_i"
3373 [(set (match_operand:SI 0 "general_movdst_operand"
3374 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3375 (match_operand:SI 1 "general_movsrc_operand"
3376 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3380 && (register_operand (operands[0], SImode)
3381 || register_operand (operands[1], SImode))"
3398 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3399 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3401 ;; t/r must come after r/r, lest reload will try to reload stuff like
3402 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3403 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3404 ;; will require a reload.
3405 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3406 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3407 (define_insn "movsi_ie"
3408 [(set (match_operand:SI 0 "general_movdst_operand"
3409 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3410 (match_operand:SI 1 "general_movsrc_operand"
3411 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3412 "(TARGET_SH2E || TARGET_SH2A)
3413 && (register_operand (operands[0], SImode)
3414 || register_operand (operands[1], SImode))"
3439 ! move optimized away"
3440 [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3441 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3442 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3444 (define_insn "movsi_i_lowpart"
3445 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3446 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3448 && (register_operand (operands[0], SImode)
3449 || register_operand (operands[1], SImode))"
3459 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3461 (define_insn_and_split "load_ra"
3462 [(set (match_operand:SI 0 "general_movdst_operand" "")
3463 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3466 "&& ! currently_expanding_to_rtl"
3467 [(set (match_dup 0) (match_dup 1))]
3470 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3471 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3474 (define_insn "*movsi_media"
3475 [(set (match_operand:SI 0 "general_movdst_operand"
3476 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3477 (match_operand:SI 1 "general_movsrc_operand"
3478 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3480 && (register_operand (operands[0], SImode)
3481 || sh_register_operand (operands[1], SImode))"
3496 [(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")
3497 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3499 (define_insn "*movsi_media_nofpu"
3500 [(set (match_operand:SI 0 "general_movdst_operand"
3501 "=r,r,r,r,m,*b,r,b")
3502 (match_operand:SI 1 "general_movsrc_operand"
3503 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3505 && (register_operand (operands[0], SImode)
3506 || sh_register_operand (operands[1], SImode))"
3516 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3517 (set_attr "length" "4,4,8,4,4,4,4,12")])
3520 [(set (match_operand:SI 0 "arith_reg_operand" "")
3521 (match_operand:SI 1 "immediate_operand" ""))]
3522 "TARGET_SHMEDIA && reload_completed
3523 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3524 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3527 operands[2] = shallow_copy_rtx (operands[1]);
3528 PUT_MODE (operands[2], DImode);
3532 [(set (match_operand:SI 0 "register_operand" "")
3533 (match_operand:SI 1 "immediate_operand" ""))]
3534 "TARGET_SHMEDIA && reload_completed
3535 && ((GET_CODE (operands[1]) == CONST_INT
3536 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3537 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3538 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3540 (define_expand "movsi"
3541 [(set (match_operand:SI 0 "general_movdst_operand" "")
3542 (match_operand:SI 1 "general_movsrc_operand" ""))]
3544 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3546 (define_expand "ic_invalidate_line"
3547 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3548 (match_dup 1)] UNSPEC_ICACHE)
3549 (clobber (scratch:SI))])]
3550 "TARGET_HARD_SH4 || TARGET_SH5"
3555 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3558 else if (TARGET_SHCOMPACT)
3560 operands[1] = function_symbol (\"__ic_invalidate\");
3561 operands[1] = force_reg (Pmode, operands[1]);
3562 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3565 else if (TARGET_SH4A_ARCH)
3567 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3570 operands[0] = force_reg (Pmode, operands[0]);
3571 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3575 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3576 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3577 ;; the requirement *1*00 for associative address writes. The alignment of
3578 ;; %0 implies that its least significant bit is cleared,
3579 ;; thus we clear the V bit of a matching entry if there is one.
3580 (define_insn "ic_invalidate_line_i"
3581 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3582 (match_operand:SI 1 "register_operand" "r")]
3584 (clobber (match_scratch:SI 2 "=&r"))]
3586 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3587 [(set_attr "length" "8")
3588 (set_attr "type" "cwb")])
3590 (define_insn "ic_invalidate_line_sh4a"
3591 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3594 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3595 [(set_attr "length" "16")
3596 (set_attr "type" "cwb")])
3598 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3599 ;; an add in the code that calculates the address.
3600 (define_insn "ic_invalidate_line_media"
3601 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3604 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3605 [(set_attr "length" "16")
3606 (set_attr "type" "invalidate_line_media")])
3608 (define_insn "ic_invalidate_line_compact"
3609 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3610 (match_operand:SI 1 "register_operand" "r")]
3612 (clobber (reg:SI PR_REG))]
3615 [(set_attr "type" "sfunc")
3616 (set_attr "needs_delay_slot" "yes")])
3618 (define_expand "initialize_trampoline"
3619 [(match_operand:SI 0 "" "")
3620 (match_operand:SI 1 "" "")
3621 (match_operand:SI 2 "" "")]
3627 tramp = force_reg (Pmode, operands[0]);
3628 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3629 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3630 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3632 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3636 (define_insn "initialize_trampoline_compact"
3637 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3638 (match_operand:SI 1 "register_operand" "r")
3639 (reg:SI R2_REG) (reg:SI R3_REG)]
3642 (clobber (reg:SI PR_REG))]
3645 [(set_attr "type" "sfunc")
3646 (set_attr "needs_delay_slot" "yes")])
3648 (define_insn "movqi_i"
3649 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3650 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3652 && (arith_reg_operand (operands[0], QImode)
3653 || arith_reg_operand (operands[1], QImode))"
3661 [(set_attr "type" "move,load,store,move,move,move")])
3663 (define_insn "*movqi_media"
3664 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3665 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3667 && (arith_reg_operand (operands[0], QImode)
3668 || arith_reg_or_0_operand (operands[1], QImode))"
3674 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3676 (define_expand "movqi"
3677 [(set (match_operand:QI 0 "general_operand" "")
3678 (match_operand:QI 1 "general_operand" ""))]
3680 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3682 (define_expand "reload_inqi"
3683 [(set (match_operand:SI 2 "" "=&r")
3684 (match_operand:QI 1 "inqhi_operand" ""))
3685 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3686 (truncate:QI (match_dup 3)))]
3690 rtx inner = XEXP (operands[1], 0);
3691 int regno = REGNO (inner);
3693 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3694 operands[1] = gen_rtx_REG (SImode, regno);
3695 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3698 /* When storing r0, we have to avoid reg+reg addressing. */
3699 (define_insn "movhi_i"
3700 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3701 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3703 && (arith_reg_operand (operands[0], HImode)
3704 || arith_reg_operand (operands[1], HImode))
3705 && (GET_CODE (operands[0]) != MEM
3706 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3707 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3708 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3718 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3720 (define_insn "*movhi_media"
3721 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3722 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3724 && (arith_reg_operand (operands[0], HImode)
3725 || arith_reg_or_0_operand (operands[1], HImode))"
3732 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3735 [(set (match_operand:HI 0 "register_operand" "")
3736 (match_operand:HI 1 "immediate_operand" ""))]
3737 "TARGET_SHMEDIA && reload_completed
3738 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3739 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3741 (define_expand "movhi"
3742 [(set (match_operand:HI 0 "general_movdst_operand" "")
3743 (match_operand:HI 1 "general_movsrc_operand" ""))]
3745 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3747 (define_expand "reload_inhi"
3748 [(set (match_operand:SI 2 "" "=&r")
3749 (match_operand:HI 1 "inqhi_operand" ""))
3750 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3751 (truncate:HI (match_dup 3)))]
3755 rtx inner = XEXP (operands[1], 0);
3756 int regno = REGNO (inner);
3758 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3759 operands[1] = gen_rtx_REG (SImode, regno);
3760 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3763 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3764 ;; compiled with -m2 -ml -O3 -funroll-loops
3765 (define_insn "*movdi_i"
3766 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3767 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3769 && (arith_reg_operand (operands[0], DImode)
3770 || arith_reg_operand (operands[1], DImode))"
3771 "* return output_movedouble (insn, operands, DImode);"
3772 [(set_attr "length" "4")
3773 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3775 ;; If the output is a register and the input is memory or a register, we have
3776 ;; to be careful and see which word needs to be loaded first.
3779 [(set (match_operand:DI 0 "general_movdst_operand" "")
3780 (match_operand:DI 1 "general_movsrc_operand" ""))]
3781 "TARGET_SH1 && reload_completed"
3782 [(set (match_dup 2) (match_dup 3))
3783 (set (match_dup 4) (match_dup 5))]
3788 if ((GET_CODE (operands[0]) == MEM
3789 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3790 || (GET_CODE (operands[1]) == MEM
3791 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3794 if (GET_CODE (operands[0]) == REG)
3795 regno = REGNO (operands[0]);
3796 else if (GET_CODE (operands[0]) == SUBREG)
3797 regno = subreg_regno (operands[0]);
3798 else if (GET_CODE (operands[0]) == MEM)
3804 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3806 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3807 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3808 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3809 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3813 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3814 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3815 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3816 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3819 if (operands[2] == 0 || operands[3] == 0
3820 || operands[4] == 0 || operands[5] == 0)
3824 (define_insn "*movdi_media"
3825 [(set (match_operand:DI 0 "general_movdst_operand"
3826 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3827 (match_operand:DI 1 "general_movsrc_operand"
3828 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3830 && (register_operand (operands[0], DImode)
3831 || sh_register_operand (operands[1], DImode))"
3846 [(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")
3847 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3849 (define_insn "*movdi_media_nofpu"
3850 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3851 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3853 && (register_operand (operands[0], DImode)
3854 || sh_register_operand (operands[1], DImode))"
3864 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3865 (set_attr "length" "4,4,16,4,4,4,4,*")])
3868 [(set (match_operand:DI 0 "arith_reg_operand" "")
3869 (match_operand:DI 1 "immediate_operand" ""))]
3870 "TARGET_SHMEDIA && reload_completed
3871 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3872 [(set (match_dup 0) (match_dup 1))]
3877 if (TARGET_SHMEDIA64)
3878 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3880 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3882 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3888 (define_expand "movdi_const"
3889 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3890 (const:DI (sign_extend:DI
3893 (match_operand:DI 1 "immediate_operand" "s")
3896 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3904 (const_int 32)))))))))
3906 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3914 (const_int 16)))))))))
3916 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3922 (match_dup 1))))))))]
3923 "TARGET_SHMEDIA64 && reload_completed
3924 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3927 sh_mark_label (operands[1], 4);
3930 (define_expand "movdi_const_32bit"
3931 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3932 (const:DI (sign_extend:DI
3935 (match_operand:DI 1 "immediate_operand" "s")
3938 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3944 (match_dup 1))))))))]
3945 "TARGET_SHMEDIA32 && reload_completed
3946 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3949 sh_mark_label (operands[1], 2);
3952 (define_expand "movdi_const_16bit"
3953 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3954 (const:DI (sign_extend:DI
3956 (match_operand:DI 1 "immediate_operand" "s")))))]
3957 "TARGET_SHMEDIA && flag_pic && reload_completed
3958 && GET_CODE (operands[1]) == SYMBOL_REF"
3962 [(set (match_operand:DI 0 "arith_reg_operand" "")
3963 (match_operand:DI 1 "immediate_operand" ""))]
3964 "TARGET_SHMEDIA && reload_completed
3965 && GET_CODE (operands[1]) == CONST_INT
3966 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3967 [(set (match_dup 0) (match_dup 2))
3971 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3972 unsigned HOST_WIDE_INT low = val;
3973 unsigned HOST_WIDE_INT high = val;
3974 unsigned HOST_WIDE_INT sign;
3975 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3977 /* Sign-extend the 16 least-significant bits. */
3982 /* Arithmetic shift right the word by 16 bits. */
3985 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3990 /* If we can't generate the constant with a two-insn movi / shori
3991 sequence, try some other strategies. */
3992 if (! CONST_OK_FOR_I16 (high))
3994 /* Try constant load / left shift. We know VAL != 0. */
3995 val2 = val ^ (val-1);
3998 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4000 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4001 || (! CONST_OK_FOR_I16 (high >> 16)
4002 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4004 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4005 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4006 GEN_INT (trailing_zeroes));
4010 /* Try constant load / right shift. */
4011 val2 = (val >> 15) + 1;
4012 if (val2 == (val2 & -val2))
4014 int shift = 49 - exact_log2 (val2);
4016 val2 = trunc_int_for_mode (val << shift, DImode);
4017 if (CONST_OK_FOR_I16 (val2))
4019 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4025 val2 = val & 0xffff;
4026 if ((val >> 16 & 0xffff) == val2
4027 && (val >> 32 & 0xffff) == val2
4028 && (val >> 48 & 0xffff) == val2)
4030 val2 = (HOST_WIDE_INT) val >> 48;
4031 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4032 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4035 /* Try movi / mshflo.l */
4036 val2 = (HOST_WIDE_INT) val >> 32;
4037 if (val2 == ((unsigned HOST_WIDE_INT)
4038 trunc_int_for_mode (val, SImode)))
4040 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4044 /* Try movi / mshflo.l w/ r63. */
4045 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4046 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4048 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4054 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4057 operands[2] = GEN_INT (val2);
4061 [(set (match_operand:DI 0 "arith_reg_operand" "")
4062 (match_operand:DI 1 "immediate_operand" ""))]
4063 "TARGET_SHMEDIA && reload_completed
4064 && GET_CODE (operands[1]) == CONST_DOUBLE"
4065 [(set (match_dup 0) (match_dup 2))
4067 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4068 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4071 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4072 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4073 unsigned HOST_WIDE_INT val = low;
4074 unsigned HOST_WIDE_INT sign;
4076 /* Sign-extend the 16 least-significant bits. */
4080 operands[1] = GEN_INT (val);
4082 /* Arithmetic shift right the double-word by 16 bits. */
4084 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4087 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4091 /* This will only be true if high is a sign-extension of low, i.e.,
4092 it must be either 0 or (unsigned)-1, and be zero iff the
4093 most-significant bit of low is set. */
4094 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4095 operands[2] = GEN_INT (low);
4097 operands[2] = immed_double_const (low, high, DImode);
4100 (define_insn "shori_media"
4101 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4102 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4106 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4111 [(set_attr "type" "arith_media,*")])
4113 (define_expand "movdi"
4114 [(set (match_operand:DI 0 "general_movdst_operand" "")
4115 (match_operand:DI 1 "general_movsrc_operand" ""))]
4117 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4119 (define_insn "movdf_media"
4120 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4121 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4123 && (register_operand (operands[0], DFmode)
4124 || sh_register_operand (operands[1], DFmode))"
4135 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4137 (define_insn "movdf_media_nofpu"
4138 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4139 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4141 && (register_operand (operands[0], DFmode)
4142 || sh_register_operand (operands[1], DFmode))"
4148 [(set_attr "type" "arith_media,*,load_media,store_media")])
4151 [(set (match_operand:DF 0 "arith_reg_operand" "")
4152 (match_operand:DF 1 "immediate_operand" ""))]
4153 "TARGET_SHMEDIA && reload_completed"
4154 [(set (match_dup 3) (match_dup 2))]
4157 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4159 REAL_VALUE_TYPE value;
4161 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4162 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4164 if (HOST_BITS_PER_WIDE_INT >= 64)
4165 operands[2] = immed_double_const ((unsigned long) values[endian]
4166 | ((HOST_WIDE_INT) values[1 - endian]
4168 else if (HOST_BITS_PER_WIDE_INT == 32)
4169 operands[2] = immed_double_const (values[endian], values[1 - endian],
4174 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4177 ;; ??? This should be a define expand.
4179 (define_insn "movdf_k"
4180 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4181 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4183 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4184 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4185 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4186 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4187 && (arith_reg_operand (operands[0], DFmode)
4188 || arith_reg_operand (operands[1], DFmode))"
4189 "* return output_movedouble (insn, operands, DFmode);"
4190 [(set_attr "length" "4")
4191 (set_attr "type" "move,pcload,load,store")])
4193 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4194 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4195 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4196 ;; the d/m/c/X alternative, which is split later into single-precision
4197 ;; instructions. And when not optimizing, no splits are done before fixing
4198 ;; up pcloads, so we need usable length information for that.
4199 (define_insn "movdf_i4"
4200 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4201 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4202 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4203 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4204 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4205 && (arith_reg_operand (operands[0], DFmode)
4206 || arith_reg_operand (operands[1], DFmode))"
4218 [(set_attr_alternative "length"
4219 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4221 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4222 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4223 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4225 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4226 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4227 ;; increment or decrement r15 explicitly.
4229 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4230 (const_int 10) (const_int 8))
4232 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233 (const_int 10) (const_int 8))])
4234 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4235 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4236 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4237 (const_string "double")
4238 (const_string "none")))])
4240 ;; Moving DFmode between fp/general registers through memory
4241 ;; (the top of the stack) is faster than moving through fpul even for
4242 ;; little endian. Because the type of an instruction is important for its
4243 ;; scheduling, it is beneficial to split these operations, rather than
4244 ;; emitting them in one single chunk, even if this will expose a stack
4245 ;; use that will prevent scheduling of other stack accesses beyond this
4248 [(set (match_operand:DF 0 "register_operand" "")
4249 (match_operand:DF 1 "register_operand" ""))
4250 (use (match_operand:PSI 2 "fpscr_operand" ""))
4251 (clobber (match_scratch:SI 3 "=X"))]
4252 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4253 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4259 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4261 emit_move_insn (stack_pointer_rtx,
4262 plus_constant (stack_pointer_rtx, -8));
4263 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4266 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4267 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4268 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4269 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4270 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4271 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4273 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4274 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4275 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4276 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4278 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4282 ;; local-alloc sometimes allocates scratch registers even when not required,
4283 ;; so we must be prepared to handle these.
4285 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4287 [(set (match_operand:DF 0 "general_movdst_operand" "")
4288 (match_operand:DF 1 "general_movsrc_operand" ""))
4289 (use (match_operand:PSI 2 "fpscr_operand" ""))
4290 (clobber (match_scratch:SI 3 ""))]
4291 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4293 && true_regnum (operands[0]) < 16
4294 && true_regnum (operands[1]) < 16"
4295 [(set (match_dup 0) (match_dup 1))]
4298 /* If this was a reg <-> mem operation with base + index reg addressing,
4299 we have to handle this in a special way. */
4300 rtx mem = operands[0];
4302 if (! memory_operand (mem, DFmode))
4307 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4308 mem = SUBREG_REG (mem);
4309 if (GET_CODE (mem) == MEM)
4311 rtx addr = XEXP (mem, 0);
4312 if (GET_CODE (addr) == PLUS
4313 && GET_CODE (XEXP (addr, 0)) == REG
4314 && GET_CODE (XEXP (addr, 1)) == REG)
4317 rtx reg0 = gen_rtx_REG (Pmode, 0);
4318 rtx regop = operands[store_p], word0 ,word1;
4320 if (GET_CODE (regop) == SUBREG)
4321 alter_subreg (®op);
4322 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4326 mem = copy_rtx (mem);
4327 PUT_MODE (mem, SImode);
4328 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4329 alter_subreg (&word0);
4330 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4331 alter_subreg (&word1);
4332 if (store_p || ! refers_to_regno_p (REGNO (word0),
4333 REGNO (word0) + 1, addr, 0))
4336 ? gen_movsi_ie (mem, word0)
4337 : gen_movsi_ie (word0, mem));
4338 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4339 mem = copy_rtx (mem);
4341 ? gen_movsi_ie (mem, word1)
4342 : gen_movsi_ie (word1, mem));
4343 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4347 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4348 emit_insn (gen_movsi_ie (word1, mem));
4349 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4350 mem = copy_rtx (mem);
4351 emit_insn (gen_movsi_ie (word0, mem));
4358 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4360 [(set (match_operand:DF 0 "register_operand" "")
4361 (match_operand:DF 1 "memory_operand" ""))
4362 (use (match_operand:PSI 2 "fpscr_operand" ""))
4363 (clobber (reg:SI R0_REG))]
4364 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4365 [(parallel [(set (match_dup 0) (match_dup 1))
4367 (clobber (scratch:SI))])]
4370 (define_expand "reload_indf"
4371 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4372 (match_operand:DF 1 "immediate_operand" "FQ"))
4373 (use (reg:PSI FPSCR_REG))
4374 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4378 (define_expand "reload_outdf"
4379 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4380 (match_operand:DF 1 "register_operand" "af,r"))
4381 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4385 ;; Simplify no-op moves.
4387 [(set (match_operand:SF 0 "register_operand" "")
4388 (match_operand:SF 1 "register_operand" ""))
4389 (use (match_operand:PSI 2 "fpscr_operand" ""))
4390 (clobber (match_scratch:SI 3 ""))]
4391 "TARGET_SH2E && reload_completed
4392 && true_regnum (operands[0]) == true_regnum (operands[1])"
4393 [(set (match_dup 0) (match_dup 0))]
4396 ;; fmovd substitute post-reload splits
4398 [(set (match_operand:DF 0 "register_operand" "")
4399 (match_operand:DF 1 "register_operand" ""))
4400 (use (match_operand:PSI 2 "fpscr_operand" ""))
4401 (clobber (match_scratch:SI 3 ""))]
4402 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4403 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4404 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4408 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4409 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4410 gen_rtx_REG (SFmode, src), operands[2]));
4411 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4412 gen_rtx_REG (SFmode, src + 1), operands[2]));
4417 [(set (match_operand:DF 0 "register_operand" "")
4418 (mem:DF (match_operand:SI 1 "register_operand" "")))
4419 (use (match_operand:PSI 2 "fpscr_operand" ""))
4420 (clobber (match_scratch:SI 3 ""))]
4421 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4422 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4423 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4427 int regno = true_regnum (operands[0]);
4429 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4431 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4432 regno + !! TARGET_LITTLE_ENDIAN),
4433 mem2, operands[2]));
4434 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4435 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4436 regno + ! TARGET_LITTLE_ENDIAN),
4437 gen_rtx_MEM (SFmode, operands[1]),
4443 [(set (match_operand:DF 0 "register_operand" "")
4444 (match_operand:DF 1 "memory_operand" ""))
4445 (use (match_operand:PSI 2 "fpscr_operand" ""))
4446 (clobber (match_scratch:SI 3 ""))]
4447 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4448 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4452 int regno = true_regnum (operands[0]);
4453 rtx addr, insn, adjust = NULL_RTX;
4454 rtx mem2 = copy_rtx (operands[1]);
4455 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4456 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4458 PUT_MODE (mem2, SFmode);
4459 operands[1] = copy_rtx (mem2);
4460 addr = XEXP (mem2, 0);
4461 if (GET_CODE (addr) != POST_INC)
4463 /* If we have to modify the stack pointer, the value that we have
4464 read with post-increment might be modified by an interrupt,
4465 so write it back. */
4466 if (REGNO (addr) == STACK_POINTER_REGNUM)
4467 adjust = gen_push_e (reg0);
4469 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4470 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4472 addr = XEXP (addr, 0);
4473 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4474 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4475 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4479 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4484 [(set (match_operand:DF 0 "memory_operand" "")
4485 (match_operand:DF 1 "register_operand" ""))
4486 (use (match_operand:PSI 2 "fpscr_operand" ""))
4487 (clobber (match_scratch:SI 3 ""))]
4488 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4489 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4493 int regno = true_regnum (operands[1]);
4494 rtx insn, addr, adjust = NULL_RTX;
4496 operands[0] = copy_rtx (operands[0]);
4497 PUT_MODE (operands[0], SFmode);
4498 insn = emit_insn (gen_movsf_ie (operands[0],
4499 gen_rtx_REG (SFmode,
4500 regno + ! TARGET_LITTLE_ENDIAN),
4502 operands[0] = copy_rtx (operands[0]);
4503 addr = XEXP (operands[0], 0);
4504 if (GET_CODE (addr) != PRE_DEC)
4506 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4507 emit_insn_before (adjust, insn);
4508 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4510 addr = XEXP (addr, 0);
4512 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4513 insn = emit_insn (gen_movsf_ie (operands[0],
4514 gen_rtx_REG (SFmode,
4515 regno + !! TARGET_LITTLE_ENDIAN),
4517 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4521 ;; If the output is a register and the input is memory or a register, we have
4522 ;; to be careful and see which word needs to be loaded first.
4525 [(set (match_operand:DF 0 "general_movdst_operand" "")
4526 (match_operand:DF 1 "general_movsrc_operand" ""))]
4527 "TARGET_SH1 && reload_completed"
4528 [(set (match_dup 2) (match_dup 3))
4529 (set (match_dup 4) (match_dup 5))]
4534 if ((GET_CODE (operands[0]) == MEM
4535 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4536 || (GET_CODE (operands[1]) == MEM
4537 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4540 if (GET_CODE (operands[0]) == REG)
4541 regno = REGNO (operands[0]);
4542 else if (GET_CODE (operands[0]) == SUBREG)
4543 regno = subreg_regno (operands[0]);
4544 else if (GET_CODE (operands[0]) == MEM)
4550 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4552 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4553 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4554 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4555 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4559 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4560 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4561 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4562 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4565 if (operands[2] == 0 || operands[3] == 0
4566 || operands[4] == 0 || operands[5] == 0)
4570 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4571 ;; used only once, let combine add in the index again.
4574 [(set (match_operand:SI 0 "register_operand" "")
4575 (match_operand:SI 1 "" ""))
4576 (clobber (match_operand 2 "register_operand" ""))]
4577 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4578 [(use (reg:SI R0_REG))]
4581 rtx addr, reg, const_int;
4583 if (GET_CODE (operands[1]) != MEM)
4585 addr = XEXP (operands[1], 0);
4586 if (GET_CODE (addr) != PLUS)
4588 reg = XEXP (addr, 0);
4589 const_int = XEXP (addr, 1);
4590 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4591 && GET_CODE (const_int) == CONST_INT))
4593 emit_move_insn (operands[2], const_int);
4594 emit_move_insn (operands[0],
4595 change_address (operands[1], VOIDmode,
4596 gen_rtx_PLUS (SImode, reg, operands[2])));
4601 [(set (match_operand:SI 1 "" "")
4602 (match_operand:SI 0 "register_operand" ""))
4603 (clobber (match_operand 2 "register_operand" ""))]
4604 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4605 [(use (reg:SI R0_REG))]
4608 rtx addr, reg, const_int;
4610 if (GET_CODE (operands[1]) != MEM)
4612 addr = XEXP (operands[1], 0);
4613 if (GET_CODE (addr) != PLUS)
4615 reg = XEXP (addr, 0);
4616 const_int = XEXP (addr, 1);
4617 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4618 && GET_CODE (const_int) == CONST_INT))
4620 emit_move_insn (operands[2], const_int);
4621 emit_move_insn (change_address (operands[1], VOIDmode,
4622 gen_rtx_PLUS (SImode, reg, operands[2])),
4627 (define_expand "movdf"
4628 [(set (match_operand:DF 0 "general_movdst_operand" "")
4629 (match_operand:DF 1 "general_movsrc_operand" ""))]
4633 if (prepare_move_operands (operands, DFmode)) DONE;
4636 if (TARGET_SHMEDIA_FPU)
4637 emit_insn (gen_movdf_media (operands[0], operands[1]));
4639 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4642 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4644 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4649 ;;This is incompatible with the way gcc uses subregs.
4650 ;;(define_insn "movv2sf_i"
4651 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4652 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4653 ;; "TARGET_SHMEDIA_FPU
4654 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4655 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4659 ;; fst%M0.p %m0, %1"
4660 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4662 (define_insn_and_split "movv2sf_i"
4663 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4664 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4665 "TARGET_SHMEDIA_FPU"
4667 "TARGET_SHMEDIA_FPU && reload_completed"
4668 [(set (match_dup 0) (match_dup 1))]
4671 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4672 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4675 (define_expand "movv2sf"
4676 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4677 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4678 "TARGET_SHMEDIA_FPU"
4681 if (prepare_move_operands (operands, V2SFmode))
4685 (define_expand "addv2sf3"
4686 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4688 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4689 "TARGET_SHMEDIA_FPU"
4692 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4696 (define_expand "subv2sf3"
4697 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4698 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4699 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4700 "TARGET_SHMEDIA_FPU"
4703 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4707 (define_expand "mulv2sf3"
4708 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4709 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4710 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4711 "TARGET_SHMEDIA_FPU"
4714 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4718 (define_expand "divv2sf3"
4719 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4720 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4721 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4722 "TARGET_SHMEDIA_FPU"
4725 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4729 (define_insn_and_split "*movv4sf_i"
4730 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4731 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4732 "TARGET_SHMEDIA_FPU"
4734 "&& reload_completed"
4740 for (i = 0; i < 4/2; i++)
4744 if (GET_CODE (operands[0]) == MEM)
4745 x = gen_rtx_MEM (V2SFmode,
4746 plus_constant (XEXP (operands[0], 0),
4747 i * GET_MODE_SIZE (V2SFmode)));
4749 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4751 if (GET_CODE (operands[1]) == MEM)
4752 y = gen_rtx_MEM (V2SFmode,
4753 plus_constant (XEXP (operands[1], 0),
4754 i * GET_MODE_SIZE (V2SFmode)));
4756 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4758 emit_insn (gen_movv2sf_i (x, y));
4763 [(set_attr "length" "8")])
4765 (define_expand "movv4sf"
4766 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4767 (match_operand:V4SF 1 "general_operand" ""))]
4768 "TARGET_SHMEDIA_FPU"
4771 if (prepare_move_operands (operands, V4SFmode))
4775 (define_insn_and_split "*movv16sf_i"
4776 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4777 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4778 "TARGET_SHMEDIA_FPU"
4780 "&& reload_completed"
4786 for (i = 0; i < 16/2; i++)
4790 if (GET_CODE (operands[0]) == MEM)
4791 x = gen_rtx_MEM (V2SFmode,
4792 plus_constant (XEXP (operands[0], 0),
4793 i * GET_MODE_SIZE (V2SFmode)));
4796 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4800 if (GET_CODE (operands[1]) == MEM)
4801 y = gen_rtx_MEM (V2SFmode,
4802 plus_constant (XEXP (operands[1], 0),
4803 i * GET_MODE_SIZE (V2SFmode)));
4806 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4810 emit_insn (gen_movv2sf_i (x, y));
4815 [(set_attr "length" "32")])
4817 (define_expand "movv16sf"
4818 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4819 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4820 "TARGET_SHMEDIA_FPU"
4823 if (prepare_move_operands (operands, V16SFmode))
4827 (define_insn "movsf_media"
4828 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4829 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4831 && (register_operand (operands[0], SFmode)
4832 || sh_register_operand (operands[1], SFmode))"
4843 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4845 (define_insn "movsf_media_nofpu"
4846 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4847 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4849 && (register_operand (operands[0], SFmode)
4850 || sh_register_operand (operands[1], SFmode))"
4856 [(set_attr "type" "arith_media,*,load_media,store_media")])
4859 [(set (match_operand:SF 0 "arith_reg_operand" "")
4860 (match_operand:SF 1 "immediate_operand" ""))]
4861 "TARGET_SHMEDIA && reload_completed
4862 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4863 [(set (match_dup 3) (match_dup 2))]
4867 REAL_VALUE_TYPE value;
4869 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4870 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4871 operands[2] = GEN_INT (values);
4873 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4876 (define_insn "movsf_i"
4877 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4878 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4881 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4882 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4883 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4884 && (arith_reg_operand (operands[0], SFmode)
4885 || arith_reg_operand (operands[1], SFmode))"
4894 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4896 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4897 ;; update_flow_info would not know where to put REG_EQUAL notes
4898 ;; when the destination changes mode.
4899 (define_insn "movsf_ie"
4900 [(set (match_operand:SF 0 "general_movdst_operand"
4901 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4902 (match_operand:SF 1 "general_movsrc_operand"
4903 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4904 (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"))
4905 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4908 && (arith_reg_operand (operands[0], SFmode)
4909 || arith_reg_operand (operands[1], SFmode)
4910 || arith_reg_operand (operands[3], SImode)
4911 || (fpul_operand (operands[0], SFmode)
4912 && memory_operand (operands[1], SFmode)
4913 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4914 || (fpul_operand (operands[1], SFmode)
4915 && memory_operand (operands[0], SFmode)
4916 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4936 ! move optimized away"
4937 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4938 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4939 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4940 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4941 (const_string "single")
4942 (const_string "none")))])
4945 [(set (match_operand:SF 0 "register_operand" "")
4946 (match_operand:SF 1 "register_operand" ""))
4947 (use (match_operand:PSI 2 "fpscr_operand" ""))
4948 (clobber (reg:SI FPUL_REG))]
4950 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4952 (clobber (scratch:SI))])
4953 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4955 (clobber (scratch:SI))])]
4958 (define_expand "movsf"
4959 [(set (match_operand:SF 0 "general_movdst_operand" "")
4960 (match_operand:SF 1 "general_movsrc_operand" ""))]
4964 if (prepare_move_operands (operands, SFmode))
4968 if (TARGET_SHMEDIA_FPU)
4969 emit_insn (gen_movsf_media (operands[0], operands[1]));
4971 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4976 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4981 (define_insn "mov_nop"
4982 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4985 [(set_attr "length" "0")
4986 (set_attr "type" "nil")])
4988 (define_expand "reload_insf"
4989 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4990 (match_operand:SF 1 "immediate_operand" "FQ"))
4991 (use (reg:PSI FPSCR_REG))
4992 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4996 (define_expand "reload_insi"
4997 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4998 (match_operand:SF 1 "immediate_operand" "FQ"))
4999 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5003 (define_insn "*movsi_y"
5004 [(set (match_operand:SI 0 "register_operand" "=y,y")
5005 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5006 (clobber (match_scratch:SI 2 "=&z,r"))]
5008 && (reload_in_progress || reload_completed)"
5010 [(set_attr "length" "4")
5011 (set_attr "type" "pcload,move")])
5014 [(set (match_operand:SI 0 "register_operand" "")
5015 (match_operand:SI 1 "immediate_operand" ""))
5016 (clobber (match_operand:SI 2 "register_operand" ""))]
5018 [(set (match_dup 2) (match_dup 1))
5019 (set (match_dup 0) (match_dup 2))]
5023 [(set (match_operand:SI 0 "register_operand" "")
5024 (match_operand:SI 1 "memory_operand" ""))
5025 (clobber (reg:SI R0_REG))]
5027 [(set (match_dup 0) (match_dup 1))]
5030 ;; ------------------------------------------------------------------------
5031 ;; Define the real conditional branch instructions.
5032 ;; ------------------------------------------------------------------------
5034 (define_insn "branch_true"
5035 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5036 (label_ref (match_operand 0 "" ""))
5039 "* return output_branch (1, insn, operands);"
5040 [(set_attr "type" "cbranch")])
5042 (define_insn "branch_false"
5043 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5044 (label_ref (match_operand 0 "" ""))
5047 "* return output_branch (0, insn, operands);"
5048 [(set_attr "type" "cbranch")])
5050 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5051 ;; which destination is too far away.
5052 ;; The const_int_operand is distinct for each branch target; it avoids
5053 ;; unwanted matches with redundant_insn.
5054 (define_insn "block_branch_redirect"
5055 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5058 [(set_attr "length" "0")])
5060 ;; This one has the additional purpose to record a possible scratch register
5061 ;; for the following branch.
5062 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5063 ;; because the insn then might be deemed dead and deleted. And we can't
5064 ;; make the use in the jump insn explicit because that would disable
5065 ;; delay slot scheduling from the target.
5066 (define_insn "indirect_jump_scratch"
5067 [(set (match_operand:SI 0 "register_operand" "=r")
5068 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5069 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5072 [(set_attr "length" "0")])
5074 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5075 ;; being pulled into the delay slot of a condbranch that has been made to
5076 ;; jump around the unconditional jump because it was out of range.
5077 (define_insn "stuff_delay_slot"
5079 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5080 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5083 [(set_attr "length" "0")
5084 (set_attr "cond_delay_slot" "yes")])
5086 ;; Conditional branch insns
5088 (define_expand "beq_media"
5090 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5091 (match_operand:DI 2 "arith_operand" "r,I06"))
5092 (label_ref:DI (match_operand 0 "" ""))
5097 (define_insn "*beq_media_i"
5099 (if_then_else (match_operator 3 "equality_comparison_operator"
5100 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5101 (match_operand:DI 2 "arith_operand" "r,I06")])
5102 (match_operand:DI 0 "target_operand" "b,b")
5108 [(set_attr "type" "cbranch_media")])
5110 (define_expand "bne_media"
5112 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5113 (match_operand:DI 2 "arith_operand" "r,I06"))
5114 (label_ref:DI (match_operand 0 "" ""))
5119 (define_expand "bgt_media"
5121 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5122 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5123 (label_ref:DI (match_operand 0 "" ""))
5128 (define_expand "bge_media"
5130 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5131 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5132 (label_ref:DI (match_operand 0 "" ""))
5137 (define_expand "bgtu_media"
5139 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5140 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5141 (label_ref:DI (match_operand 0 "" ""))
5146 (define_expand "bgeu_media"
5148 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5149 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5150 (label_ref:DI (match_operand 0 "" ""))
5155 (define_insn "*bgt_media_i"
5157 (if_then_else (match_operator 3 "greater_comparison_operator"
5158 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5159 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5160 (match_operand:DI 0 "target_operand" "b")
5163 "b%o3%' %N1, %N2, %0"
5164 [(set_attr "type" "cbranch_media")])
5166 ;; These are only needed to make invert_jump() happy.
5167 (define_insn "*blt_media_i"
5169 (if_then_else (match_operator 3 "less_comparison_operator"
5170 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5171 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5172 (match_operand:DI 0 "target_operand" "b")
5175 "b%o3%' %N2, %N1, %0"
5176 [(set_attr "type" "cbranch_media")])
5178 (define_expand "beq"
5180 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5181 (label_ref (match_operand 0 "" ""))
5188 if (GET_MODE (sh_compare_op0) != DImode)
5190 rtx tmp = gen_reg_rtx (DImode);
5192 emit_insn (gen_seq (tmp));
5193 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5197 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5198 emit_jump_insn (gen_beq_media (operands[0],
5199 sh_compare_op0, sh_compare_op1));
5203 from_compare (operands, EQ);
5206 (define_expand "bne"
5208 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5209 (label_ref (match_operand 0 "" ""))
5216 if (GET_MODE (sh_compare_op0) != DImode)
5218 rtx tmp = gen_reg_rtx (DImode);
5220 emit_insn (gen_seq (tmp));
5221 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5225 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5226 emit_jump_insn (gen_bne_media (operands[0],
5227 sh_compare_op0, sh_compare_op1));
5231 from_compare (operands, EQ);
5234 (define_expand "bgt"
5236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5237 (label_ref (match_operand 0 "" ""))
5244 if (GET_MODE (sh_compare_op0) != DImode)
5246 rtx tmp = gen_reg_rtx (DImode);
5248 emit_insn (gen_sgt (tmp));
5249 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5253 if (sh_compare_op0 != const0_rtx)
5254 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5255 if (sh_compare_op1 != const0_rtx)
5256 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5257 emit_jump_insn (gen_bgt_media (operands[0],
5258 sh_compare_op0, sh_compare_op1));
5262 from_compare (operands, GT);
5265 (define_expand "blt"
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5275 if (GET_MODE (sh_compare_op0) != DImode)
5277 rtx tmp = gen_reg_rtx (DImode);
5279 emit_insn (gen_slt (tmp));
5280 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5284 if (sh_compare_op0 != const0_rtx)
5285 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286 if (sh_compare_op1 != const0_rtx)
5287 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5288 emit_jump_insn (gen_bgt_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5293 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5295 rtx tmp = sh_compare_op0;
5296 sh_compare_op0 = sh_compare_op1;
5297 sh_compare_op1 = tmp;
5298 emit_insn (gen_bgt (operands[0]));
5301 from_compare (operands, GE);
5304 (define_expand "ble"
5306 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5307 (label_ref (match_operand 0 "" ""))
5314 if (GET_MODE (sh_compare_op0) != DImode)
5316 rtx tmp = gen_reg_rtx (DImode);
5318 emit_insn (gen_sle (tmp));
5319 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5323 if (sh_compare_op0 != const0_rtx)
5324 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5325 if (sh_compare_op1 != const0_rtx)
5326 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5327 emit_jump_insn (gen_bge_media (operands[0],
5328 sh_compare_op1, sh_compare_op0));
5334 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5336 rtx tmp = sh_compare_op0;
5337 sh_compare_op0 = sh_compare_op1;
5338 sh_compare_op1 = tmp;
5339 emit_insn (gen_bge (operands[0]));
5342 from_compare (operands, GT);
5345 (define_expand "bge"
5347 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5348 (label_ref (match_operand 0 "" ""))
5355 if (GET_MODE (sh_compare_op0) != DImode)
5357 rtx tmp = gen_reg_rtx (DImode);
5359 emit_insn (gen_sge (tmp));
5360 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5364 if (sh_compare_op0 != const0_rtx)
5365 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5366 if (sh_compare_op1 != const0_rtx)
5367 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5368 emit_jump_insn (gen_bge_media (operands[0],
5369 sh_compare_op0, sh_compare_op1));
5375 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5377 rtx tmp = sh_compare_op0;
5378 sh_compare_op0 = sh_compare_op1;
5379 sh_compare_op1 = tmp;
5380 emit_insn (gen_ble (operands[0]));
5383 from_compare (operands, GE);
5386 (define_expand "bgtu"
5388 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5389 (label_ref (match_operand 0 "" ""))
5396 if (sh_compare_op0 != const0_rtx)
5397 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5398 if (sh_compare_op1 != const0_rtx)
5399 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5400 emit_jump_insn (gen_bgtu_media (operands[0],
5401 sh_compare_op0, sh_compare_op1));
5405 from_compare (operands, GTU);
5408 (define_expand "bltu"
5410 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5411 (label_ref (match_operand 0 "" ""))
5418 if (sh_compare_op0 != const0_rtx)
5419 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5420 if (sh_compare_op1 != const0_rtx)
5421 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5422 emit_jump_insn (gen_bgtu_media (operands[0],
5423 sh_compare_op1, sh_compare_op0));
5427 from_compare (operands, GEU);
5430 (define_expand "bgeu"
5432 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5433 (label_ref (match_operand 0 "" ""))
5440 if (sh_compare_op0 != const0_rtx)
5441 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5442 if (sh_compare_op1 != const0_rtx)
5443 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5444 emit_jump_insn (gen_bgeu_media (operands[0],
5445 sh_compare_op0, sh_compare_op1));
5449 from_compare (operands, GEU);
5452 (define_expand "bleu"
5454 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5455 (label_ref (match_operand 0 "" ""))
5462 if (sh_compare_op0 != const0_rtx)
5463 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5464 if (sh_compare_op1 != const0_rtx)
5465 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5466 emit_jump_insn (gen_bgeu_media (operands[0],
5467 sh_compare_op1, sh_compare_op0));
5471 from_compare (operands, GTU);
5474 (define_expand "bunordered"
5475 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5477 (if_then_else (ne (match_dup 1) (const_int 0))
5478 (label_ref:DI (match_operand 0 "" ""))
5483 operands[1] = gen_reg_rtx (DImode);
5484 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5485 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5488 ;; ------------------------------------------------------------------------
5489 ;; Jump and linkage insns
5490 ;; ------------------------------------------------------------------------
5492 (define_insn "jump_compact"
5494 (label_ref (match_operand 0 "" "")))]
5498 /* The length is 16 if the delay slot is unfilled. */
5499 if (get_attr_length(insn) > 4)
5500 return output_far_jump(insn, operands[0]);
5502 return \"bra %l0%#\";
5504 [(set_attr "type" "jump")
5505 (set_attr "needs_delay_slot" "yes")])
5507 ;; ??? It would be much saner to explicitly use the scratch register
5508 ;; in the jump insn, and have indirect_jump_scratch only set it,
5509 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5510 ;; from the target then, as it uses simplejump_p.
5511 ;;(define_insn "jump_compact_far"
5513 ;; (label_ref (match_operand 0 "" "")))
5514 ;; (use (match_operand 1 "register_operand" "r")]
5516 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5517 ;; [(set_attr "type" "jump")
5518 ;; (set_attr "needs_delay_slot" "yes")])
5520 (define_insn "jump_media"
5522 (match_operand:DI 0 "target_operand" "b"))]
5525 [(set_attr "type" "jump_media")])
5527 (define_expand "jump"
5529 (label_ref (match_operand 0 "" "")))]
5534 emit_jump_insn (gen_jump_compact (operands[0]));
5535 else if (TARGET_SHMEDIA)
5537 if (reload_in_progress || reload_completed)
5539 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5545 (define_insn "force_mode_for_call"
5546 [(use (reg:PSI FPSCR_REG))]
5549 [(set_attr "length" "0")
5550 (set (attr "fp_mode")
5551 (if_then_else (eq_attr "fpu_single" "yes")
5552 (const_string "single") (const_string "double")))])
5554 (define_insn "calli"
5555 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5556 (match_operand 1 "" ""))
5557 (use (reg:PSI FPSCR_REG))
5558 (clobber (reg:SI PR_REG))]
5561 [(set_attr "type" "call")
5562 (set (attr "fp_mode")
5563 (if_then_else (eq_attr "fpu_single" "yes")
5564 (const_string "single") (const_string "double")))
5565 (set_attr "needs_delay_slot" "yes")
5566 (set_attr "fp_set" "unknown")])
5568 ;; This is a pc-rel call, using bsrf, for use with PIC.
5570 (define_insn "calli_pcrel"
5571 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5572 (match_operand 1 "" ""))
5573 (use (reg:PSI FPSCR_REG))
5574 (use (reg:SI PIC_REG))
5575 (use (match_operand 2 "" ""))
5576 (clobber (reg:SI PR_REG))]
5579 [(set_attr "type" "call")
5580 (set (attr "fp_mode")
5581 (if_then_else (eq_attr "fpu_single" "yes")
5582 (const_string "single") (const_string "double")))
5583 (set_attr "needs_delay_slot" "yes")
5584 (set_attr "fp_set" "unknown")])
5586 (define_insn_and_split "call_pcrel"
5587 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5588 (match_operand 1 "" ""))
5589 (use (reg:PSI FPSCR_REG))
5590 (use (reg:SI PIC_REG))
5591 (clobber (reg:SI PR_REG))
5592 (clobber (match_scratch:SI 2 "=r"))]
5599 rtx lab = PATTERN (gen_call_site ());
5601 if (SYMBOL_REF_LOCAL_P (operands[0]))
5602 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5604 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5605 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5608 [(set_attr "type" "call")
5609 (set (attr "fp_mode")
5610 (if_then_else (eq_attr "fpu_single" "yes")
5611 (const_string "single") (const_string "double")))
5612 (set_attr "needs_delay_slot" "yes")
5613 (set_attr "fp_set" "unknown")])
5615 (define_insn "call_compact"
5616 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5617 (match_operand 1 "" ""))
5618 (match_operand 2 "immediate_operand" "n")
5619 (use (reg:SI R0_REG))
5620 (use (reg:SI R1_REG))
5621 (use (reg:PSI FPSCR_REG))
5622 (clobber (reg:SI PR_REG))]
5623 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5625 [(set_attr "type" "call")
5626 (set (attr "fp_mode")
5627 (if_then_else (eq_attr "fpu_single" "yes")
5628 (const_string "single") (const_string "double")))
5629 (set_attr "needs_delay_slot" "yes")])
5631 (define_insn "call_compact_rettramp"
5632 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5633 (match_operand 1 "" ""))
5634 (match_operand 2 "immediate_operand" "n")
5635 (use (reg:SI R0_REG))
5636 (use (reg:SI R1_REG))
5637 (use (reg:PSI FPSCR_REG))
5638 (clobber (reg:SI R10_REG))
5639 (clobber (reg:SI PR_REG))]
5640 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5642 [(set_attr "type" "call")
5643 (set (attr "fp_mode")
5644 (if_then_else (eq_attr "fpu_single" "yes")
5645 (const_string "single") (const_string "double")))
5646 (set_attr "needs_delay_slot" "yes")])
5648 (define_insn "call_media"
5649 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5650 (match_operand 1 "" ""))
5651 (clobber (reg:DI PR_MEDIA_REG))]
5654 [(set_attr "type" "jump_media")])
5656 (define_insn "call_valuei"
5657 [(set (match_operand 0 "" "=rf")
5658 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5659 (match_operand 2 "" "")))
5660 (use (reg:PSI FPSCR_REG))
5661 (clobber (reg:SI PR_REG))]
5664 [(set_attr "type" "call")
5665 (set (attr "fp_mode")
5666 (if_then_else (eq_attr "fpu_single" "yes")
5667 (const_string "single") (const_string "double")))
5668 (set_attr "needs_delay_slot" "yes")
5669 (set_attr "fp_set" "unknown")])
5671 (define_insn "call_valuei_pcrel"
5672 [(set (match_operand 0 "" "=rf")
5673 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5674 (match_operand 2 "" "")))
5675 (use (reg:PSI FPSCR_REG))
5676 (use (reg:SI PIC_REG))
5677 (use (match_operand 3 "" ""))
5678 (clobber (reg:SI PR_REG))]
5681 [(set_attr "type" "call")
5682 (set (attr "fp_mode")
5683 (if_then_else (eq_attr "fpu_single" "yes")
5684 (const_string "single") (const_string "double")))
5685 (set_attr "needs_delay_slot" "yes")
5686 (set_attr "fp_set" "unknown")])
5688 (define_insn_and_split "call_value_pcrel"
5689 [(set (match_operand 0 "" "=rf")
5690 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5691 (match_operand 2 "" "")))
5692 (use (reg:PSI FPSCR_REG))
5693 (use (reg:SI PIC_REG))
5694 (clobber (reg:SI PR_REG))
5695 (clobber (match_scratch:SI 3 "=r"))]
5702 rtx lab = PATTERN (gen_call_site ());
5704 if (SYMBOL_REF_LOCAL_P (operands[1]))
5705 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5707 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5708 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5712 [(set_attr "type" "call")
5713 (set (attr "fp_mode")
5714 (if_then_else (eq_attr "fpu_single" "yes")
5715 (const_string "single") (const_string "double")))
5716 (set_attr "needs_delay_slot" "yes")
5717 (set_attr "fp_set" "unknown")])
5719 (define_insn "call_value_compact"
5720 [(set (match_operand 0 "" "=rf")
5721 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5722 (match_operand 2 "" "")))
5723 (match_operand 3 "immediate_operand" "n")
5724 (use (reg:SI R0_REG))
5725 (use (reg:SI R1_REG))
5726 (use (reg:PSI FPSCR_REG))
5727 (clobber (reg:SI PR_REG))]
5728 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5730 [(set_attr "type" "call")
5731 (set (attr "fp_mode")
5732 (if_then_else (eq_attr "fpu_single" "yes")
5733 (const_string "single") (const_string "double")))
5734 (set_attr "needs_delay_slot" "yes")])
5736 (define_insn "call_value_compact_rettramp"
5737 [(set (match_operand 0 "" "=rf")
5738 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5739 (match_operand 2 "" "")))
5740 (match_operand 3 "immediate_operand" "n")
5741 (use (reg:SI R0_REG))
5742 (use (reg:SI R1_REG))
5743 (use (reg:PSI FPSCR_REG))
5744 (clobber (reg:SI R10_REG))
5745 (clobber (reg:SI PR_REG))]
5746 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5748 [(set_attr "type" "call")
5749 (set (attr "fp_mode")
5750 (if_then_else (eq_attr "fpu_single" "yes")
5751 (const_string "single") (const_string "double")))
5752 (set_attr "needs_delay_slot" "yes")])
5754 (define_insn "call_value_media"
5755 [(set (match_operand 0 "" "=rf")
5756 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5757 (match_operand 2 "" "")))
5758 (clobber (reg:DI PR_MEDIA_REG))]
5761 [(set_attr "type" "jump_media")])
5763 (define_expand "call"
5764 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5765 (match_operand 1 "" ""))
5766 (match_operand 2 "" "")
5767 (use (reg:PSI FPSCR_REG))
5768 (clobber (reg:SI PR_REG))])]
5774 operands[0] = XEXP (operands[0], 0);
5775 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5777 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5779 rtx reg = gen_reg_rtx (Pmode);
5781 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5786 operands[0] = gen_sym2PIC (operands[0]);
5787 PUT_MODE (operands[0], Pmode);
5790 if (GET_MODE (operands[0]) == SImode)
5792 if (GET_CODE (operands[0]) == REG)
5793 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5794 else if (GET_CODE (operands[0]) == SUBREG)
5796 operands[0] = SUBREG_REG (operands[0]);
5797 if (GET_MODE (operands[0]) != DImode)
5798 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5802 operands[0] = shallow_copy_rtx (operands[0]);
5803 PUT_MODE (operands[0], DImode);
5806 if (! target_reg_operand (operands[0], DImode))
5807 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5808 emit_call_insn (gen_call_media (operands[0], operands[1]));
5811 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5813 rtx cookie_rtx = operands[2];
5814 long cookie = INTVAL (cookie_rtx);
5815 rtx func = XEXP (operands[0], 0);
5820 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5822 rtx reg = gen_reg_rtx (Pmode);
5824 emit_insn (gen_symGOTPLT2reg (reg, func));
5828 func = legitimize_pic_address (func, Pmode, 0);
5831 r0 = gen_rtx_REG (SImode, R0_REG);
5832 r1 = gen_rtx_REG (SImode, R1_REG);
5834 /* Since such a call function may use all call-clobbered
5835 registers, we force a mode switch earlier, so that we don't
5836 run out of registers when adjusting fpscr for the call. */
5837 emit_insn (gen_force_mode_for_call ());
5839 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5842 rtx reg = gen_reg_rtx (Pmode);
5844 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5847 operands[0] = force_reg (SImode, operands[0]);
5849 emit_move_insn (r0, func);
5850 emit_move_insn (r1, cookie_rtx);
5852 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5853 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5856 emit_call_insn (gen_call_compact (operands[0], operands[1],
5861 else if (TARGET_SHCOMPACT && flag_pic
5862 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5863 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5865 rtx reg = gen_reg_rtx (Pmode);
5867 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5868 XEXP (operands[0], 0) = reg;
5870 if (flag_pic && TARGET_SH2
5871 && GET_CODE (operands[0]) == MEM
5872 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5874 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5879 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5880 operands[1] = operands[2];
5883 emit_call_insn (gen_calli (operands[0], operands[1]));
5887 (define_insn "call_pop_compact"
5888 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5889 (match_operand 1 "" ""))
5890 (match_operand 2 "immediate_operand" "n")
5891 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5892 (match_operand 3 "immediate_operand" "n")))
5893 (use (reg:SI R0_REG))
5894 (use (reg:SI R1_REG))
5895 (use (reg:PSI FPSCR_REG))
5896 (clobber (reg:SI PR_REG))]
5897 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5899 [(set_attr "type" "call")
5900 (set (attr "fp_mode")
5901 (if_then_else (eq_attr "fpu_single" "yes")
5902 (const_string "single") (const_string "double")))
5903 (set_attr "needs_delay_slot" "yes")])
5905 (define_insn "call_pop_compact_rettramp"
5906 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5907 (match_operand 1 "" ""))
5908 (match_operand 2 "immediate_operand" "n")
5909 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5910 (match_operand 3 "immediate_operand" "n")))
5911 (use (reg:SI R0_REG))
5912 (use (reg:SI R1_REG))
5913 (use (reg:PSI FPSCR_REG))
5914 (clobber (reg:SI R10_REG))
5915 (clobber (reg:SI PR_REG))]
5916 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5918 [(set_attr "type" "call")
5919 (set (attr "fp_mode")
5920 (if_then_else (eq_attr "fpu_single" "yes")
5921 (const_string "single") (const_string "double")))
5922 (set_attr "needs_delay_slot" "yes")])
5924 (define_expand "call_pop"
5925 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5926 (match_operand 1 "" ""))
5927 (match_operand 2 "" "")
5928 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5929 (match_operand 3 "" "")))])]
5933 if (operands[2] && INTVAL (operands[2]))
5935 rtx cookie_rtx = operands[2];
5936 long cookie = INTVAL (cookie_rtx);
5937 rtx func = XEXP (operands[0], 0);
5942 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5944 rtx reg = gen_reg_rtx (Pmode);
5946 emit_insn (gen_symGOTPLT2reg (reg, func));
5950 func = legitimize_pic_address (func, Pmode, 0);
5953 r0 = gen_rtx_REG (SImode, R0_REG);
5954 r1 = gen_rtx_REG (SImode, R1_REG);
5956 /* Since such a call function may use all call-clobbered
5957 registers, we force a mode switch earlier, so that we don't
5958 run out of registers when adjusting fpscr for the call. */
5959 emit_insn (gen_force_mode_for_call ());
5961 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5964 rtx reg = gen_reg_rtx (Pmode);
5966 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5969 operands[0] = force_reg (SImode, operands[0]);
5971 emit_move_insn (r0, func);
5972 emit_move_insn (r1, cookie_rtx);
5974 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5975 emit_call_insn (gen_call_pop_compact_rettramp
5976 (operands[0], operands[1], operands[2], operands[3]));
5978 emit_call_insn (gen_call_pop_compact
5979 (operands[0], operands[1], operands[2], operands[3]));
5987 (define_expand "call_value"
5988 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5989 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5990 (match_operand 2 "" "")))
5991 (match_operand 3 "" "")
5992 (use (reg:PSI FPSCR_REG))
5993 (clobber (reg:SI PR_REG))])]
5999 operands[1] = XEXP (operands[1], 0);
6000 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6002 if (! SYMBOL_REF_LOCAL_P (operands[1]))
6004 rtx reg = gen_reg_rtx (Pmode);
6006 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6011 operands[1] = gen_sym2PIC (operands[1]);
6012 PUT_MODE (operands[1], Pmode);
6015 if (GET_MODE (operands[1]) == SImode)
6017 if (GET_CODE (operands[1]) == REG)
6018 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6019 else if (GET_CODE (operands[1]) == SUBREG)
6021 operands[1] = SUBREG_REG (operands[1]);
6022 if (GET_MODE (operands[1]) != DImode)
6023 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6027 operands[1] = shallow_copy_rtx (operands[1]);
6028 PUT_MODE (operands[1], DImode);
6031 if (! target_reg_operand (operands[1], DImode))
6032 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6033 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6037 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6039 rtx cookie_rtx = operands[3];
6040 long cookie = INTVAL (cookie_rtx);
6041 rtx func = XEXP (operands[1], 0);
6046 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6048 rtx reg = gen_reg_rtx (Pmode);
6050 emit_insn (gen_symGOTPLT2reg (reg, func));
6054 func = legitimize_pic_address (func, Pmode, 0);
6057 r0 = gen_rtx_REG (SImode, R0_REG);
6058 r1 = gen_rtx_REG (SImode, R1_REG);
6060 /* Since such a call function may use all call-clobbered
6061 registers, we force a mode switch earlier, so that we don't
6062 run out of registers when adjusting fpscr for the call. */
6063 emit_insn (gen_force_mode_for_call ());
6065 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6068 rtx reg = gen_reg_rtx (Pmode);
6070 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6073 operands[1] = force_reg (SImode, operands[1]);
6075 emit_move_insn (r0, func);
6076 emit_move_insn (r1, cookie_rtx);
6078 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6079 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6084 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6085 operands[2], operands[3]));
6089 else if (TARGET_SHCOMPACT && flag_pic
6090 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6091 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6093 rtx reg = gen_reg_rtx (Pmode);
6095 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6096 XEXP (operands[1], 0) = reg;
6098 if (flag_pic && TARGET_SH2
6099 && GET_CODE (operands[1]) == MEM
6100 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6102 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6107 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6109 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6113 (define_insn "sibcalli"
6114 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6115 (match_operand 1 "" ""))
6116 (use (reg:PSI FPSCR_REG))
6120 [(set_attr "needs_delay_slot" "yes")
6121 (set (attr "fp_mode")
6122 (if_then_else (eq_attr "fpu_single" "yes")
6123 (const_string "single") (const_string "double")))
6124 (set_attr "type" "jump_ind")])
6126 (define_insn "sibcalli_pcrel"
6127 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6128 (match_operand 1 "" ""))
6129 (use (match_operand 2 "" ""))
6130 (use (reg:PSI FPSCR_REG))
6134 [(set_attr "needs_delay_slot" "yes")
6135 (set (attr "fp_mode")
6136 (if_then_else (eq_attr "fpu_single" "yes")
6137 (const_string "single") (const_string "double")))
6138 (set_attr "type" "jump_ind")])
6140 (define_insn_and_split "sibcall_pcrel"
6141 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6142 (match_operand 1 "" ""))
6143 (use (reg:PSI FPSCR_REG))
6144 (clobber (match_scratch:SI 2 "=k"))
6152 rtx lab = PATTERN (gen_call_site ());
6155 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6156 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6158 SIBLING_CALL_P (call_insn) = 1;
6161 [(set_attr "needs_delay_slot" "yes")
6162 (set (attr "fp_mode")
6163 (if_then_else (eq_attr "fpu_single" "yes")
6164 (const_string "single") (const_string "double")))
6165 (set_attr "type" "jump_ind")])
6167 (define_insn "sibcall_compact"
6168 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6169 (match_operand 1 "" ""))
6171 (use (match_operand:SI 2 "register_operand" "z,x"))
6172 (use (reg:SI R1_REG))
6173 (use (reg:PSI FPSCR_REG))
6174 ;; We want to make sure the `x' above will only match MACH_REG
6175 ;; because sibcall_epilogue may clobber MACL_REG.
6176 (clobber (reg:SI MACL_REG))]
6180 jmp @%0\\n sts %2, r0"
6181 [(set_attr "needs_delay_slot" "yes,no")
6182 (set_attr "length" "2,4")
6183 (set (attr "fp_mode") (const_string "single"))
6184 (set_attr "type" "jump_ind")])
6186 (define_insn "sibcall_media"
6187 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6188 (match_operand 1 "" ""))
6189 (use (reg:SI PR_MEDIA_REG))
6193 [(set_attr "type" "jump_media")])
6195 (define_expand "sibcall"
6197 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6198 (match_operand 1 "" ""))
6199 (match_operand 2 "" "")
6200 (use (reg:PSI FPSCR_REG))
6207 operands[0] = XEXP (operands[0], 0);
6208 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6210 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6212 rtx reg = gen_reg_rtx (Pmode);
6214 /* We must not use GOTPLT for sibcalls, because PIC_REG
6215 must be restored before the PLT code gets to run. */
6216 emit_insn (gen_symGOT2reg (reg, operands[0]));
6221 operands[0] = gen_sym2PIC (operands[0]);
6222 PUT_MODE (operands[0], Pmode);
6225 if (GET_MODE (operands[0]) == SImode)
6227 if (GET_CODE (operands[0]) == REG)
6228 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6229 else if (GET_CODE (operands[0]) == SUBREG)
6231 operands[0] = SUBREG_REG (operands[0]);
6232 if (GET_MODE (operands[0]) != DImode)
6233 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6237 operands[0] = shallow_copy_rtx (operands[0]);
6238 PUT_MODE (operands[0], DImode);
6241 if (! target_reg_operand (operands[0], DImode))
6242 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6243 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6246 else if (TARGET_SHCOMPACT && operands[2]
6247 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6249 rtx cookie_rtx = operands[2];
6250 long cookie = INTVAL (cookie_rtx);
6251 rtx func = XEXP (operands[0], 0);
6256 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6258 rtx reg = gen_reg_rtx (Pmode);
6260 emit_insn (gen_symGOT2reg (reg, func));
6264 func = legitimize_pic_address (func, Pmode, 0);
6267 /* FIXME: if we could tell whether all argument registers are
6268 already taken, we could decide whether to force the use of
6269 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6270 simple way to tell. We could use the CALL_COOKIE, but we
6271 can't currently tell a register used for regular argument
6272 passing from one that is unused. If we leave it up to reload
6273 to decide which register to use, it seems to always choose
6274 R0_REG, which leaves no available registers in SIBCALL_REGS
6275 to hold the address of the trampoline. */
6276 mach = gen_rtx_REG (SImode, MACH_REG);
6277 r1 = gen_rtx_REG (SImode, R1_REG);
6279 /* Since such a call function may use all call-clobbered
6280 registers, we force a mode switch earlier, so that we don't
6281 run out of registers when adjusting fpscr for the call. */
6282 emit_insn (gen_force_mode_for_call ());
6284 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6287 rtx reg = gen_reg_rtx (Pmode);
6289 emit_insn (gen_symGOT2reg (reg, operands[0]));
6292 operands[0] = force_reg (SImode, operands[0]);
6294 /* We don't need a return trampoline, since the callee will
6295 return directly to the upper caller. */
6296 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6298 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6299 cookie_rtx = GEN_INT (cookie);
6302 emit_move_insn (mach, func);
6303 emit_move_insn (r1, cookie_rtx);
6305 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6308 else if (TARGET_SHCOMPACT && flag_pic
6309 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6310 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6312 rtx reg = gen_reg_rtx (Pmode);
6314 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6315 XEXP (operands[0], 0) = reg;
6317 if (flag_pic && TARGET_SH2
6318 && GET_CODE (operands[0]) == MEM
6319 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6320 /* The PLT needs the PIC register, but the epilogue would have
6321 to restore it, so we can only use PC-relative PIC calls for
6322 static functions. */
6323 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6325 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6329 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6331 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6335 (define_expand "sibcall_value"
6336 [(set (match_operand 0 "" "")
6337 (call (match_operand 1 "" "")
6338 (match_operand 2 "" "")))
6339 (match_operand 3 "" "")]
6343 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6347 (define_insn "call_value_pop_compact"
6348 [(set (match_operand 0 "" "=rf")
6349 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6350 (match_operand 2 "" "")))
6351 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6352 (match_operand 4 "immediate_operand" "n")))
6353 (match_operand 3 "immediate_operand" "n")
6354 (use (reg:SI R0_REG))
6355 (use (reg:SI R1_REG))
6356 (use (reg:PSI FPSCR_REG))
6357 (clobber (reg:SI PR_REG))]
6358 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6360 [(set_attr "type" "call")
6361 (set (attr "fp_mode")
6362 (if_then_else (eq_attr "fpu_single" "yes")
6363 (const_string "single") (const_string "double")))
6364 (set_attr "needs_delay_slot" "yes")])
6366 (define_insn "call_value_pop_compact_rettramp"
6367 [(set (match_operand 0 "" "=rf")
6368 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6369 (match_operand 2 "" "")))
6370 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6371 (match_operand 4 "immediate_operand" "n")))
6372 (match_operand 3 "immediate_operand" "n")
6373 (use (reg:SI R0_REG))
6374 (use (reg:SI R1_REG))
6375 (use (reg:PSI FPSCR_REG))
6376 (clobber (reg:SI R10_REG))
6377 (clobber (reg:SI PR_REG))]
6378 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6380 [(set_attr "type" "call")
6381 (set (attr "fp_mode")
6382 (if_then_else (eq_attr "fpu_single" "yes")
6383 (const_string "single") (const_string "double")))
6384 (set_attr "needs_delay_slot" "yes")])
6386 (define_expand "call_value_pop"
6387 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6388 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6389 (match_operand 2 "" "")))
6390 (match_operand 3 "" "")
6391 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6392 (match_operand 4 "" "")))])]
6396 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6398 rtx cookie_rtx = operands[3];
6399 long cookie = INTVAL (cookie_rtx);
6400 rtx func = XEXP (operands[1], 0);
6405 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6407 rtx reg = gen_reg_rtx (Pmode);
6409 emit_insn (gen_symGOTPLT2reg (reg, func));
6413 func = legitimize_pic_address (func, Pmode, 0);
6416 r0 = gen_rtx_REG (SImode, R0_REG);
6417 r1 = gen_rtx_REG (SImode, R1_REG);
6419 /* Since such a call function may use all call-clobbered
6420 registers, we force a mode switch earlier, so that we don't
6421 run out of registers when adjusting fpscr for the call. */
6422 emit_insn (gen_force_mode_for_call ());
6424 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6427 rtx reg = gen_reg_rtx (Pmode);
6429 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6432 operands[1] = force_reg (SImode, operands[1]);
6434 emit_move_insn (r0, func);
6435 emit_move_insn (r1, cookie_rtx);
6437 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6438 emit_call_insn (gen_call_value_pop_compact_rettramp
6439 (operands[0], operands[1], operands[2],
6440 operands[3], operands[4]));
6442 emit_call_insn (gen_call_value_pop_compact
6443 (operands[0], operands[1], operands[2],
6444 operands[3], operands[4]));
6452 (define_expand "sibcall_epilogue"
6457 sh_expand_epilogue (1);
6458 if (TARGET_SHCOMPACT)
6462 /* If epilogue clobbers r0, preserve it in macl. */
6463 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6464 if ((set = single_set (insn))
6465 && GET_CODE (SET_DEST (set)) == REG
6466 && REGNO (SET_DEST (set)) == R0_REG)
6468 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6469 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6472 /* We can't tell at this point whether the sibcall is a
6473 sibcall_compact and, if it is, whether it uses r0 or
6474 mach as operand 2, so let the instructions that
6475 preserve r0 be optimized away if r0 turns out to be
6477 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6478 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6480 i = emit_move_insn (r0, tmp);
6481 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6489 (define_insn "indirect_jump_compact"
6491 (match_operand:SI 0 "arith_reg_operand" "r"))]
6494 [(set_attr "needs_delay_slot" "yes")
6495 (set_attr "type" "jump_ind")])
6497 (define_expand "indirect_jump"
6499 (match_operand 0 "register_operand" ""))]
6503 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6504 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6507 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6508 ;; which can be present in structured code from indirect jumps which can not
6509 ;; be present in structured code. This allows -fprofile-arcs to work.
6511 ;; For SH1 processors.
6512 (define_insn "casesi_jump_1"
6514 (match_operand:SI 0 "register_operand" "r"))
6515 (use (label_ref (match_operand 1 "" "")))]
6518 [(set_attr "needs_delay_slot" "yes")
6519 (set_attr "type" "jump_ind")])
6521 ;; For all later processors.
6522 (define_insn "casesi_jump_2"
6523 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6524 (label_ref (match_operand 1 "" ""))))
6525 (use (label_ref (match_operand 2 "" "")))]
6527 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6529 [(set_attr "needs_delay_slot" "yes")
6530 (set_attr "type" "jump_ind")])
6532 (define_insn "casesi_jump_media"
6533 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6534 (use (label_ref (match_operand 1 "" "")))]
6537 [(set_attr "type" "jump_media")])
6539 ;; Call subroutine returning any type.
6540 ;; ??? This probably doesn't work.
6542 (define_expand "untyped_call"
6543 [(parallel [(call (match_operand 0 "" "")
6545 (match_operand 1 "" "")
6546 (match_operand 2 "" "")])]
6547 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6552 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6554 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6556 rtx set = XVECEXP (operands[2], 0, i);
6557 emit_move_insn (SET_DEST (set), SET_SRC (set));
6560 /* The optimizer does not know that the call sets the function value
6561 registers we stored in the result block. We avoid problems by
6562 claiming that all hard registers are used and clobbered at this
6564 emit_insn (gen_blockage ());
6569 ;; ------------------------------------------------------------------------
6571 ;; ------------------------------------------------------------------------
6574 [(set (reg:SI T_REG)
6575 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6576 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6579 [(set_attr "type" "arith")])
6586 ;; Load address of a label. This is only generated by the casesi expand,
6587 ;; and by machine_dependent_reorg (fixing up fp moves).
6588 ;; This must use unspec, because this only works for labels that are
6592 [(set (reg:SI R0_REG)
6593 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6596 [(set_attr "in_delay_slot" "no")
6597 (set_attr "type" "arith")])
6599 ;; machine_dependent_reorg will make this a `mova'.
6600 (define_insn "mova_const"
6601 [(set (reg:SI R0_REG)
6602 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6605 [(set_attr "in_delay_slot" "no")
6606 (set_attr "type" "arith")])
6608 (define_expand "GOTaddr2picreg"
6609 [(set (reg:SI R0_REG)
6610 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6612 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6613 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6616 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6617 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6620 operands[1] = gen_datalabel_ref (operands[1]);
6624 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6625 rtx dipic = operands[0];
6626 rtx lab = PATTERN (gen_call_site ());
6629 equiv = operands[1];
6630 operands[1] = gen_rtx_MINUS (DImode,
6634 gen_rtx_MINUS (DImode,
6635 gen_rtx_CONST (DImode,
6638 operands[1] = gen_sym2PIC (operands[1]);
6639 PUT_MODE (operands[1], DImode);
6641 if (GET_MODE (dipic) != DImode)
6642 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6644 if (TARGET_SHMEDIA64)
6645 emit_insn (gen_movdi_const (dipic, operands[1]));
6647 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6649 emit_insn (gen_ptrel (tr, dipic, lab));
6651 if (GET_MODE (operands[0]) != GET_MODE (tr))
6652 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6654 insn = emit_move_insn (operands[0], tr);
6656 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6665 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6666 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6667 UNSPEC_DATALABEL)))]
6668 "TARGET_SHMEDIA && flag_pic
6669 && EXTRA_CONSTRAINT_Csy (operands[1])"
6670 "ptb/u datalabel %1, %0"
6671 [(set_attr "type" "pt_media")
6672 (set_attr "length" "*")])
6674 (define_insn "ptrel"
6675 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6676 (plus:DI (match_operand:DI 1 "register_operand" "r")
6678 (match_operand:DI 2 "" "")]
6680 "%O2: ptrel/u %1, %0"
6681 [(set_attr "type" "ptabs_media")])
6683 (define_expand "builtin_setjmp_receiver"
6684 [(match_operand 0 "" "")]
6688 emit_insn (gen_GOTaddr2picreg ());
6692 (define_expand "call_site"
6693 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6697 static HOST_WIDE_INT i = 0;
6698 operands[0] = GEN_INT (i);
6702 (define_expand "sym_label2reg"
6703 [(set (match_operand:SI 0 "" "")
6706 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6709 (match_operand:SI 2 "" "")
6713 (define_expand "symGOT_load"
6714 [(set (match_dup 2) (match_operand 1 "" ""))
6715 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6716 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6722 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6723 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6727 rtx reg = operands[2];
6729 if (GET_MODE (reg) != DImode)
6730 reg = gen_rtx_SUBREG (DImode, reg, 0);
6733 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6735 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6738 emit_move_insn (operands[2], operands[1]);
6740 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6742 gen_rtx_REG (Pmode, PIC_REG)));
6744 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6746 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6753 (define_expand "sym2GOT"
6754 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6758 (define_expand "symGOT2reg"
6759 [(match_operand 0 "" "") (match_operand 1 "" "")]
6765 gotsym = gen_sym2GOT (operands[1]);
6766 PUT_MODE (gotsym, Pmode);
6767 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6769 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6774 (define_expand "sym2GOTPLT"
6775 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6779 (define_expand "symGOTPLT2reg"
6780 [(match_operand 0 "" "") (match_operand 1 "" "")]
6784 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6788 (define_expand "sym2GOTOFF"
6789 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6793 (define_expand "symGOTOFF2reg"
6794 [(match_operand 0 "" "") (match_operand 1 "" "")]
6798 rtx gotoffsym, insn;
6799 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6801 gotoffsym = gen_sym2GOTOFF (operands[1]);
6802 PUT_MODE (gotoffsym, Pmode);
6803 emit_move_insn (t, gotoffsym);
6804 insn = emit_move_insn (operands[0],
6805 gen_rtx_PLUS (Pmode, t,
6806 gen_rtx_REG (Pmode, PIC_REG)));
6808 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6814 (define_expand "symPLT_label2reg"
6815 [(set (match_operand:SI 0 "" "")
6818 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6822 (match_operand:SI 2 "" "")
6824 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6825 ;; Even though the PIC register is not really used by the call
6826 ;; sequence in which this is expanded, the PLT code assumes the PIC
6827 ;; register is set, so we must not skip its initialization. Since
6828 ;; we only use this expand as part of calling sequences, and never
6829 ;; to take the address of a function, this is the best point to
6830 ;; insert the (use). Using the PLT to take the address of a
6831 ;; function would be wrong, not only because the PLT entry could
6832 ;; then be called from a function that doesn't initialize the PIC
6833 ;; register to the proper GOT, but also because pointers to the
6834 ;; same function might not compare equal, should they be set by
6835 ;; different shared libraries.
6836 (use (reg:SI PIC_REG))]
6840 (define_expand "sym2PIC"
6841 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6845 ;; TLS code generation.
6846 ;; ??? this should be a define_insn_and_split
6847 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6848 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6851 (define_insn "tls_global_dynamic"
6852 [(set (match_operand:SI 0 "register_operand" "=&z")
6853 (call (unspec:SI [(match_operand:SI 1 "" "")]
6856 (use (reg:PSI FPSCR_REG))
6857 (use (reg:SI PIC_REG))
6858 (clobber (reg:SI PR_REG))
6859 (clobber (scratch:SI))]
6865 \\tmova\\t2f,r0\\n\\
6866 \\tmov.l\\t2f,r1\\n\\
6869 \\tadd\\tr12,r4\\n\\
6873 1:\\t.long\\t%a1@TLSGD\\n\\
6874 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6877 [(set_attr "type" "tls_load")
6878 (set_attr "length" "26")])
6880 (define_insn "tls_local_dynamic"
6881 [(set (match_operand:SI 0 "register_operand" "=&z")
6882 (call (unspec:SI [(match_operand:SI 1 "" "")]
6885 (use (reg:PSI FPSCR_REG))
6886 (use (reg:SI PIC_REG))
6887 (clobber (reg:SI PR_REG))
6888 (clobber (scratch:SI))]
6894 \\tmova\\t2f,r0\\n\\
6895 \\tmov.l\\t2f,r1\\n\\
6898 \\tadd\\tr12,r4\\n\\
6902 1:\\t.long\\t%a1@TLSLDM\\n\\
6903 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6906 [(set_attr "type" "tls_load")
6907 (set_attr "length" "26")])
6909 (define_expand "sym2DTPOFF"
6910 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6914 (define_expand "symDTPOFF2reg"
6915 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6919 rtx dtpoffsym, insn;
6920 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6922 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6923 PUT_MODE (dtpoffsym, Pmode);
6924 emit_move_insn (t, dtpoffsym);
6925 insn = emit_move_insn (operands[0],
6926 gen_rtx_PLUS (Pmode, t, operands[2]));
6930 (define_expand "sym2GOTTPOFF"
6931 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6935 (define_insn "tls_initial_exec"
6936 [(set (match_operand:SI 0 "register_operand" "=&r")
6937 (unspec:SI [(match_operand:SI 1 "" "")]
6939 (use (reg:SI GBR_REG))
6940 (use (reg:SI PIC_REG))
6941 (clobber (reg:SI R0_REG))]
6947 \\tstc\\tgbr,%0\\n\\
6948 \\tmov.l\\t@(r0,r12),r0\\n\\
6952 1:\\t.long\\t%a1\\n\\
6955 [(set_attr "type" "tls_load")
6956 (set_attr "length" "16")])
6958 (define_expand "sym2TPOFF"
6959 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6963 (define_expand "symTPOFF2reg"
6964 [(match_operand 0 "" "") (match_operand 1 "" "")]
6970 tpoffsym = gen_sym2TPOFF (operands[1]);
6971 PUT_MODE (tpoffsym, Pmode);
6972 insn = emit_move_insn (operands[0], tpoffsym);
6976 (define_insn "load_gbr"
6977 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6978 (use (reg:SI GBR_REG))]
6981 [(set_attr "type" "tls_load")])
6983 ;; case instruction for switch statements.
6985 ;; Operand 0 is index
6986 ;; operand 1 is the minimum bound
6987 ;; operand 2 is the maximum bound - minimum bound + 1
6988 ;; operand 3 is CODE_LABEL for the table;
6989 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6991 (define_expand "casesi"
6992 [(match_operand:SI 0 "arith_reg_operand" "")
6993 (match_operand:SI 1 "arith_reg_operand" "")
6994 (match_operand:SI 2 "arith_reg_operand" "")
6995 (match_operand 3 "" "") (match_operand 4 "" "")]
6999 rtx reg = gen_reg_rtx (SImode);
7000 rtx reg2 = gen_reg_rtx (SImode);
7003 rtx reg = gen_reg_rtx (DImode);
7004 rtx reg2 = gen_reg_rtx (DImode);
7005 rtx reg3 = gen_reg_rtx (DImode);
7006 rtx reg4 = gen_reg_rtx (DImode);
7007 rtx reg5 = gen_reg_rtx (DImode);
7009 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7010 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7011 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7013 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7014 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7015 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7016 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7017 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7018 (DImode, operands[3])));
7019 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7020 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7021 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7025 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7026 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7027 /* If optimizing, casesi_worker depends on the mode of the instruction
7028 before label it 'uses' - operands[3]. */
7029 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7031 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7033 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7035 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7036 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7037 operands[3], but to lab. We will fix this up in
7038 machine_dependent_reorg. */
7043 (define_expand "casesi_0"
7044 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7045 (set (match_dup 4) (minus:SI (match_dup 4)
7046 (match_operand:SI 1 "arith_operand" "")))
7048 (gtu:SI (match_dup 4)
7049 (match_operand:SI 2 "arith_reg_operand" "")))
7051 (if_then_else (ne (reg:SI T_REG)
7053 (label_ref (match_operand 3 "" ""))
7058 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7059 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7060 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7062 (define_insn "casesi_worker_0"
7063 [(set (match_operand:SI 0 "register_operand" "=r,r")
7064 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7065 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7066 (clobber (match_scratch:SI 3 "=X,1"))
7067 (clobber (match_scratch:SI 4 "=&z,z"))]
7072 [(set (match_operand:SI 0 "register_operand" "")
7073 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7074 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7075 (clobber (match_scratch:SI 3 ""))
7076 (clobber (match_scratch:SI 4 ""))]
7077 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7078 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7079 (parallel [(set (match_dup 0)
7080 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7081 (label_ref (match_dup 2))] UNSPEC_CASESI))
7082 (clobber (match_dup 3))])
7083 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7084 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7087 [(set (match_operand:SI 0 "register_operand" "")
7088 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7089 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7090 (clobber (match_scratch:SI 3 ""))
7091 (clobber (match_scratch:SI 4 ""))]
7092 "TARGET_SH2 && reload_completed"
7093 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7094 (parallel [(set (match_dup 0)
7095 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7096 (label_ref (match_dup 2))] UNSPEC_CASESI))
7097 (clobber (match_dup 3))])]
7098 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7100 (define_insn "casesi_worker_1"
7101 [(set (match_operand:SI 0 "register_operand" "=r,r")
7102 (unspec:SI [(reg:SI R0_REG)
7103 (match_operand:SI 1 "register_operand" "0,r")
7104 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7105 (clobber (match_scratch:SI 3 "=X,1"))]
7109 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7111 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7114 switch (GET_MODE (diff_vec))
7117 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7119 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7121 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7122 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7123 return \"mov.b @(r0,%1),%0\";
7128 [(set_attr "length" "4")])
7130 (define_insn "casesi_worker_2"
7131 [(set (match_operand:SI 0 "register_operand" "=r,r")
7132 (unspec:SI [(reg:SI R0_REG)
7133 (match_operand:SI 1 "register_operand" "0,r")
7134 (label_ref (match_operand 2 "" ""))
7135 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7136 (clobber (match_operand:SI 4 "" "=X,1"))]
7137 "TARGET_SH2 && reload_completed && flag_pic"
7140 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7143 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7146 switch (GET_MODE (diff_vec))
7149 output_asm_insn (\"shll2 %1\", operands);
7150 load = \"mov.l @(r0,%1),%0\"; break;
7152 output_asm_insn (\"add %1,%1\", operands);
7153 load = \"mov.w @(r0,%1),%0\"; break;
7155 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7156 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7158 load = \"mov.b @(r0,%1),%0\";
7163 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7166 [(set_attr "length" "8")])
7168 (define_insn "casesi_shift_media"
7169 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7170 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7171 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7176 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7178 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7181 switch (GET_MODE (diff_vec))
7184 return \"shlli %1, 2, %0\";
7186 return \"shlli %1, 1, %0\";
7188 if (rtx_equal_p (operands[0], operands[1]))
7190 return \"add %1, r63, %0\";
7195 [(set_attr "type" "arith_media")])
7197 (define_insn "casesi_load_media"
7198 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7199 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7200 (match_operand 2 "arith_reg_operand" "r")
7201 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7205 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7207 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7210 switch (GET_MODE (diff_vec))
7213 return \"ldx.l %1, %2, %0\";
7216 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7217 return \"ldx.uw %1, %2, %0\";
7219 return \"ldx.w %1, %2, %0\";
7221 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7222 return \"ldx.ub %1, %2, %0\";
7223 return \"ldx.b %1, %2, %0\";
7228 [(set_attr "type" "load_media")])
7230 (define_expand "return"
7232 "reload_completed && ! sh_need_epilogue ()"
7237 emit_jump_insn (gen_return_media ());
7241 if (TARGET_SHCOMPACT
7242 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7244 emit_jump_insn (gen_shcompact_return_tramp ());
7249 (define_insn "*return_i"
7251 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7252 && (current_function_args_info.call_cookie
7253 & CALL_COOKIE_RET_TRAMP (1)))
7254 && reload_completed"
7256 [(set_attr "type" "return")
7257 (set_attr "needs_delay_slot" "yes")])
7259 (define_expand "shcompact_return_tramp"
7262 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7265 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7266 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7269 emit_insn (gen_symGOTPLT2reg (reg, sym));
7271 emit_move_insn (reg, sym);
7273 emit_jump_insn (gen_shcompact_return_tramp_i ());
7277 (define_insn "shcompact_return_tramp_i"
7278 [(parallel [(return) (use (reg:SI R0_REG))])]
7280 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7282 [(set_attr "type" "jump_ind")
7283 (set_attr "needs_delay_slot" "yes")])
7285 (define_insn "return_media_i"
7286 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7287 "TARGET_SHMEDIA && reload_completed"
7289 [(set_attr "type" "jump_media")])
7291 (define_insn "return_media_rte"
7293 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7295 [(set_attr "type" "jump_media")])
7297 (define_expand "return_media"
7299 "TARGET_SHMEDIA && reload_completed"
7302 int tr_regno = sh_media_register_for_return ();
7305 if (current_function_interrupt)
7307 emit_jump_insn (gen_return_media_rte ());
7312 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7314 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7317 tr = gen_rtx_REG (DImode, tr_regno);
7318 emit_move_insn (tr, r18);
7321 tr = gen_rtx_REG (DImode, tr_regno);
7323 emit_jump_insn (gen_return_media_i (tr));
7327 (define_insn "shcompact_preserve_incoming_args"
7328 [(set (match_operand:SI 0 "register_operand" "+r")
7329 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7332 [(set_attr "length" "0")])
7334 (define_insn "shcompact_incoming_args"
7335 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7336 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7337 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7338 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7339 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7340 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7341 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7342 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7343 (set (mem:BLK (reg:SI MACL_REG))
7344 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7345 (use (reg:SI R0_REG))
7346 (clobber (reg:SI R0_REG))
7347 (clobber (reg:SI MACL_REG))
7348 (clobber (reg:SI MACH_REG))
7349 (clobber (reg:SI PR_REG))]
7352 [(set_attr "needs_delay_slot" "yes")])
7354 (define_insn "shmedia_save_restore_regs_compact"
7355 [(set (reg:SI SP_REG)
7356 (plus:SI (reg:SI SP_REG)
7357 (match_operand:SI 0 "immediate_operand" "i")))
7358 (use (reg:SI R0_REG))
7359 (clobber (reg:SI PR_REG))]
7361 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7362 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7364 [(set_attr "needs_delay_slot" "yes")])
7366 (define_expand "prologue"
7369 "sh_expand_prologue (); DONE;")
7371 (define_expand "epilogue"
7376 sh_expand_epilogue (0);
7377 emit_jump_insn (gen_return ());
7381 (define_expand "eh_return"
7382 [(use (match_operand 0 "register_operand" ""))]
7385 rtx ra = operands[0];
7387 if (TARGET_SHMEDIA64)
7388 emit_insn (gen_eh_set_ra_di (ra));
7390 emit_insn (gen_eh_set_ra_si (ra));
7395 ;; Clobber the return address on the stack. We can't expand this
7396 ;; until we know where it will be put in the stack frame.
7398 (define_insn "eh_set_ra_si"
7399 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7400 (clobber (match_scratch:SI 1 "=&r"))]
7401 "! TARGET_SHMEDIA64"
7404 (define_insn "eh_set_ra_di"
7405 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7406 (clobber (match_scratch:DI 1 "=&r"))]
7411 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7412 (clobber (match_scratch 1 ""))]
7417 sh_set_return_address (operands[0], operands[1]);
7421 (define_insn "blockage"
7422 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7425 [(set_attr "length" "0")])
7427 ;; ------------------------------------------------------------------------
7429 ;; ------------------------------------------------------------------------
7432 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7433 (eq:SI (reg:SI T_REG) (const_int 1)))]
7436 [(set_attr "type" "arith")])
7438 (define_expand "seq"
7439 [(set (match_operand:SI 0 "arith_reg_operand" "")
7446 if (GET_MODE (operands[0]) != DImode)
7447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7448 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7449 if (sh_compare_op1 != const0_rtx)
7450 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7451 ? GET_MODE (sh_compare_op0)
7452 : GET_MODE (sh_compare_op1),
7455 switch (GET_MODE (sh_compare_op0))
7458 emit_insn (gen_cmpeqdi_media (operands[0],
7459 sh_compare_op0, sh_compare_op1));
7463 if (! TARGET_SHMEDIA_FPU)
7465 emit_insn (gen_cmpeqsf_media (operands[0],
7466 sh_compare_op0, sh_compare_op1));
7470 if (! TARGET_SHMEDIA_FPU)
7472 emit_insn (gen_cmpeqdf_media (operands[0],
7473 sh_compare_op0, sh_compare_op1));
7481 if (sh_expand_t_scc (EQ, operands[0]))
7483 if (! currently_expanding_to_rtl)
7485 operands[1] = prepare_scc_operands (EQ);
7488 (define_expand "slt"
7489 [(set (match_operand:SI 0 "arith_reg_operand" "")
7496 if (GET_MODE (operands[0]) != DImode)
7497 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7498 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7499 if (sh_compare_op1 != const0_rtx)
7500 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7501 ? GET_MODE (sh_compare_op0)
7502 : GET_MODE (sh_compare_op1),
7505 switch (GET_MODE (sh_compare_op0))
7508 emit_insn (gen_cmpgtdi_media (operands[0],
7509 sh_compare_op1, sh_compare_op0));
7513 if (! TARGET_SHMEDIA_FPU)
7515 emit_insn (gen_cmpgtsf_media (operands[0],
7516 sh_compare_op1, sh_compare_op0));
7520 if (! TARGET_SHMEDIA_FPU)
7522 emit_insn (gen_cmpgtdf_media (operands[0],
7523 sh_compare_op1, sh_compare_op0));
7531 if (! currently_expanding_to_rtl)
7533 operands[1] = prepare_scc_operands (LT);
7536 (define_expand "sle"
7537 [(match_operand:SI 0 "arith_reg_operand" "")]
7541 rtx tmp = sh_compare_op0;
7545 if (GET_MODE (operands[0]) != DImode)
7546 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7547 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7548 if (sh_compare_op1 != const0_rtx)
7549 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7550 ? GET_MODE (sh_compare_op0)
7551 : GET_MODE (sh_compare_op1),
7554 switch (GET_MODE (sh_compare_op0))
7558 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7560 emit_insn (gen_cmpgtdi_media (tmp,
7561 sh_compare_op0, sh_compare_op1));
7562 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7567 if (! TARGET_SHMEDIA_FPU)
7569 emit_insn (gen_cmpgesf_media (operands[0],
7570 sh_compare_op1, sh_compare_op0));
7574 if (! TARGET_SHMEDIA_FPU)
7576 emit_insn (gen_cmpgedf_media (operands[0],
7577 sh_compare_op1, sh_compare_op0));
7586 sh_compare_op0 = sh_compare_op1;
7587 sh_compare_op1 = tmp;
7588 emit_insn (gen_sge (operands[0]));
7592 (define_expand "sgt"
7593 [(set (match_operand:SI 0 "arith_reg_operand" "")
7600 if (GET_MODE (operands[0]) != DImode)
7601 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7602 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7603 if (sh_compare_op1 != const0_rtx)
7604 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7605 ? GET_MODE (sh_compare_op0)
7606 : GET_MODE (sh_compare_op1),
7609 switch (GET_MODE (sh_compare_op0))
7612 emit_insn (gen_cmpgtdi_media (operands[0],
7613 sh_compare_op0, sh_compare_op1));
7617 if (! TARGET_SHMEDIA_FPU)
7619 emit_insn (gen_cmpgtsf_media (operands[0],
7620 sh_compare_op0, sh_compare_op1));
7624 if (! TARGET_SHMEDIA_FPU)
7626 emit_insn (gen_cmpgtdf_media (operands[0],
7627 sh_compare_op0, sh_compare_op1));
7635 if (! currently_expanding_to_rtl)
7637 operands[1] = prepare_scc_operands (GT);
7640 (define_expand "sge"
7641 [(set (match_operand:SI 0 "arith_reg_operand" "")
7648 if (GET_MODE (operands[0]) != DImode)
7649 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7650 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7651 if (sh_compare_op1 != const0_rtx)
7652 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7653 ? GET_MODE (sh_compare_op0)
7654 : GET_MODE (sh_compare_op1),
7657 switch (GET_MODE (sh_compare_op0))
7661 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7663 emit_insn (gen_cmpgtdi_media (tmp,
7664 sh_compare_op1, sh_compare_op0));
7665 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7670 if (! TARGET_SHMEDIA_FPU)
7672 emit_insn (gen_cmpgesf_media (operands[0],
7673 sh_compare_op0, sh_compare_op1));
7677 if (! TARGET_SHMEDIA_FPU)
7679 emit_insn (gen_cmpgedf_media (operands[0],
7680 sh_compare_op0, sh_compare_op1));
7689 if (! currently_expanding_to_rtl)
7691 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7695 rtx lab = gen_label_rtx ();
7696 prepare_scc_operands (EQ);
7697 emit_jump_insn (gen_branch_true (lab));
7698 prepare_scc_operands (GT);
7700 emit_insn (gen_movt (operands[0]));
7703 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7706 operands[1] = prepare_scc_operands (GE);
7709 (define_expand "sgtu"
7710 [(set (match_operand:SI 0 "arith_reg_operand" "")
7717 if (GET_MODE (operands[0]) != DImode)
7718 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7719 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7720 if (sh_compare_op1 != const0_rtx)
7721 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7722 ? GET_MODE (sh_compare_op0)
7723 : GET_MODE (sh_compare_op1),
7726 emit_insn (gen_cmpgtudi_media (operands[0],
7727 sh_compare_op0, sh_compare_op1));
7730 if (! currently_expanding_to_rtl)
7732 operands[1] = prepare_scc_operands (GTU);
7735 (define_expand "sltu"
7736 [(set (match_operand:SI 0 "arith_reg_operand" "")
7743 if (GET_MODE (operands[0]) != DImode)
7744 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7745 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7746 if (sh_compare_op1 != const0_rtx)
7747 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7748 ? GET_MODE (sh_compare_op0)
7749 : GET_MODE (sh_compare_op1),
7752 emit_insn (gen_cmpgtudi_media (operands[0],
7753 sh_compare_op1, sh_compare_op0));
7756 if (! currently_expanding_to_rtl)
7758 operands[1] = prepare_scc_operands (LTU);
7761 (define_expand "sleu"
7762 [(set (match_operand:SI 0 "arith_reg_operand" "")
7771 if (GET_MODE (operands[0]) != DImode)
7772 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7773 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7774 if (sh_compare_op1 != const0_rtx)
7775 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7776 ? GET_MODE (sh_compare_op0)
7777 : GET_MODE (sh_compare_op1),
7780 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7782 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7783 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7787 if (! currently_expanding_to_rtl)
7789 operands[1] = prepare_scc_operands (LEU);
7792 (define_expand "sgeu"
7793 [(set (match_operand:SI 0 "arith_reg_operand" "")
7802 if (GET_MODE (operands[0]) != DImode)
7803 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7804 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7805 if (sh_compare_op1 != const0_rtx)
7806 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7807 ? GET_MODE (sh_compare_op0)
7808 : GET_MODE (sh_compare_op1),
7811 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7813 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7814 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7819 if (! currently_expanding_to_rtl)
7821 operands[1] = prepare_scc_operands (GEU);
7824 ;; sne moves the complement of the T reg to DEST like this:
7828 ;; This is better than xoring compare result with 1 because it does
7829 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7832 (define_expand "sne"
7833 [(set (match_dup 2) (const_int -1))
7834 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7835 (neg:SI (plus:SI (match_dup 1)
7838 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7847 if (GET_MODE (operands[0]) != DImode)
7848 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7850 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7853 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7854 if (sh_compare_op1 != const0_rtx)
7855 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7856 ? GET_MODE (sh_compare_op0)
7857 : GET_MODE (sh_compare_op1),
7860 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7862 emit_insn (gen_seq (tmp));
7863 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7868 if (sh_expand_t_scc (NE, operands[0]))
7870 if (! currently_expanding_to_rtl)
7872 operands[1] = prepare_scc_operands (EQ);
7873 operands[2] = gen_reg_rtx (SImode);
7876 (define_expand "sunordered"
7877 [(set (match_operand:DI 0 "arith_reg_operand" "")
7878 (unordered:DI (match_dup 1) (match_dup 2)))]
7879 "TARGET_SHMEDIA_FPU"
7882 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7883 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7886 ;; Use the same trick for FP sle / sge
7887 (define_expand "movnegt"
7888 [(set (match_dup 2) (const_int -1))
7889 (parallel [(set (match_operand 0 "" "")
7890 (neg:SI (plus:SI (match_dup 1)
7893 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7896 "operands[2] = gen_reg_rtx (SImode);")
7898 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7899 ;; This prevents a regression that occurred when we switched from xor to
7903 [(set (match_operand:SI 0 "arith_reg_operand" "")
7904 (plus:SI (reg:SI T_REG)
7907 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7908 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7911 ;; -------------------------------------------------------------------------
7912 ;; Instructions to cope with inline literal tables
7913 ;; -------------------------------------------------------------------------
7915 ; 2 byte integer in line
7917 (define_insn "consttable_2"
7918 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7919 (match_operand 1 "" "")]
7924 if (operands[1] != const0_rtx)
7925 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7928 [(set_attr "length" "2")
7929 (set_attr "in_delay_slot" "no")])
7931 ; 4 byte integer in line
7933 (define_insn "consttable_4"
7934 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7935 (match_operand 1 "" "")]
7940 if (operands[1] != const0_rtx)
7941 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7944 [(set_attr "length" "4")
7945 (set_attr "in_delay_slot" "no")])
7947 ; 8 byte integer in line
7949 (define_insn "consttable_8"
7950 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7951 (match_operand 1 "" "")]
7956 if (operands[1] != const0_rtx)
7957 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7960 [(set_attr "length" "8")
7961 (set_attr "in_delay_slot" "no")])
7963 ; 4 byte floating point
7965 (define_insn "consttable_sf"
7966 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7967 (match_operand 1 "" "")]
7972 if (operands[1] != const0_rtx)
7975 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7976 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7980 [(set_attr "length" "4")
7981 (set_attr "in_delay_slot" "no")])
7983 ; 8 byte floating point
7985 (define_insn "consttable_df"
7986 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7987 (match_operand 1 "" "")]
7992 if (operands[1] != const0_rtx)
7995 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7996 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8000 [(set_attr "length" "8")
8001 (set_attr "in_delay_slot" "no")])
8003 ;; Alignment is needed for some constant tables; it may also be added for
8004 ;; Instructions at the start of loops, or after unconditional branches.
8005 ;; ??? We would get more accurate lengths if we did instruction
8006 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8007 ;; here is too conservative.
8009 ; align to a two byte boundary
8011 (define_expand "align_2"
8012 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8016 ; align to a four byte boundary
8017 ;; align_4 and align_log are instructions for the starts of loops, or
8018 ;; after unconditional branches, which may take up extra room.
8020 (define_expand "align_4"
8021 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8025 ; align to a cache line boundary
8027 (define_insn "align_log"
8028 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8031 [(set_attr "length" "0")
8032 (set_attr "in_delay_slot" "no")])
8034 ; emitted at the end of the literal table, used to emit the
8035 ; 32bit branch labels if needed.
8037 (define_insn "consttable_end"
8038 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8040 "* return output_jump_label_table ();"
8041 [(set_attr "in_delay_slot" "no")])
8043 ; emitted at the end of the window in the literal table.
8045 (define_insn "consttable_window_end"
8046 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8049 [(set_attr "length" "0")
8050 (set_attr "in_delay_slot" "no")])
8052 ;; -------------------------------------------------------------------------
8054 ;; -------------------------------------------------------------------------
8056 ;; String/block move insn.
8058 (define_expand "movmemsi"
8059 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8060 (mem:BLK (match_operand:BLK 1 "" "")))
8061 (use (match_operand:SI 2 "nonmemory_operand" ""))
8062 (use (match_operand:SI 3 "immediate_operand" ""))
8063 (clobber (reg:SI PR_REG))
8064 (clobber (reg:SI R4_REG))
8065 (clobber (reg:SI R5_REG))
8066 (clobber (reg:SI R0_REG))])]
8067 "TARGET_SH1 && ! TARGET_SH5"
8070 if(expand_block_move (operands))
8075 (define_insn "block_move_real"
8076 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8077 (mem:BLK (reg:SI R5_REG)))
8078 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8079 (clobber (reg:SI PR_REG))
8080 (clobber (reg:SI R0_REG))])]
8081 "TARGET_SH1 && ! TARGET_HARD_SH4"
8083 [(set_attr "type" "sfunc")
8084 (set_attr "needs_delay_slot" "yes")])
8086 (define_insn "block_lump_real"
8087 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8088 (mem:BLK (reg:SI R5_REG)))
8089 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8090 (use (reg:SI R6_REG))
8091 (clobber (reg:SI PR_REG))
8092 (clobber (reg:SI T_REG))
8093 (clobber (reg:SI R4_REG))
8094 (clobber (reg:SI R5_REG))
8095 (clobber (reg:SI R6_REG))
8096 (clobber (reg:SI R0_REG))])]
8097 "TARGET_SH1 && ! TARGET_HARD_SH4"
8099 [(set_attr "type" "sfunc")
8100 (set_attr "needs_delay_slot" "yes")])
8102 (define_insn "block_move_real_i4"
8103 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8104 (mem:BLK (reg:SI R5_REG)))
8105 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8106 (clobber (reg:SI PR_REG))
8107 (clobber (reg:SI R0_REG))
8108 (clobber (reg:SI R1_REG))
8109 (clobber (reg:SI R2_REG))])]
8112 [(set_attr "type" "sfunc")
8113 (set_attr "needs_delay_slot" "yes")])
8115 (define_insn "block_lump_real_i4"
8116 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8117 (mem:BLK (reg:SI R5_REG)))
8118 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8119 (use (reg:SI R6_REG))
8120 (clobber (reg:SI PR_REG))
8121 (clobber (reg:SI T_REG))
8122 (clobber (reg:SI R4_REG))
8123 (clobber (reg:SI R5_REG))
8124 (clobber (reg:SI R6_REG))
8125 (clobber (reg:SI R0_REG))
8126 (clobber (reg:SI R1_REG))
8127 (clobber (reg:SI R2_REG))
8128 (clobber (reg:SI R3_REG))])]
8131 [(set_attr "type" "sfunc")
8132 (set_attr "needs_delay_slot" "yes")])
8134 ;; -------------------------------------------------------------------------
8135 ;; Floating point instructions.
8136 ;; -------------------------------------------------------------------------
8138 ;; ??? All patterns should have a type attribute.
8140 (define_expand "fpu_switch0"
8141 [(set (match_operand:SI 0 "" "") (match_dup 2))
8142 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8143 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8146 operands[1] = get_fpscr_rtx ();
8147 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8149 operands[2] = legitimize_pic_address (operands[2], SImode,
8150 no_new_pseudos ? operands[0] : 0);
8153 (define_expand "fpu_switch1"
8154 [(set (match_operand:SI 0 "" "") (match_dup 2))
8155 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8156 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8157 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8160 operands[1] = get_fpscr_rtx ();
8161 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8163 operands[2] = legitimize_pic_address (operands[2], SImode,
8164 no_new_pseudos ? operands[0] : 0);
8165 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8168 (define_expand "movpsi"
8169 [(set (match_operand:PSI 0 "register_operand" "")
8170 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8171 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8174 ;; The c / m alternative is a fake to guide reload to load directly into
8175 ;; fpscr, since reload doesn't know how to use post-increment.
8176 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8177 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8178 ;; predicate after reload.
8179 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8180 ;; like a mac -> gpr move.
8181 (define_insn "fpu_switch"
8182 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8183 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8185 && (! reload_completed
8186 || true_regnum (operands[0]) != FPSCR_REG
8187 || GET_CODE (operands[1]) != MEM
8188 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8190 ! precision stays the same
8199 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8200 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8203 [(set (reg:PSI FPSCR_REG)
8204 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8205 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8206 [(set (match_dup 0) (match_dup 0))]
8209 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8210 gen_rtx_MEM (PSImode,
8211 gen_rtx_POST_INC (Pmode,
8213 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8217 [(set (reg:PSI FPSCR_REG)
8218 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8219 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8220 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8223 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8224 gen_rtx_MEM (PSImode,
8225 gen_rtx_POST_INC (Pmode,
8227 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8230 ;; ??? This uses the fp unit, but has no type indicating that.
8231 ;; If we did that, this would either give a bogus latency or introduce
8232 ;; a bogus FIFO constraint.
8233 ;; Since this insn is currently only used for prologues/epilogues,
8234 ;; it is probably best to claim no function unit, which matches the
8236 (define_insn "toggle_sz"
8237 [(set (reg:PSI FPSCR_REG)
8238 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8239 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8241 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8243 ;; There's no way we can use it today, since optimize mode switching
8244 ;; doesn't enable us to know from which mode we're switching to the
8245 ;; mode it requests, to tell whether we can use a relative mode switch
8246 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8248 (define_insn "toggle_pr"
8249 [(set (reg:PSI FPSCR_REG)
8250 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8251 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8253 [(set_attr "type" "fp")])
8255 (define_expand "addsf3"
8256 [(set (match_operand:SF 0 "arith_reg_operand" "")
8257 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8258 (match_operand:SF 2 "arith_reg_operand" "")))]
8259 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8264 expand_sf_binop (&gen_addsf3_i, operands);
8269 (define_insn "*addsf3_media"
8270 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8271 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8272 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8273 "TARGET_SHMEDIA_FPU"
8275 [(set_attr "type" "fparith_media")])
8277 (define_insn_and_split "unary_sf_op"
8278 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8283 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8284 (match_operator:SF 2 "unary_float_operator"
8285 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8286 (parallel [(match_operand 4
8287 "const_int_operand" "n")]))]))
8288 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8289 "TARGET_SHMEDIA_FPU"
8291 "TARGET_SHMEDIA_FPU && reload_completed"
8292 [(set (match_dup 5) (match_dup 6))]
8295 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8296 rtx op1 = gen_rtx_REG (SFmode,
8297 (true_regnum (operands[1])
8298 + (INTVAL (operands[4]) ^ endian)));
8300 operands[7] = gen_rtx_REG (SFmode,
8301 (true_regnum (operands[0])
8302 + (INTVAL (operands[3]) ^ endian)));
8303 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8305 [(set_attr "type" "fparith_media")])
8307 (define_insn_and_split "binary_sf_op"
8308 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8313 (parallel [(match_operand 7 "const_int_operand" "n")]))
8314 (match_operator:SF 3 "binary_float_operator"
8315 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8316 (parallel [(match_operand 5
8317 "const_int_operand" "n")]))
8318 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8319 (parallel [(match_operand 6
8320 "const_int_operand" "n")]))]))
8321 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8322 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8324 "&& reload_completed"
8325 [(set (match_dup 8) (match_dup 9))]
8328 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8329 rtx op1 = gen_rtx_REG (SFmode,
8330 (true_regnum (operands[1])
8331 + (INTVAL (operands[5]) ^ endian)));
8332 rtx op2 = gen_rtx_REG (SFmode,
8333 (true_regnum (operands[2])
8334 + (INTVAL (operands[6]) ^ endian)));
8336 operands[8] = gen_rtx_REG (SFmode,
8337 (true_regnum (operands[0])
8338 + (INTVAL (operands[4]) ^ endian)));
8339 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8341 [(set_attr "type" "fparith_media")])
8343 (define_insn "addsf3_i"
8344 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8345 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8346 (match_operand:SF 2 "arith_reg_operand" "f")))
8347 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8350 [(set_attr "type" "fp")
8351 (set_attr "fp_mode" "single")])
8353 (define_expand "subsf3"
8354 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8355 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8356 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8357 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8362 expand_sf_binop (&gen_subsf3_i, operands);
8367 (define_insn "*subsf3_media"
8368 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8369 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8370 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8371 "TARGET_SHMEDIA_FPU"
8373 [(set_attr "type" "fparith_media")])
8375 (define_insn "subsf3_i"
8376 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8377 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8378 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8379 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8382 [(set_attr "type" "fp")
8383 (set_attr "fp_mode" "single")])
8385 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8386 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8387 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8388 ;; SH3E, we use a separate insn for SH3E mulsf3.
8390 (define_expand "mulsf3"
8391 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8392 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8393 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8394 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8397 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8398 expand_sf_binop (&gen_mulsf3_i4, operands);
8399 else if (TARGET_SH2E)
8400 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8401 if (! TARGET_SHMEDIA)
8405 (define_insn "*mulsf3_media"
8406 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8407 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8408 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8409 "TARGET_SHMEDIA_FPU"
8411 [(set_attr "type" "fparith_media")])
8413 (define_insn "mulsf3_i4"
8414 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8415 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8416 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8417 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8420 [(set_attr "type" "fp")
8421 (set_attr "fp_mode" "single")])
8423 (define_insn "mulsf3_ie"
8424 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8425 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8426 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8427 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8429 [(set_attr "type" "fp")])
8431 (define_insn "*mac_media"
8432 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8433 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8434 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8435 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8436 "TARGET_SHMEDIA_FPU"
8438 [(set_attr "type" "fparith_media")])
8440 (define_insn "*macsf3"
8441 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8442 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8443 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8444 (match_operand:SF 3 "arith_reg_operand" "0")))
8445 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8446 "TARGET_SH2E && ! TARGET_SH4"
8448 [(set_attr "type" "fp")
8449 (set_attr "fp_mode" "single")])
8451 (define_expand "divsf3"
8452 [(set (match_operand:SF 0 "arith_reg_operand" "")
8453 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8454 (match_operand:SF 2 "arith_reg_operand" "")))]
8455 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8460 expand_sf_binop (&gen_divsf3_i, operands);
8465 (define_insn "*divsf3_media"
8466 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8467 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8468 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8469 "TARGET_SHMEDIA_FPU"
8471 [(set_attr "type" "fdiv_media")])
8473 (define_insn "divsf3_i"
8474 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8475 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8476 (match_operand:SF 2 "arith_reg_operand" "f")))
8477 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8480 [(set_attr "type" "fdiv")
8481 (set_attr "fp_mode" "single")])
8483 (define_insn "floatdisf2"
8484 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8485 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8486 "TARGET_SHMEDIA_FPU"
8488 [(set_attr "type" "fpconv_media")])
8490 (define_expand "floatsisf2"
8491 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8492 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8493 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8496 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8498 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8503 (define_insn "*floatsisf2_media"
8504 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8505 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8506 "TARGET_SHMEDIA_FPU"
8508 [(set_attr "type" "fpconv_media")])
8510 (define_insn "floatsisf2_i4"
8511 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8512 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8513 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8514 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8516 [(set_attr "type" "fp")
8517 (set_attr "fp_mode" "single")])
8519 (define_insn "*floatsisf2_ie"
8520 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8521 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8522 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8524 [(set_attr "type" "fp")])
8526 (define_insn "fix_truncsfdi2"
8527 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8528 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8529 "TARGET_SHMEDIA_FPU"
8531 [(set_attr "type" "fpconv_media")])
8533 (define_expand "fix_truncsfsi2"
8534 [(set (match_operand:SI 0 "fpul_operand" "=y")
8535 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8536 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8539 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8541 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8546 (define_insn "*fix_truncsfsi2_media"
8547 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8548 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8549 "TARGET_SHMEDIA_FPU"
8551 [(set_attr "type" "fpconv_media")])
8553 (define_insn "fix_truncsfsi2_i4"
8554 [(set (match_operand:SI 0 "fpul_operand" "=y")
8555 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8556 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8557 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8559 [(set_attr "type" "ftrc_s")
8560 (set_attr "fp_mode" "single")])
8562 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8563 ;; fix_truncsfsi2_i4.
8564 ;; (define_insn "fix_truncsfsi2_i4_2"
8565 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8566 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8567 ;; (use (reg:PSI FPSCR_REG))
8568 ;; (clobber (reg:SI FPUL_REG))]
8571 ;; [(set_attr "length" "4")
8572 ;; (set_attr "fp_mode" "single")])
8575 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8576 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8577 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8578 ;; (clobber (reg:SI FPUL_REG))]
8580 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8581 ;; (use (match_dup 2))])
8582 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8584 (define_insn "*fixsfsi"
8585 [(set (match_operand:SI 0 "fpul_operand" "=y")
8586 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8587 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8589 [(set_attr "type" "fp")])
8591 (define_insn "cmpgtsf_t"
8592 [(set (reg:SI T_REG)
8593 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8594 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8595 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8597 [(set_attr "type" "fp")
8598 (set_attr "fp_mode" "single")])
8600 (define_insn "cmpeqsf_t"
8601 [(set (reg:SI T_REG)
8602 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8603 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8604 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8606 [(set_attr "type" "fp")
8607 (set_attr "fp_mode" "single")])
8609 (define_insn "ieee_ccmpeqsf_t"
8610 [(set (reg:SI T_REG)
8611 (ior:SI (reg:SI T_REG)
8612 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8613 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8614 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8615 "* return output_ieee_ccmpeq (insn, operands);"
8616 [(set_attr "length" "4")])
8619 (define_insn "cmpgtsf_t_i4"
8620 [(set (reg:SI T_REG)
8621 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8622 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8623 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8624 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8626 [(set_attr "type" "fp")
8627 (set_attr "fp_mode" "single")])
8629 (define_insn "cmpeqsf_t_i4"
8630 [(set (reg:SI T_REG)
8631 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8632 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8633 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8634 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8636 [(set_attr "type" "fp")
8637 (set_attr "fp_mode" "single")])
8639 (define_insn "*ieee_ccmpeqsf_t_4"
8640 [(set (reg:SI T_REG)
8641 (ior:SI (reg:SI T_REG)
8642 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8643 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8644 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8645 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8646 "* return output_ieee_ccmpeq (insn, operands);"
8647 [(set_attr "length" "4")
8648 (set_attr "fp_mode" "single")])
8650 (define_insn "cmpeqsf_media"
8651 [(set (match_operand:DI 0 "register_operand" "=r")
8652 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8653 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8654 "TARGET_SHMEDIA_FPU"
8655 "fcmpeq.s %1, %2, %0"
8656 [(set_attr "type" "fcmp_media")])
8658 (define_insn "cmpgtsf_media"
8659 [(set (match_operand:DI 0 "register_operand" "=r")
8660 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8661 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8662 "TARGET_SHMEDIA_FPU"
8663 "fcmpgt.s %1, %2, %0"
8664 [(set_attr "type" "fcmp_media")])
8666 (define_insn "cmpgesf_media"
8667 [(set (match_operand:DI 0 "register_operand" "=r")
8668 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8669 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8670 "TARGET_SHMEDIA_FPU"
8671 "fcmpge.s %1, %2, %0"
8672 [(set_attr "type" "fcmp_media")])
8674 (define_insn "cmpunsf_media"
8675 [(set (match_operand:DI 0 "register_operand" "=r")
8676 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8677 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8678 "TARGET_SHMEDIA_FPU"
8679 "fcmpun.s %1, %2, %0"
8680 [(set_attr "type" "fcmp_media")])
8682 (define_expand "cmpsf"
8683 [(set (reg:SI T_REG)
8684 (compare (match_operand:SF 0 "arith_operand" "")
8685 (match_operand:SF 1 "arith_operand" "")))]
8686 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8689 sh_compare_op0 = operands[0];
8690 sh_compare_op1 = operands[1];
8694 (define_expand "negsf2"
8695 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8696 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8697 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8702 expand_sf_unop (&gen_negsf2_i, operands);
8707 (define_insn "*negsf2_media"
8708 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8709 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8710 "TARGET_SHMEDIA_FPU"
8712 [(set_attr "type" "fmove_media")])
8714 (define_insn "negsf2_i"
8715 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8716 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8717 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8720 [(set_attr "type" "fmove")
8721 (set_attr "fp_mode" "single")])
8723 (define_expand "sqrtsf2"
8724 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8725 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8726 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8731 expand_sf_unop (&gen_sqrtsf2_i, operands);
8736 (define_insn "*sqrtsf2_media"
8737 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8738 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8739 "TARGET_SHMEDIA_FPU"
8741 [(set_attr "type" "fdiv_media")])
8743 (define_insn "sqrtsf2_i"
8744 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8745 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8746 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8749 [(set_attr "type" "fdiv")
8750 (set_attr "fp_mode" "single")])
8752 (define_insn "rsqrtsf2"
8753 [(set (match_operand:SF 0 "register_operand" "=f")
8754 (div:SF (match_operand:SF 1 "immediate_operand" "i")
8755 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8756 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8757 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8758 && operands[1] == CONST1_RTX (SFmode)"
8760 [(set_attr "type" "fsrra")
8761 (set_attr "fp_mode" "single")])
8764 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8766 (unspec:SF [(mult:SF
8767 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8768 (match_operand:SF 2 "immediate_operand" "i"))
8770 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8772 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8773 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8774 && operands[2] == sh_fsca_int2sf ()"
8776 [(set_attr "type" "fsca")
8777 (set_attr "fp_mode" "single")])
8779 (define_expand "sinsf2"
8780 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8781 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8783 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8786 rtx scaled = gen_reg_rtx (SFmode);
8787 rtx truncated = gen_reg_rtx (SImode);
8788 rtx fsca = gen_reg_rtx (V2SFmode);
8789 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8791 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8792 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8793 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8795 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8799 (define_expand "cossf2"
8800 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8801 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8803 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8806 rtx scaled = gen_reg_rtx (SFmode);
8807 rtx truncated = gen_reg_rtx (SImode);
8808 rtx fsca = gen_reg_rtx (V2SFmode);
8809 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8811 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8812 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8813 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8815 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8819 (define_expand "sindf2"
8820 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8821 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8823 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8826 rtx scaled = gen_reg_rtx (DFmode);
8827 rtx truncated = gen_reg_rtx (SImode);
8828 rtx fsca = gen_reg_rtx (V2SFmode);
8829 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8830 rtx sfresult = gen_reg_rtx (SFmode);
8832 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8833 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8834 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8836 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8837 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8841 (define_expand "cosdf2"
8842 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8843 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8845 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8848 rtx scaled = gen_reg_rtx (DFmode);
8849 rtx truncated = gen_reg_rtx (SImode);
8850 rtx fsca = gen_reg_rtx (V2SFmode);
8851 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8852 rtx sfresult = gen_reg_rtx (SFmode);
8854 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8855 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8856 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8858 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8859 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8863 (define_expand "abssf2"
8864 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8865 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8866 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8871 expand_sf_unop (&gen_abssf2_i, operands);
8876 (define_insn "*abssf2_media"
8877 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8878 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8879 "TARGET_SHMEDIA_FPU"
8881 [(set_attr "type" "fmove_media")])
8883 (define_insn "abssf2_i"
8884 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8885 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8886 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8889 [(set_attr "type" "fmove")
8890 (set_attr "fp_mode" "single")])
8892 (define_expand "adddf3"
8893 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8894 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8895 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8896 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8899 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8901 expand_df_binop (&gen_adddf3_i, operands);
8906 (define_insn "*adddf3_media"
8907 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8908 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8909 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8910 "TARGET_SHMEDIA_FPU"
8912 [(set_attr "type" "dfparith_media")])
8914 (define_insn "adddf3_i"
8915 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8916 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8917 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8918 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8919 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8921 [(set_attr "type" "dfp_arith")
8922 (set_attr "fp_mode" "double")])
8924 (define_expand "subdf3"
8925 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8926 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8927 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8928 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8931 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8933 expand_df_binop (&gen_subdf3_i, operands);
8938 (define_insn "*subdf3_media"
8939 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8940 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8941 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8942 "TARGET_SHMEDIA_FPU"
8944 [(set_attr "type" "dfparith_media")])
8946 (define_insn "subdf3_i"
8947 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8948 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8949 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8950 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8951 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8953 [(set_attr "type" "dfp_arith")
8954 (set_attr "fp_mode" "double")])
8956 (define_expand "muldf3"
8957 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8958 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8959 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8960 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8963 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8965 expand_df_binop (&gen_muldf3_i, operands);
8970 (define_insn "*muldf3_media"
8971 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8972 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8973 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8974 "TARGET_SHMEDIA_FPU"
8976 [(set_attr "type" "dfmul_media")])
8978 (define_insn "muldf3_i"
8979 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8980 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8981 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8982 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8983 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8985 [(set_attr "type" "dfp_arith")
8986 (set_attr "fp_mode" "double")])
8988 (define_expand "divdf3"
8989 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8990 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8991 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8992 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8995 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8997 expand_df_binop (&gen_divdf3_i, operands);
9002 (define_insn "*divdf3_media"
9003 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9004 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9005 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9006 "TARGET_SHMEDIA_FPU"
9008 [(set_attr "type" "dfdiv_media")])
9010 (define_insn "divdf3_i"
9011 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9012 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9013 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9014 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9015 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9017 [(set_attr "type" "dfdiv")
9018 (set_attr "fp_mode" "double")])
9020 (define_insn "floatdidf2"
9021 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9022 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9023 "TARGET_SHMEDIA_FPU"
9025 [(set_attr "type" "dfpconv_media")])
9027 (define_expand "floatsidf2"
9028 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9029 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9030 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9033 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9035 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9041 (define_insn "*floatsidf2_media"
9042 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9043 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9044 "TARGET_SHMEDIA_FPU"
9046 [(set_attr "type" "dfpconv_media")])
9048 (define_insn "floatsidf2_i"
9049 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9050 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9051 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9052 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9054 [(set_attr "type" "dfp_conv")
9055 (set_attr "fp_mode" "double")])
9057 (define_insn "fix_truncdfdi2"
9058 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9059 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9060 "TARGET_SHMEDIA_FPU"
9062 [(set_attr "type" "dfpconv_media")])
9064 (define_expand "fix_truncdfsi2"
9065 [(set (match_operand:SI 0 "fpul_operand" "")
9066 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9067 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9070 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9072 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9078 (define_insn "*fix_truncdfsi2_media"
9079 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9080 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9081 "TARGET_SHMEDIA_FPU"
9083 [(set_attr "type" "dfpconv_media")])
9085 (define_insn "fix_truncdfsi2_i"
9086 [(set (match_operand:SI 0 "fpul_operand" "=y")
9087 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9088 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9089 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9091 [(set_attr "type" "dfp_conv")
9092 (set_attr "dfp_comp" "no")
9093 (set_attr "fp_mode" "double")])
9095 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
9096 ;; fix_truncdfsi2_i.
9097 ;; (define_insn "fix_truncdfsi2_i4"
9098 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9099 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9100 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9101 ;; (clobber (reg:SI FPUL_REG))]
9104 ;; [(set_attr "length" "4")
9105 ;; (set_attr "fp_mode" "double")])
9108 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9109 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9110 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9111 ;; (clobber (reg:SI FPUL_REG))]
9113 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9114 ;; (use (match_dup 2))])
9115 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
9117 (define_insn "cmpgtdf_t"
9118 [(set (reg:SI T_REG)
9119 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9120 (match_operand:DF 1 "arith_reg_operand" "f")))
9121 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9122 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9124 [(set_attr "type" "dfp_cmp")
9125 (set_attr "fp_mode" "double")])
9127 (define_insn "cmpeqdf_t"
9128 [(set (reg:SI T_REG)
9129 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9130 (match_operand:DF 1 "arith_reg_operand" "f")))
9131 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9132 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9134 [(set_attr "type" "dfp_cmp")
9135 (set_attr "fp_mode" "double")])
9137 (define_insn "*ieee_ccmpeqdf_t"
9138 [(set (reg:SI T_REG)
9139 (ior:SI (reg:SI T_REG)
9140 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9141 (match_operand:DF 1 "arith_reg_operand" "f"))))
9142 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9143 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9144 "* return output_ieee_ccmpeq (insn, operands);"
9145 [(set_attr "length" "4")
9146 (set_attr "fp_mode" "double")])
9148 (define_insn "cmpeqdf_media"
9149 [(set (match_operand:DI 0 "register_operand" "=r")
9150 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9151 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9152 "TARGET_SHMEDIA_FPU"
9154 [(set_attr "type" "fcmp_media")])
9156 (define_insn "cmpgtdf_media"
9157 [(set (match_operand:DI 0 "register_operand" "=r")
9158 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9159 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9160 "TARGET_SHMEDIA_FPU"
9162 [(set_attr "type" "fcmp_media")])
9164 (define_insn "cmpgedf_media"
9165 [(set (match_operand:DI 0 "register_operand" "=r")
9166 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9167 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9168 "TARGET_SHMEDIA_FPU"
9170 [(set_attr "type" "fcmp_media")])
9172 (define_insn "cmpundf_media"
9173 [(set (match_operand:DI 0 "register_operand" "=r")
9174 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9175 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9176 "TARGET_SHMEDIA_FPU"
9178 [(set_attr "type" "fcmp_media")])
9180 (define_expand "cmpdf"
9181 [(set (reg:SI T_REG)
9182 (compare (match_operand:DF 0 "arith_operand" "")
9183 (match_operand:DF 1 "arith_operand" "")))]
9184 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9187 sh_compare_op0 = operands[0];
9188 sh_compare_op1 = operands[1];
9192 (define_expand "negdf2"
9193 [(set (match_operand:DF 0 "arith_reg_operand" "")
9194 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9195 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9198 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9200 expand_df_unop (&gen_negdf2_i, operands);
9205 (define_insn "*negdf2_media"
9206 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9207 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9208 "TARGET_SHMEDIA_FPU"
9210 [(set_attr "type" "fmove_media")])
9212 (define_insn "negdf2_i"
9213 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9214 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9215 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9216 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9218 [(set_attr "type" "fmove")
9219 (set_attr "fp_mode" "double")])
9221 (define_expand "sqrtdf2"
9222 [(set (match_operand:DF 0 "arith_reg_operand" "")
9223 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9224 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9227 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9229 expand_df_unop (&gen_sqrtdf2_i, operands);
9234 (define_insn "*sqrtdf2_media"
9235 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9236 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9237 "TARGET_SHMEDIA_FPU"
9239 [(set_attr "type" "dfdiv_media")])
9241 (define_insn "sqrtdf2_i"
9242 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9243 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9244 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9245 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9247 [(set_attr "type" "dfdiv")
9248 (set_attr "fp_mode" "double")])
9250 (define_expand "absdf2"
9251 [(set (match_operand:DF 0 "arith_reg_operand" "")
9252 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9253 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9256 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9258 expand_df_unop (&gen_absdf2_i, operands);
9263 (define_insn "*absdf2_media"
9264 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9265 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9266 "TARGET_SHMEDIA_FPU"
9268 [(set_attr "type" "fmove_media")])
9270 (define_insn "absdf2_i"
9271 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9272 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9273 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9274 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9276 [(set_attr "type" "fmove")
9277 (set_attr "fp_mode" "double")])
9279 (define_expand "extendsfdf2"
9280 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9281 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9282 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9285 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9287 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9293 (define_insn "*extendsfdf2_media"
9294 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9295 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9296 "TARGET_SHMEDIA_FPU"
9298 [(set_attr "type" "dfpconv_media")])
9300 (define_insn "extendsfdf2_i4"
9301 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9302 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9303 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9304 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9306 [(set_attr "type" "fp")
9307 (set_attr "fp_mode" "double")])
9309 (define_expand "truncdfsf2"
9310 [(set (match_operand:SF 0 "fpul_operand" "")
9311 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9312 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9315 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9317 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9323 (define_insn "*truncdfsf2_media"
9324 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9325 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9326 "TARGET_SHMEDIA_FPU"
9328 [(set_attr "type" "dfpconv_media")])
9330 (define_insn "truncdfsf2_i4"
9331 [(set (match_operand:SF 0 "fpul_operand" "=y")
9332 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9333 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9334 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9336 [(set_attr "type" "fp")
9337 (set_attr "fp_mode" "double")])
9339 ;; Bit field extract patterns. These give better code for packed bitfields,
9340 ;; because they allow auto-increment addresses to be generated.
9342 (define_expand "insv"
9343 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9344 (match_operand:SI 1 "immediate_operand" "")
9345 (match_operand:SI 2 "immediate_operand" ""))
9346 (match_operand:SI 3 "general_operand" ""))]
9347 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9350 rtx addr_target, orig_address, shift_reg, qi_val;
9351 HOST_WIDE_INT bitsize, size, v = 0;
9352 rtx x = operands[3];
9354 /* ??? expmed doesn't care for non-register predicates. */
9355 if (! memory_operand (operands[0], VOIDmode)
9356 || ! immediate_operand (operands[1], VOIDmode)
9357 || ! immediate_operand (operands[2], VOIDmode)
9358 || ! general_operand (x, VOIDmode))
9360 /* If this isn't a 16 / 24 / 32 bit field, or if
9361 it doesn't start on a byte boundary, then fail. */
9362 bitsize = INTVAL (operands[1]);
9363 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9364 || (INTVAL (operands[2]) % 8) != 0)
9368 orig_address = XEXP (operands[0], 0);
9369 shift_reg = gen_reg_rtx (SImode);
9370 if (GET_CODE (x) == CONST_INT)
9373 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9377 emit_insn (gen_movsi (shift_reg, operands[3]));
9378 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9380 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9382 operands[0] = replace_equiv_address (operands[0], addr_target);
9383 emit_insn (gen_movqi (operands[0], qi_val));
9387 if (GET_CODE (x) == CONST_INT)
9389 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9392 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9393 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9395 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9396 emit_insn (gen_movqi (operands[0], qi_val));
9402 (define_insn "movua"
9403 [(set (match_operand:SI 0 "register_operand" "=z")
9404 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9405 (const_int 32) (const_int 0)))]
9408 [(set_attr "type" "movua")])
9410 ;; We shouldn't need this, but cse replaces increments with references
9411 ;; to other regs before flow has a chance to create post_inc
9412 ;; addressing modes, and only postreload's cse_move2add brings the
9413 ;; increments back to a usable form.
9415 [(set (match_operand:SI 0 "register_operand" "")
9416 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9417 (const_int 32) (const_int 0)))
9418 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9419 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9420 [(set (match_operand:SI 0 "register_operand" "")
9421 (sign_extract:SI (mem:SI (post_inc:SI
9422 (match_operand:SI 1 "register_operand" "")))
9423 (const_int 32) (const_int 0)))]
9426 (define_expand "extv"
9427 [(set (match_operand:SI 0 "register_operand" "")
9428 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9429 (match_operand 2 "const_int_operand" "")
9430 (match_operand 3 "const_int_operand" "")))]
9433 if (TARGET_SH4A_ARCH
9434 && INTVAL (operands[2]) == 32
9435 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9436 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9438 emit_insn (gen_movua (operands[0],
9439 adjust_address (operands[1], SImode, 0)));
9446 (define_expand "extzv"
9447 [(set (match_operand:SI 0 "register_operand" "")
9448 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9449 (match_operand 2 "const_int_operand" "")
9450 (match_operand 3 "const_int_operand" "")))]
9453 if (TARGET_SH4A_ARCH
9454 && INTVAL (operands[2]) == 32
9455 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9456 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9458 emit_insn (gen_movua (operands[0],
9459 adjust_address (operands[1], SImode, 0)));
9467 ;; -------------------------------------------------------------------------
9469 ;; -------------------------------------------------------------------------
9471 ;; This matches cases where a stack pointer increment at the start of the
9472 ;; epilogue combines with a stack slot read loading the return value.
9475 [(set (match_operand:SI 0 "arith_reg_operand" "")
9476 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9477 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9478 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9481 ;; See the comment on the dt combiner pattern above.
9484 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9485 (plus:SI (match_dup 0)
9488 (eq:SI (match_dup 0)
9493 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9494 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9495 ;; reload when the constant is too large for a reg+offset address.
9497 ;; ??? We would get much better code if this was done in reload. This would
9498 ;; require modifying find_reloads_address to recognize that if the constant
9499 ;; is out-of-range for an immediate add, then we get better code by reloading
9500 ;; the constant into a register than by reloading the sum into a register,
9501 ;; since the former is one instruction shorter if the address does not need
9502 ;; to be offsettable. Unfortunately this does not work, because there is
9503 ;; only one register, r0, that can be used as an index register. This register
9504 ;; is also the function return value register. So, if we try to force reload
9505 ;; to use double-reg addresses, then we end up with some instructions that
9506 ;; need to use r0 twice. The only way to fix this is to change the calling
9507 ;; convention so that r0 is not used to return values.
9510 [(set (match_operand:SI 0 "register_operand" "=r")
9511 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9512 (set (mem:SI (match_dup 0))
9513 (match_operand:SI 2 "general_movsrc_operand" ""))]
9514 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9515 "mov.l %2,@(%0,%1)")
9518 [(set (match_operand:SI 0 "register_operand" "=r")
9519 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9520 (set (match_operand:SI 2 "general_movdst_operand" "")
9521 (mem:SI (match_dup 0)))]
9522 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9523 "mov.l @(%0,%1),%2")
9526 [(set (match_operand:SI 0 "register_operand" "=r")
9527 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9528 (set (mem:HI (match_dup 0))
9529 (match_operand:HI 2 "general_movsrc_operand" ""))]
9530 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9531 "mov.w %2,@(%0,%1)")
9534 [(set (match_operand:SI 0 "register_operand" "=r")
9535 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9536 (set (match_operand:HI 2 "general_movdst_operand" "")
9537 (mem:HI (match_dup 0)))]
9538 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9539 "mov.w @(%0,%1),%2")
9542 [(set (match_operand:SI 0 "register_operand" "=r")
9543 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9544 (set (mem:QI (match_dup 0))
9545 (match_operand:QI 2 "general_movsrc_operand" ""))]
9546 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9547 "mov.b %2,@(%0,%1)")
9550 [(set (match_operand:SI 0 "register_operand" "=r")
9551 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9552 (set (match_operand:QI 2 "general_movdst_operand" "")
9553 (mem:QI (match_dup 0)))]
9554 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9555 "mov.b @(%0,%1),%2")
9558 [(set (match_operand:SI 0 "register_operand" "=r")
9559 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9560 (set (mem:SF (match_dup 0))
9561 (match_operand:SF 2 "general_movsrc_operand" ""))]
9562 "TARGET_SH1 && REGNO (operands[0]) == 0
9563 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9564 || (GET_CODE (operands[2]) == SUBREG
9565 && REGNO (SUBREG_REG (operands[2])) < 16))
9566 && reg_unused_after (operands[0], insn)"
9567 "mov.l %2,@(%0,%1)")
9570 [(set (match_operand:SI 0 "register_operand" "=r")
9571 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9572 (set (match_operand:SF 2 "general_movdst_operand" "")
9574 (mem:SF (match_dup 0)))]
9575 "TARGET_SH1 && REGNO (operands[0]) == 0
9576 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9577 || (GET_CODE (operands[2]) == SUBREG
9578 && REGNO (SUBREG_REG (operands[2])) < 16))
9579 && reg_unused_after (operands[0], insn)"
9580 "mov.l @(%0,%1),%2")
9583 [(set (match_operand:SI 0 "register_operand" "=r")
9584 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9585 (set (mem:SF (match_dup 0))
9586 (match_operand:SF 2 "general_movsrc_operand" ""))]
9587 "TARGET_SH2E && REGNO (operands[0]) == 0
9588 && ((GET_CODE (operands[2]) == REG
9589 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9590 || (GET_CODE (operands[2]) == SUBREG
9591 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9592 && reg_unused_after (operands[0], insn)"
9593 "fmov{.s|} %2,@(%0,%1)")
9596 [(set (match_operand:SI 0 "register_operand" "=r")
9597 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9598 (set (match_operand:SF 2 "general_movdst_operand" "")
9600 (mem:SF (match_dup 0)))]
9601 "TARGET_SH2E && REGNO (operands[0]) == 0
9602 && ((GET_CODE (operands[2]) == REG
9603 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9604 || (GET_CODE (operands[2]) == SUBREG
9605 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9606 && reg_unused_after (operands[0], insn)"
9607 "fmov{.s|} @(%0,%1),%2")
9609 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9610 (define_insn "sp_switch_1"
9617 xoperands[0] = sp_switch;
9618 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9619 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9620 return \"mov r0,r15\";
9622 [(set_attr "length" "10")])
9624 ;; Switch back to the original stack for interrupt functions with the
9625 ;; sp_switch attribute. */
9626 (define_insn "sp_switch_2"
9629 "mov.l @r15+,r15\;mov.l @r15+,r0"
9630 [(set_attr "length" "4")])
9632 ;; Integer vector moves
9634 (define_expand "movv8qi"
9635 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9636 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9638 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9640 (define_insn "movv8qi_i"
9641 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9642 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9644 && (register_operand (operands[0], V8QImode)
9645 || sh_register_operand (operands[1], V8QImode))"
9652 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9653 (set_attr "length" "4,4,16,4,4")])
9656 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9657 (subreg:V8QI (const_int 0) 0))]
9660 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9661 (const_int 0) (const_int 0) (const_int 0)
9662 (const_int 0) (const_int 0)]))])
9665 [(set (match_operand 0 "arith_reg_dest" "")
9666 (match_operand 1 "sh_rep_vec" ""))]
9667 "TARGET_SHMEDIA && reload_completed
9668 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9669 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9670 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9671 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9672 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9673 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9674 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9675 [(set (match_dup 0) (match_dup 1))
9679 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9680 rtx elt1 = XVECEXP (operands[1], 0, 1);
9683 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9687 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9688 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9690 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9691 operands[1] = XVECEXP (operands[1], 0, 0);
9694 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9696 = GEN_INT (TARGET_LITTLE_ENDIAN
9697 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9698 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9701 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9703 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9709 [(set (match_operand 0 "arith_reg_dest" "")
9710 (match_operand 1 "sh_const_vec" ""))]
9711 "TARGET_SHMEDIA && reload_completed
9712 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9713 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9714 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9715 [(set (match_dup 0) (match_dup 1))]
9718 rtx v = operands[1];
9719 enum machine_mode new_mode
9720 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9722 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9724 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9727 (define_expand "movv2hi"
9728 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9729 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9731 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9733 (define_insn "movv2hi_i"
9734 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9735 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9737 && (register_operand (operands[0], V2HImode)
9738 || sh_register_operand (operands[1], V2HImode))"
9745 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9746 (set_attr "length" "4,4,16,4,4")])
9748 (define_expand "movv4hi"
9749 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9750 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9752 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9754 (define_insn "movv4hi_i"
9755 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9756 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9758 && (register_operand (operands[0], V4HImode)
9759 || sh_register_operand (operands[1], V4HImode))"
9766 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9767 (set_attr "length" "4,4,16,4,4")])
9769 (define_expand "movv2si"
9770 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9771 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9773 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9775 (define_insn "movv2si_i"
9776 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9777 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9779 && (register_operand (operands[0], V2SImode)
9780 || sh_register_operand (operands[1], V2SImode))"
9787 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9788 (set_attr "length" "4,4,16,4,4")])
9790 ;; Multimedia Intrinsics
9792 (define_insn "absv2si2"
9793 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9794 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9797 [(set_attr "type" "mcmp_media")])
9799 (define_insn "absv4hi2"
9800 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9801 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9804 [(set_attr "type" "mcmp_media")])
9806 (define_insn "addv2si3"
9807 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9808 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9809 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9812 [(set_attr "type" "arith_media")])
9814 (define_insn "addv4hi3"
9815 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9816 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9817 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9820 [(set_attr "type" "arith_media")])
9822 (define_insn "ssaddv2si3"
9823 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9824 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9825 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9827 "madds.l %1, %2, %0"
9828 [(set_attr "type" "mcmp_media")])
9830 (define_insn "usaddv8qi3"
9831 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9832 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9833 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9835 "madds.ub %1, %2, %0"
9836 [(set_attr "type" "mcmp_media")])
9838 (define_insn "ssaddv4hi3"
9839 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9840 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9841 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9843 "madds.w %1, %2, %0"
9844 [(set_attr "type" "mcmp_media")])
9846 (define_insn "negcmpeqv8qi"
9847 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9848 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9849 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9851 "mcmpeq.b %N1, %N2, %0"
9852 [(set_attr "type" "mcmp_media")])
9854 (define_insn "negcmpeqv2si"
9855 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9856 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9857 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9859 "mcmpeq.l %N1, %N2, %0"
9860 [(set_attr "type" "mcmp_media")])
9862 (define_insn "negcmpeqv4hi"
9863 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9864 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9865 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9867 "mcmpeq.w %N1, %N2, %0"
9868 [(set_attr "type" "mcmp_media")])
9870 (define_insn "negcmpgtuv8qi"
9871 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9872 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9873 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9875 "mcmpgt.ub %N1, %N2, %0"
9876 [(set_attr "type" "mcmp_media")])
9878 (define_insn "negcmpgtv2si"
9879 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9880 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9881 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9883 "mcmpgt.l %N1, %N2, %0"
9884 [(set_attr "type" "mcmp_media")])
9886 (define_insn "negcmpgtv4hi"
9887 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9888 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9889 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9891 "mcmpgt.w %N1, %N2, %0"
9892 [(set_attr "type" "mcmp_media")])
9895 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9896 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9897 (match_operand:DI 2 "arith_reg_operand" "r"))
9898 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9899 (not:DI (match_dup 2)))))]
9902 [(set_attr "type" "arith_media")])
9904 (define_insn "mcnvs_lw"
9905 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9907 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9908 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9910 "mcnvs.lw %N1, %N2, %0"
9911 [(set_attr "type" "mcmp_media")])
9913 (define_insn "mcnvs_wb"
9914 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9916 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9917 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9919 "mcnvs.wb %N1, %N2, %0"
9920 [(set_attr "type" "mcmp_media")])
9922 (define_insn "mcnvs_wub"
9923 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9925 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9926 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9928 "mcnvs.wub %N1, %N2, %0"
9929 [(set_attr "type" "mcmp_media")])
9931 (define_insn "mextr_rl"
9932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9933 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9934 (match_operand:HI 3 "mextr_bit_offset" "i"))
9935 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9936 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9937 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9940 static char templ[16];
9942 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9943 (int) INTVAL (operands[3]) >> 3);
9946 [(set_attr "type" "arith_media")])
9948 (define_insn "*mextr_lr"
9949 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9950 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9951 (match_operand:HI 3 "mextr_bit_offset" "i"))
9952 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9953 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9954 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9957 static char templ[16];
9959 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9960 (int) INTVAL (operands[4]) >> 3);
9963 [(set_attr "type" "arith_media")])
9965 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9966 ; vector then varies depending on endianness.
9967 (define_expand "mextr1"
9968 [(match_operand:DI 0 "arith_reg_dest" "")
9969 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9970 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9974 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9975 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9979 (define_expand "mextr2"
9980 [(match_operand:DI 0 "arith_reg_dest" "")
9981 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9982 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9986 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9987 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9991 (define_expand "mextr3"
9992 [(match_operand:DI 0 "arith_reg_dest" "")
9993 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9994 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9998 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9999 GEN_INT (3 * 8), GEN_INT (5 * 8)));
10003 (define_expand "mextr4"
10004 [(match_operand:DI 0 "arith_reg_dest" "")
10005 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10006 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10010 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10011 GEN_INT (4 * 8), GEN_INT (4 * 8)));
10015 (define_expand "mextr5"
10016 [(match_operand:DI 0 "arith_reg_dest" "")
10017 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10018 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10022 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10023 GEN_INT (5 * 8), GEN_INT (3 * 8)));
10027 (define_expand "mextr6"
10028 [(match_operand:DI 0 "arith_reg_dest" "")
10029 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10030 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10034 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10035 GEN_INT (6 * 8), GEN_INT (2 * 8)));
10039 (define_expand "mextr7"
10040 [(match_operand:DI 0 "arith_reg_dest" "")
10041 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10042 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10046 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10047 GEN_INT (7 * 8), GEN_INT (1 * 8)));
10051 (define_expand "mmacfx_wl"
10052 [(match_operand:V2SI 0 "arith_reg_dest" "")
10053 (match_operand:V2HI 1 "extend_reg_operand" "")
10054 (match_operand:V2HI 2 "extend_reg_operand" "")
10055 (match_operand:V2SI 3 "arith_reg_operand" "")]
10059 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10060 operands[1], operands[2]));
10064 (define_insn "mmacfx_wl_i"
10065 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10067 (match_operand:V2SI 1 "arith_reg_operand" "0")
10072 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10073 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10076 "mmacfx.wl %2, %3, %0"
10077 [(set_attr "type" "mac_media")])
10079 (define_expand "mmacnfx_wl"
10080 [(match_operand:V2SI 0 "arith_reg_dest" "")
10081 (match_operand:V2HI 1 "extend_reg_operand" "")
10082 (match_operand:V2HI 2 "extend_reg_operand" "")
10083 (match_operand:V2SI 3 "arith_reg_operand" "")]
10087 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10088 operands[1], operands[2]));
10092 (define_insn "mmacnfx_wl_i"
10093 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10095 (match_operand:V2SI 1 "arith_reg_operand" "0")
10100 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10101 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10104 "mmacnfx.wl %2, %3, %0"
10105 [(set_attr "type" "mac_media")])
10107 (define_insn "mulv2si3"
10108 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10109 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10110 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10112 "mmul.l %1, %2, %0"
10113 [(set_attr "type" "d2mpy_media")])
10115 (define_insn "mulv4hi3"
10116 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10117 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10118 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10120 "mmul.w %1, %2, %0"
10121 [(set_attr "type" "dmpy_media")])
10123 (define_insn "mmulfx_l"
10124 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10128 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10129 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10132 "mmulfx.l %1, %2, %0"
10133 [(set_attr "type" "d2mpy_media")])
10135 (define_insn "mmulfx_w"
10136 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10140 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10141 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10144 "mmulfx.w %1, %2, %0"
10145 [(set_attr "type" "dmpy_media")])
10147 (define_insn "mmulfxrp_w"
10148 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10153 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10154 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10158 "mmulfxrp.w %1, %2, %0"
10159 [(set_attr "type" "dmpy_media")])
10161 (define_expand "mmulhi_wl"
10162 [(match_operand:V2SI 0 "arith_reg_dest" "")
10163 (match_operand:V4HI 1 "arith_reg_operand" "")
10164 (match_operand:V4HI 2 "arith_reg_operand" "")]
10168 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10169 (operands[0], operands[1], operands[2]));
10173 (define_expand "mmullo_wl"
10174 [(match_operand:V2SI 0 "arith_reg_dest" "")
10175 (match_operand:V4HI 1 "arith_reg_operand" "")
10176 (match_operand:V4HI 2 "arith_reg_operand" "")]
10180 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10181 (operands[0], operands[1], operands[2]));
10185 (define_insn "mmul23_wl"
10186 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10189 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10190 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10191 (parallel [(const_int 2) (const_int 3)])))]
10193 "* return (TARGET_LITTLE_ENDIAN
10194 ? \"mmulhi.wl %1, %2, %0\"
10195 : \"mmullo.wl %1, %2, %0\");"
10196 [(set_attr "type" "dmpy_media")])
10198 (define_insn "mmul01_wl"
10199 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10202 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10203 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10204 (parallel [(const_int 0) (const_int 1)])))]
10206 "* return (TARGET_LITTLE_ENDIAN
10207 ? \"mmullo.wl %1, %2, %0\"
10208 : \"mmulhi.wl %1, %2, %0\");"
10209 [(set_attr "type" "dmpy_media")])
10211 (define_expand "mmulsum_wq"
10212 [(match_operand:DI 0 "arith_reg_dest" "")
10213 (match_operand:V4HI 1 "arith_reg_operand" "")
10214 (match_operand:V4HI 2 "arith_reg_operand" "")
10215 (match_operand:DI 3 "arith_reg_operand" "")]
10219 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10220 operands[1], operands[2]));
10224 (define_insn "mmulsum_wq_i"
10225 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10226 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10231 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10232 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10233 (parallel [(const_int 0)]))
10234 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10235 (sign_extend:V4DI (match_dup 3)))
10236 (parallel [(const_int 1)])))
10238 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10239 (sign_extend:V4DI (match_dup 3)))
10240 (parallel [(const_int 2)]))
10241 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10242 (sign_extend:V4DI (match_dup 3)))
10243 (parallel [(const_int 3)]))))))]
10245 "mmulsum.wq %2, %3, %0"
10246 [(set_attr "type" "mac_media")])
10248 (define_expand "mperm_w"
10249 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10250 (match_operand:V4HI 1 "arith_reg_operand" "r")
10251 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10255 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10256 (operands[0], operands[1], operands[2]));
10260 ; This use of vec_select isn't exactly correct according to rtl.texi
10261 ; (because not constant), but it seems a straightforward extension.
10262 (define_insn "mperm_w_little"
10263 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10265 (match_operand:V4HI 1 "arith_reg_operand" "r")
10267 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10268 (const_int 2) (const_int 0))
10269 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10270 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10271 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10272 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10273 "mperm.w %1, %N2, %0"
10274 [(set_attr "type" "arith_media")])
10276 (define_insn "mperm_w_big"
10277 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10279 (match_operand:V4HI 1 "arith_reg_operand" "r")
10281 [(zero_extract:QI (not:QI (match_operand:QI 2
10282 "extend_reg_or_0_operand" "rZ"))
10283 (const_int 2) (const_int 0))
10284 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10285 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10286 (zero_extract:QI (not:QI (match_dup 2))
10287 (const_int 2) (const_int 6))])))]
10288 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10289 "mperm.w %1, %N2, %0"
10290 [(set_attr "type" "arith_media")])
10292 (define_insn "mperm_w0"
10293 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10294 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10295 "trunc_hi_operand" "r"))))]
10297 "mperm.w %1, r63, %0"
10298 [(set_attr "type" "arith_media")])
10300 (define_expand "msad_ubq"
10301 [(match_operand:DI 0 "arith_reg_dest" "")
10302 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10303 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10304 (match_operand:DI 3 "arith_reg_operand" "")]
10308 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10309 operands[1], operands[2]));
10313 (define_insn "msad_ubq_i"
10314 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10319 (match_operand:DI 1 "arith_reg_operand" "0")
10320 (abs:DI (vec_select:DI
10323 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10325 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10326 (parallel [(const_int 0)]))))
10327 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10328 (zero_extend:V8DI (match_dup 3)))
10329 (parallel [(const_int 1)]))))
10331 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10332 (zero_extend:V8DI (match_dup 3)))
10333 (parallel [(const_int 2)])))
10334 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10335 (zero_extend:V8DI (match_dup 3)))
10336 (parallel [(const_int 3)])))))
10339 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10340 (zero_extend:V8DI (match_dup 3)))
10341 (parallel [(const_int 4)])))
10342 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10343 (zero_extend:V8DI (match_dup 3)))
10344 (parallel [(const_int 5)]))))
10346 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10347 (zero_extend:V8DI (match_dup 3)))
10348 (parallel [(const_int 6)])))
10349 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10350 (zero_extend:V8DI (match_dup 3)))
10351 (parallel [(const_int 7)])))))))]
10353 "msad.ubq %N2, %N3, %0"
10354 [(set_attr "type" "mac_media")])
10356 (define_insn "mshalds_l"
10357 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10360 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10361 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10362 (const_int 31)))))]
10364 "mshalds.l %1, %2, %0"
10365 [(set_attr "type" "mcmp_media")])
10367 (define_insn "mshalds_w"
10368 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10371 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10372 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10373 (const_int 15)))))]
10375 "mshalds.w %1, %2, %0"
10376 [(set_attr "type" "mcmp_media")])
10378 (define_insn "ashrv2si3"
10379 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10380 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10381 (match_operand:DI 2 "arith_reg_operand" "r")))]
10383 "mshard.l %1, %2, %0"
10384 [(set_attr "type" "arith_media")])
10386 (define_insn "ashrv4hi3"
10387 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10388 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10389 (match_operand:DI 2 "arith_reg_operand" "r")))]
10391 "mshard.w %1, %2, %0"
10392 [(set_attr "type" "arith_media")])
10394 (define_insn "mshards_q"
10395 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10397 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10398 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10400 "mshards.q %1, %N2, %0"
10401 [(set_attr "type" "mcmp_media")])
10403 (define_expand "mshfhi_b"
10404 [(match_operand:V8QI 0 "arith_reg_dest" "")
10405 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10406 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10410 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10411 (operands[0], operands[1], operands[2]));
10415 (define_expand "mshflo_b"
10416 [(match_operand:V8QI 0 "arith_reg_dest" "")
10417 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10418 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10422 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10423 (operands[0], operands[1], operands[2]));
10427 (define_insn "mshf4_b"
10429 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10431 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10432 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10433 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10434 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10436 "* return (TARGET_LITTLE_ENDIAN
10437 ? \"mshfhi.b %N1, %N2, %0\"
10438 : \"mshflo.b %N1, %N2, %0\");"
10439 [(set_attr "type" "arith_media")])
10441 (define_insn "mshf0_b"
10443 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10445 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10446 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10447 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10448 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10450 "* return (TARGET_LITTLE_ENDIAN
10451 ? \"mshflo.b %N1, %N2, %0\"
10452 : \"mshfhi.b %N1, %N2, %0\");"
10453 [(set_attr "type" "arith_media")])
10455 (define_expand "mshfhi_l"
10456 [(match_operand:V2SI 0 "arith_reg_dest" "")
10457 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10458 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10462 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10463 (operands[0], operands[1], operands[2]));
10467 (define_expand "mshflo_l"
10468 [(match_operand:V2SI 0 "arith_reg_dest" "")
10469 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10470 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10474 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10475 (operands[0], operands[1], operands[2]));
10479 (define_insn "mshf4_l"
10480 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10482 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10483 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10484 (parallel [(const_int 1) (const_int 3)])))]
10486 "* return (TARGET_LITTLE_ENDIAN
10487 ? \"mshfhi.l %N1, %N2, %0\"
10488 : \"mshflo.l %N1, %N2, %0\");"
10489 [(set_attr "type" "arith_media")])
10491 (define_insn "mshf0_l"
10492 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10494 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10496 (parallel [(const_int 0) (const_int 2)])))]
10498 "* return (TARGET_LITTLE_ENDIAN
10499 ? \"mshflo.l %N1, %N2, %0\"
10500 : \"mshfhi.l %N1, %N2, %0\");"
10501 [(set_attr "type" "arith_media")])
10503 (define_expand "mshfhi_w"
10504 [(match_operand:V4HI 0 "arith_reg_dest" "")
10505 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10506 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10510 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10511 (operands[0], operands[1], operands[2]));
10515 (define_expand "mshflo_w"
10516 [(match_operand:V4HI 0 "arith_reg_dest" "")
10517 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10518 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10522 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10523 (operands[0], operands[1], operands[2]));
10527 (define_insn "mshf4_w"
10528 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10530 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10531 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10532 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10534 "* return (TARGET_LITTLE_ENDIAN
10535 ? \"mshfhi.w %N1, %N2, %0\"
10536 : \"mshflo.w %N1, %N2, %0\");"
10537 [(set_attr "type" "arith_media")])
10539 (define_insn "mshf0_w"
10540 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10542 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10543 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10544 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10546 "* return (TARGET_LITTLE_ENDIAN
10547 ? \"mshflo.w %N1, %N2, %0\"
10548 : \"mshfhi.w %N1, %N2, %0\");"
10549 [(set_attr "type" "arith_media")])
10551 (define_insn "mshflo_w_x"
10552 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10554 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10555 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10556 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10558 "mshflo.w %N1, %N2, %0"
10559 [(set_attr "type" "arith_media")])
10561 /* These are useful to expand ANDs and as combiner patterns. */
10562 (define_insn_and_split "mshfhi_l_di"
10563 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10564 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10566 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10567 (const_int -4294967296))))]
10570 mshfhi.l %N1, %N2, %0
10572 "TARGET_SHMEDIA && reload_completed
10573 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10574 [(set (match_dup 3) (match_dup 4))
10575 (set (match_dup 5) (match_dup 6))]
10578 operands[3] = gen_lowpart (SImode, operands[0]);
10579 operands[4] = gen_highpart (SImode, operands[1]);
10580 operands[5] = gen_highpart (SImode, operands[0]);
10581 operands[6] = gen_highpart (SImode, operands[2]);
10583 [(set_attr "type" "arith_media")])
10585 (define_insn "*mshfhi_l_di_rev"
10586 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10587 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10588 (const_int -4294967296))
10589 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10592 "mshfhi.l %N2, %N1, %0"
10593 [(set_attr "type" "arith_media")])
10596 [(set (match_operand:DI 0 "arith_reg_dest" "")
10597 (ior:DI (zero_extend:DI (match_operand:SI 1
10598 "extend_reg_or_0_operand" ""))
10599 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10600 (const_int -4294967296))))
10601 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10606 emit_insn (gen_ashldi3_media (operands[3],
10607 simplify_gen_subreg (DImode, operands[1],
10610 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10614 (define_insn "mshflo_l_di"
10615 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10616 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10617 (const_int 4294967295))
10618 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10622 "mshflo.l %N1, %N2, %0"
10623 [(set_attr "type" "arith_media")])
10625 (define_insn "*mshflo_l_di_rev"
10626 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10627 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10629 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10630 (const_int 4294967295))))]
10633 "mshflo.l %N2, %N1, %0"
10634 [(set_attr "type" "arith_media")])
10636 ;; Combiner pattern for trampoline initialization.
10637 (define_insn_and_split "*double_shori"
10638 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10639 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10641 (match_operand:DI 2 "const_int_operand" "n")))]
10643 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10645 "rtx_equal_p (operands[0], operands[1])"
10649 HOST_WIDE_INT v = INTVAL (operands[2]);
10651 emit_insn (gen_shori_media (operands[0], operands[0],
10652 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10653 emit_insn (gen_shori_media (operands[0], operands[0],
10654 gen_int_mode (v, HImode)));
10659 (define_insn "*mshflo_l_di_x"
10660 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10661 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10663 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10667 "mshflo.l %N1, %N2, %0"
10668 [(set_attr "type" "arith_media")])
10670 (define_insn_and_split "concat_v2sf"
10671 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10672 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10673 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10674 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10678 mshflo.l %N1, %N2, %0
10681 "TARGET_SHMEDIA && reload_completed
10682 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10683 [(set (match_dup 3) (match_dup 1))
10684 (set (match_dup 4) (match_dup 2))]
10687 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10688 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10690 [(set_attr "type" "arith_media")])
10692 (define_insn "*mshflo_l_di_x_rev"
10693 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10694 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10696 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10699 "mshflo.l %N2, %N1, %0"
10700 [(set_attr "type" "arith_media")])
10702 (define_insn "ashlv2si3"
10703 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10704 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10705 (match_operand:DI 2 "arith_reg_operand" "r")))]
10707 "mshlld.l %1, %2, %0"
10708 [(set_attr "type" "arith_media")])
10710 (define_insn "ashlv4hi3"
10711 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10712 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10713 (match_operand:DI 2 "arith_reg_operand" "r")))]
10715 "mshlld.w %1, %2, %0"
10716 [(set_attr "type" "arith_media")])
10718 (define_insn "lshrv2si3"
10719 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10720 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10721 (match_operand:DI 2 "arith_reg_operand" "r")))]
10723 "mshlrd.l %1, %2, %0"
10724 [(set_attr "type" "arith_media")])
10726 (define_insn "lshrv4hi3"
10727 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10728 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10729 (match_operand:DI 2 "arith_reg_operand" "r")))]
10731 "mshlrd.w %1, %2, %0"
10732 [(set_attr "type" "arith_media")])
10734 (define_insn "subv2si3"
10735 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10736 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10737 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10739 "msub.l %N1, %2, %0"
10740 [(set_attr "type" "arith_media")])
10742 (define_insn "subv4hi3"
10743 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10744 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10745 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10747 "msub.w %N1, %2, %0"
10748 [(set_attr "type" "arith_media")])
10750 (define_insn "sssubv2si3"
10751 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10752 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10753 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10755 "msubs.l %N1, %2, %0"
10756 [(set_attr "type" "mcmp_media")])
10758 (define_insn "ussubv8qi3"
10759 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10760 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10761 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10763 "msubs.ub %1, %2, %0"
10764 [(set_attr "type" "mcmp_media")])
10766 (define_insn "sssubv4hi3"
10767 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10768 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10769 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10771 "msubs.w %N1, %2, %0"
10772 [(set_attr "type" "mcmp_media")])
10774 ;; Floating Point Intrinsics
10776 (define_insn "fcosa_s"
10777 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10778 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10782 [(set_attr "type" "atrans_media")])
10784 (define_insn "fsina_s"
10785 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10786 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10790 [(set_attr "type" "atrans_media")])
10792 (define_insn "fipr"
10793 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10794 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10795 "fp_arith_reg_operand" "f")
10796 (match_operand:V4SF 2
10797 "fp_arith_reg_operand" "f"))
10798 (parallel [(const_int 0)]))
10799 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10800 (parallel [(const_int 1)])))
10801 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10802 (parallel [(const_int 2)]))
10803 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10804 (parallel [(const_int 3)])))))]
10806 "fipr.s %1, %2, %0"
10807 [(set_attr "type" "fparith_media")])
10809 (define_insn "fsrra_s"
10810 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10811 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10815 [(set_attr "type" "atrans_media")])
10817 (define_insn "ftrv"
10818 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10822 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10823 (parallel [(const_int 0) (const_int 5)
10824 (const_int 10) (const_int 15)]))
10825 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10827 (vec_select:V4SF (match_dup 1)
10828 (parallel [(const_int 4) (const_int 9)
10829 (const_int 14) (const_int 3)]))
10830 (vec_select:V4SF (match_dup 2)
10831 (parallel [(const_int 1) (const_int 2)
10832 (const_int 3) (const_int 0)]))))
10835 (vec_select:V4SF (match_dup 1)
10836 (parallel [(const_int 8) (const_int 13)
10837 (const_int 2) (const_int 7)]))
10838 (vec_select:V4SF (match_dup 2)
10839 (parallel [(const_int 2) (const_int 3)
10840 (const_int 0) (const_int 1)])))
10842 (vec_select:V4SF (match_dup 1)
10843 (parallel [(const_int 12) (const_int 1)
10844 (const_int 6) (const_int 11)]))
10845 (vec_select:V4SF (match_dup 2)
10846 (parallel [(const_int 3) (const_int 0)
10847 (const_int 1) (const_int 2)]))))))]
10849 "ftrv.s %1, %2, %0"
10850 [(set_attr "type" "fparith_media")])
10853 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10854 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10858 [(set_attr "type" "arith_media")])
10860 (define_insn "nsbsi"
10861 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10863 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10867 [(set_attr "type" "arith_media")])
10869 (define_insn "nsbdi"
10870 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10872 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10876 [(set_attr "type" "arith_media")])
10878 (define_expand "ffsdi2"
10879 [(set (match_operand:DI 0 "arith_reg_dest" "")
10880 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10884 rtx scratch = gen_reg_rtx (DImode);
10887 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10888 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10889 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10890 emit_insn (gen_nsbdi (scratch, scratch));
10891 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10892 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10893 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10895 = gen_rtx_EXPR_LIST (REG_EQUAL,
10896 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10900 (define_expand "ffssi2"
10901 [(set (match_operand:SI 0 "arith_reg_dest" "")
10902 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10906 rtx scratch = gen_reg_rtx (SImode);
10907 rtx discratch = gen_reg_rtx (DImode);
10910 emit_insn (gen_adddi3 (discratch,
10911 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10913 emit_insn (gen_andcdi3 (discratch,
10914 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10916 emit_insn (gen_nsbsi (scratch, discratch));
10917 last = emit_insn (gen_subsi3 (operands[0],
10918 force_reg (SImode, GEN_INT (63)), scratch));
10920 = gen_rtx_EXPR_LIST (REG_EQUAL,
10921 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10925 (define_insn "byterev"
10926 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10927 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10928 (parallel [(const_int 7) (const_int 6) (const_int 5)
10929 (const_int 4) (const_int 3) (const_int 2)
10930 (const_int 1) (const_int 0)])))]
10933 [(set_attr "type" "arith_media")])
10935 (define_insn "prefetch"
10936 [(prefetch (match_operand:QI 0 "address_operand" "p")
10937 (match_operand:SI 1 "const_int_operand" "n")
10938 (match_operand:SI 2 "const_int_operand" "n"))]
10939 "TARGET_SHMEDIA || TARGET_HARD_SH4"
10942 if (TARGET_HARD_SH4)
10943 return \"pref @%0\";
10944 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10945 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10948 [(set_attr "type" "other")])