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,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.
528 (and (eq_attr "type" "cbranch")
529 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
530 ;; SH2e has a hardware bug that pretty much prohibits the use of
531 ;; annuled delay slots.
532 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
533 (not (eq_attr "cpu" "sh2e"))) (nil)])
535 ;; -------------------------------------------------------------------------
536 ;; SImode signed integer comparisons
537 ;; -------------------------------------------------------------------------
541 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
542 (match_operand:SI 1 "arith_operand" "K08,r"))
546 [(set_attr "type" "mt_group")])
548 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
549 ;; That would still allow reload to create cmpi instructions, but would
550 ;; perhaps allow forcing the constant into a register when that is better.
551 ;; Probably should use r0 for mem/imm compares, but force constant into a
552 ;; register for pseudo/imm compares.
554 (define_insn "cmpeqsi_t"
556 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
557 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
563 [(set_attr "type" "mt_group")])
565 (define_insn "cmpgtsi_t"
567 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
568 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
573 [(set_attr "type" "mt_group")])
575 (define_insn "cmpgesi_t"
577 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
578 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
583 [(set_attr "type" "mt_group")])
585 ;; -------------------------------------------------------------------------
586 ;; SImode unsigned integer comparisons
587 ;; -------------------------------------------------------------------------
589 (define_insn "cmpgeusi_t"
591 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
592 (match_operand:SI 1 "arith_reg_operand" "r")))]
595 [(set_attr "type" "mt_group")])
597 (define_insn "cmpgtusi_t"
599 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
600 (match_operand:SI 1 "arith_reg_operand" "r")))]
603 [(set_attr "type" "mt_group")])
605 ;; We save the compare operands in the cmpxx patterns and use them when
606 ;; we generate the branch.
608 (define_expand "cmpsi"
610 (compare (match_operand:SI 0 "cmpsi_operand" "")
611 (match_operand:SI 1 "arith_operand" "")))]
615 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
616 && GET_CODE (operands[1]) != CONST_INT)
617 operands[0] = copy_to_mode_reg (SImode, operands[0]);
618 sh_compare_op0 = operands[0];
619 sh_compare_op1 = operands[1];
623 ;; -------------------------------------------------------------------------
624 ;; DImode signed integer comparisons
625 ;; -------------------------------------------------------------------------
627 ;; ??? Could get better scheduling by splitting the initial test from the
628 ;; rest of the insn after reload. However, the gain would hardly justify
629 ;; the sh.md size increase necessary to do that.
633 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
634 (match_operand:DI 1 "arith_operand" "r"))
637 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
639 [(set_attr "length" "6")
640 (set_attr "type" "arith3b")])
642 (define_insn "cmpeqdi_t"
644 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
645 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
648 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
649 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
650 [(set_attr "length" "6")
651 (set_attr "type" "arith3b")])
655 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
656 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
657 ;; If we applied this split when not optimizing, it would only be
658 ;; applied during the machine-dependent reorg, when no new basic blocks
660 "TARGET_SH1 && reload_completed && optimize"
661 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
662 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
663 (label_ref (match_dup 6))
665 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
670 = gen_rtx_REG (SImode,
671 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
673 = (operands[1] == const0_rtx
675 : gen_rtx_REG (SImode,
676 true_regnum (operands[1])
677 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
678 operands[4] = gen_lowpart (SImode, operands[0]);
679 operands[5] = gen_lowpart (SImode, operands[1]);
680 operands[6] = gen_label_rtx ();
683 (define_insn "cmpgtdi_t"
685 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
686 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
689 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
690 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
691 [(set_attr "length" "8")
692 (set_attr "type" "arith3")])
694 (define_insn "cmpgedi_t"
696 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
697 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
700 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
702 [(set_attr "length" "8,2")
703 (set_attr "type" "arith3,mt_group")])
705 ;; -------------------------------------------------------------------------
706 ;; DImode unsigned integer comparisons
707 ;; -------------------------------------------------------------------------
709 (define_insn "cmpgeudi_t"
711 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
712 (match_operand:DI 1 "arith_reg_operand" "r")))]
714 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
715 [(set_attr "length" "8")
716 (set_attr "type" "arith3")])
718 (define_insn "cmpgtudi_t"
720 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
721 (match_operand:DI 1 "arith_reg_operand" "r")))]
723 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
724 [(set_attr "length" "8")
725 (set_attr "type" "arith3")])
727 (define_insn "cmpeqdi_media"
728 [(set (match_operand:DI 0 "register_operand" "=r")
729 (eq:DI (match_operand:DI 1 "register_operand" "%r")
730 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
733 [(set_attr "type" "cmp_media")])
735 (define_insn "cmpgtdi_media"
736 [(set (match_operand:DI 0 "register_operand" "=r")
737 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
738 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
741 [(set_attr "type" "cmp_media")])
743 (define_insn "cmpgtudi_media"
744 [(set (match_operand:DI 0 "register_operand" "=r")
745 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
746 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
748 "cmpgtu %N1, %N2, %0"
749 [(set_attr "type" "cmp_media")])
751 ;; We save the compare operands in the cmpxx patterns and use them when
752 ;; we generate the branch.
754 (define_expand "cmpdi"
756 (compare (match_operand:DI 0 "arith_operand" "")
757 (match_operand:DI 1 "arith_operand" "")))]
758 "TARGET_SH2 || TARGET_SHMEDIA"
761 sh_compare_op0 = operands[0];
762 sh_compare_op1 = operands[1];
765 ;; -------------------------------------------------------------------------
766 ;; Conditional move instructions
767 ;; -------------------------------------------------------------------------
769 ;; The insn names may seem reversed, but note that cmveq performs the move
770 ;; if op1 == 0, and cmvne does it if op1 != 0.
772 (define_insn "movdicc_false"
773 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
774 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
776 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
777 (match_operand:DI 3 "arith_reg_operand" "0")))]
780 [(set_attr "type" "arith_media")])
782 (define_insn "movdicc_true"
783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
784 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
786 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
787 (match_operand:DI 3 "arith_reg_operand" "0")))]
790 [(set_attr "type" "arith_media")])
792 (define_expand "movdicc"
793 [(set (match_operand:DI 0 "register_operand" "")
794 (if_then_else:DI (match_operand 1 "comparison_operator" "")
795 (match_operand:DI 2 "register_operand" "")
796 (match_operand:DI 3 "register_operand" "")))]
800 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
801 && GET_MODE (sh_compare_op0) == DImode
802 && sh_compare_op1 == const0_rtx)
803 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
804 sh_compare_op0, sh_compare_op1);
812 tmp = gen_reg_rtx (DImode);
814 switch (GET_CODE (operands[1]))
817 emit_insn (gen_seq (tmp));
818 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
822 emit_insn (gen_seq (tmp));
823 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
827 emit_insn (gen_sgt (tmp));
828 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
832 emit_insn (gen_slt (tmp));
833 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
837 emit_insn (gen_slt (tmp));
838 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
842 emit_insn (gen_sgt (tmp));
843 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
847 emit_insn (gen_sgtu (tmp));
848 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
852 emit_insn (gen_sltu (tmp));
853 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
857 emit_insn (gen_sltu (tmp));
858 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
862 emit_insn (gen_sgtu (tmp));
863 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
867 emit_insn (gen_sunordered (tmp));
868 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
872 emit_insn (gen_sunordered (tmp));
873 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
890 ;; -------------------------------------------------------------------------
891 ;; Addition instructions
892 ;; -------------------------------------------------------------------------
894 (define_expand "adddi3"
895 [(set (match_operand:DI 0 "arith_reg_operand" "")
896 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
897 (match_operand:DI 2 "arith_operand" "")))]
903 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
905 operands[2] = force_reg (DImode, operands[2]);
906 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
911 (define_insn "*adddi3_media"
912 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
913 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
914 (match_operand:DI 2 "arith_operand" "r,I10")))]
919 [(set_attr "type" "arith_media")])
921 (define_insn "adddi3z_media"
922 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
924 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
925 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
928 [(set_attr "type" "arith_media")])
930 (define_insn "adddi3_compact"
931 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
932 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
933 (match_operand:DI 2 "arith_reg_operand" "r")))
934 (clobber (reg:SI T_REG))]
937 [(set_attr "length" "6")])
940 [(set (match_operand:DI 0 "arith_reg_operand" "")
941 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
942 (match_operand:DI 2 "arith_reg_operand" "")))
943 (clobber (reg:SI T_REG))]
944 "TARGET_SH1 && reload_completed"
948 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
949 high0 = gen_rtx_REG (SImode,
950 true_regnum (operands[0])
951 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
952 high2 = gen_rtx_REG (SImode,
953 true_regnum (operands[2])
954 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
955 emit_insn (gen_clrt ());
956 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
957 emit_insn (gen_addc1 (high0, high0, high2));
962 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
963 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
964 (match_operand:SI 2 "arith_reg_operand" "r"))
967 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
970 [(set_attr "type" "arith")])
973 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
974 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
975 (match_operand:SI 2 "arith_reg_operand" "r"))
977 (clobber (reg:SI T_REG))]
980 [(set_attr "type" "arith")])
982 (define_expand "addsi3"
983 [(set (match_operand:SI 0 "arith_reg_operand" "")
984 (plus:SI (match_operand:SI 1 "arith_operand" "")
985 (match_operand:SI 2 "arith_operand" "")))]
990 operands[1] = force_reg (SImode, operands[1]);
993 (define_insn "addsi3_media"
994 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
995 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
996 (match_operand:SI 2 "arith_operand" "r,I10")))]
1001 [(set_attr "type" "arith_media")])
1003 (define_insn "*addsi3_compact"
1004 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1005 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1006 (match_operand:SI 2 "arith_operand" "rI08")))]
1009 [(set_attr "type" "arith")])
1011 ;; -------------------------------------------------------------------------
1012 ;; Subtraction instructions
1013 ;; -------------------------------------------------------------------------
1015 (define_expand "subdi3"
1016 [(set (match_operand:DI 0 "arith_reg_operand" "")
1017 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1018 (match_operand:DI 2 "arith_reg_operand" "")))]
1024 operands[1] = force_reg (DImode, operands[1]);
1025 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1030 (define_insn "*subdi3_media"
1031 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1032 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1033 (match_operand:DI 2 "arith_reg_operand" "r")))]
1036 [(set_attr "type" "arith_media")])
1038 (define_insn "subdi3_compact"
1039 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1040 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1041 (match_operand:DI 2 "arith_reg_operand" "r")))
1042 (clobber (reg:SI T_REG))]
1045 [(set_attr "length" "6")])
1048 [(set (match_operand:DI 0 "arith_reg_operand" "")
1049 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1050 (match_operand:DI 2 "arith_reg_operand" "")))
1051 (clobber (reg:SI T_REG))]
1052 "TARGET_SH1 && reload_completed"
1056 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1057 high0 = gen_rtx_REG (SImode,
1058 true_regnum (operands[0])
1059 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1060 high2 = gen_rtx_REG (SImode,
1061 true_regnum (operands[2])
1062 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1063 emit_insn (gen_clrt ());
1064 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1065 emit_insn (gen_subc1 (high0, high0, high2));
1070 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1071 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1072 (match_operand:SI 2 "arith_reg_operand" "r"))
1075 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1080 [(set_attr "type" "arith")])
1082 (define_insn "subc1"
1083 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1084 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1085 (match_operand:SI 2 "arith_reg_operand" "r"))
1087 (clobber (reg:SI T_REG))]
1090 [(set_attr "type" "arith")])
1092 (define_insn "*subsi3_internal"
1093 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1094 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1095 (match_operand:SI 2 "arith_reg_operand" "r")))]
1098 [(set_attr "type" "arith")])
1100 (define_insn "*subsi3_media"
1101 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1102 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1103 (match_operand:SI 2 "extend_reg_operand" "r")))]
1106 [(set_attr "type" "arith_media")])
1108 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1109 ;; will sometimes save one instruction. Otherwise we might get
1110 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1113 (define_expand "subsi3"
1114 [(set (match_operand:SI 0 "arith_reg_operand" "")
1115 (minus:SI (match_operand:SI 1 "arith_operand" "")
1116 (match_operand:SI 2 "arith_reg_operand" "")))]
1120 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1122 emit_insn (gen_negsi2 (operands[0], operands[2]));
1123 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1128 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1130 if (operands[1] != const0_rtx)
1131 operands[1] = force_reg (SImode, operands[1]);
1135 ;; -------------------------------------------------------------------------
1136 ;; Division instructions
1137 ;; -------------------------------------------------------------------------
1139 ;; We take advantage of the library routines which don't clobber as many
1140 ;; registers as a normal function call would.
1142 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1143 ;; also has an effect on the register that holds the address of the sfunc.
1144 ;; To make this work, we have an extra dummy insn that shows the use
1145 ;; of this register for reorg.
1147 (define_insn "use_sfunc_addr"
1148 [(set (reg:SI PR_REG)
1149 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1150 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1152 [(set_attr "length" "0")])
1154 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1155 ;; hard register 0. If we used hard register 0, then the next instruction
1156 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1157 ;; gets allocated to a stack slot that needs its address reloaded, then
1158 ;; there is nothing to prevent reload from using r0 to reload the address.
1159 ;; This reload would clobber the value in r0 we are trying to store.
1160 ;; If we let reload allocate r0, then this problem can never happen.
1162 (define_insn "udivsi3_i1"
1163 [(set (match_operand:SI 0 "register_operand" "=z")
1164 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1165 (clobber (reg:SI T_REG))
1166 (clobber (reg:SI PR_REG))
1167 (clobber (reg:SI R4_REG))
1168 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1169 "TARGET_SH1 && ! TARGET_SH4"
1171 [(set_attr "type" "sfunc")
1172 (set_attr "needs_delay_slot" "yes")])
1174 ; Since shmedia-nofpu code could be linked against shcompact code, and
1175 ; the udivsi3 libcall has the same name, we must consider all registers
1176 ; clobbered that are in the union of the registers clobbered by the
1177 ; shmedia and the shcompact implementation. Note, if the shcompact
1178 ; implementation actually used shcompact code, we'd need to clobber
1179 ; also r23 and fr23.
1180 (define_insn "udivsi3_i1_media"
1181 [(set (match_operand:SI 0 "register_operand" "=z")
1182 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1183 (clobber (reg:SI T_MEDIA_REG))
1184 (clobber (reg:SI PR_MEDIA_REG))
1185 (clobber (reg:SI R20_REG))
1186 (clobber (reg:SI R21_REG))
1187 (clobber (reg:SI R22_REG))
1188 (clobber (reg:DI TR0_REG))
1189 (clobber (reg:DI TR1_REG))
1190 (clobber (reg:DI TR2_REG))
1191 (use (match_operand:DI 1 "target_operand" "b"))]
1192 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1194 [(set_attr "type" "sfunc")
1195 (set_attr "needs_delay_slot" "yes")])
1197 (define_expand "udivsi3_i4_media"
1199 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1201 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1202 (set (match_dup 5) (float:DF (match_dup 3)))
1203 (set (match_dup 6) (float:DF (match_dup 4)))
1204 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1205 (set (match_dup 8) (fix:DI (match_dup 7)))
1206 (set (match_operand:SI 0 "register_operand" "")
1207 (truncate:SI (match_dup 8)))]
1208 "TARGET_SHMEDIA_FPU"
1211 operands[3] = gen_reg_rtx (DImode);
1212 operands[4] = gen_reg_rtx (DImode);
1213 operands[5] = gen_reg_rtx (DFmode);
1214 operands[6] = gen_reg_rtx (DFmode);
1215 operands[7] = gen_reg_rtx (DFmode);
1216 operands[8] = gen_reg_rtx (DImode);
1219 (define_insn "udivsi3_i4"
1220 [(set (match_operand:SI 0 "register_operand" "=y")
1221 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1222 (clobber (reg:SI T_REG))
1223 (clobber (reg:SI PR_REG))
1224 (clobber (reg:DF DR0_REG))
1225 (clobber (reg:DF DR2_REG))
1226 (clobber (reg:DF DR4_REG))
1227 (clobber (reg:SI R0_REG))
1228 (clobber (reg:SI R1_REG))
1229 (clobber (reg:SI R4_REG))
1230 (clobber (reg:SI R5_REG))
1231 (use (reg:PSI FPSCR_REG))
1232 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1233 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1235 [(set_attr "type" "sfunc")
1236 (set_attr "fp_mode" "double")
1237 (set_attr "needs_delay_slot" "yes")])
1239 (define_insn "udivsi3_i4_single"
1240 [(set (match_operand:SI 0 "register_operand" "=y")
1241 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1242 (clobber (reg:SI T_REG))
1243 (clobber (reg:SI PR_REG))
1244 (clobber (reg:DF DR0_REG))
1245 (clobber (reg:DF DR2_REG))
1246 (clobber (reg:DF DR4_REG))
1247 (clobber (reg:SI R0_REG))
1248 (clobber (reg:SI R1_REG))
1249 (clobber (reg:SI R4_REG))
1250 (clobber (reg:SI R5_REG))
1251 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1252 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1254 [(set_attr "type" "sfunc")
1255 (set_attr "needs_delay_slot" "yes")])
1257 (define_expand "udivsi3"
1258 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1259 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1260 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1261 (parallel [(set (match_operand:SI 0 "register_operand" "")
1262 (udiv:SI (reg:SI R4_REG)
1264 (clobber (reg:SI T_REG))
1265 (clobber (reg:SI PR_REG))
1266 (clobber (reg:SI R4_REG))
1267 (use (match_dup 3))])]
1273 operands[3] = gen_reg_rtx (Pmode);
1274 /* Emit the move of the address to a pseudo outside of the libcall. */
1275 if (TARGET_HARD_SH4 && TARGET_SH2E)
1277 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1278 if (TARGET_FPU_SINGLE)
1279 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1281 last = gen_udivsi3_i4 (operands[0], operands[3]);
1283 else if (TARGET_SHMEDIA_FPU)
1285 operands[1] = force_reg (SImode, operands[1]);
1286 operands[2] = force_reg (SImode, operands[2]);
1287 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1290 else if (TARGET_SH5)
1292 emit_move_insn (operands[3],
1293 function_symbol (TARGET_FPU_ANY
1298 last = gen_udivsi3_i1_media (operands[0],
1301 : gen_rtx_SUBREG (DImode, operands[3],
1303 else if (TARGET_FPU_ANY)
1304 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1306 last = gen_udivsi3_i1 (operands[0], operands[3]);
1310 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1311 last = gen_udivsi3_i1 (operands[0], operands[3]);
1313 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1314 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1315 last = emit_insn (last);
1316 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1317 invariant code motion can move it. */
1318 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1319 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1323 (define_insn "divsi3_i1"
1324 [(set (match_operand:SI 0 "register_operand" "=z")
1325 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1326 (clobber (reg:SI T_REG))
1327 (clobber (reg:SI PR_REG))
1328 (clobber (reg:SI R1_REG))
1329 (clobber (reg:SI R2_REG))
1330 (clobber (reg:SI R3_REG))
1331 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1332 "TARGET_SH1 && ! TARGET_SH4"
1334 [(set_attr "type" "sfunc")
1335 (set_attr "needs_delay_slot" "yes")])
1337 ; Since shmedia-nofpu code could be linked against shcompact code, and
1338 ; the sdivsi3 libcall has the same name, we must consider all registers
1339 ; clobbered that are in the union of the registers clobbered by the
1340 ; shmedia and the shcompact implementation. Note, if the shcompact
1341 ; implementation actually used shcompact code, we'd need to clobber
1342 ; also r22, r23 and fr23.
1343 (define_insn "divsi3_i1_media"
1344 [(set (match_operand:SI 0 "register_operand" "=z")
1345 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1346 (clobber (reg:SI T_MEDIA_REG))
1347 (clobber (reg:SI PR_MEDIA_REG))
1348 (clobber (reg:SI R1_REG))
1349 (clobber (reg:SI R2_REG))
1350 (clobber (reg:SI R3_REG))
1351 (clobber (reg:SI R20_REG))
1352 (clobber (reg:SI R21_REG))
1353 (clobber (reg:DI TR0_REG))
1354 (clobber (reg:DI TR1_REG))
1355 (clobber (reg:DI TR2_REG))
1356 (use (match_operand:DI 1 "target_operand" "b"))]
1357 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1359 [(set_attr "type" "sfunc")])
1361 (define_expand "divsi3_i4_media"
1362 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1363 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1364 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1365 (set (match_operand:SI 0 "register_operand" "=r")
1366 (fix:SI (match_dup 5)))]
1367 "TARGET_SHMEDIA_FPU"
1370 operands[3] = gen_reg_rtx (DFmode);
1371 operands[4] = gen_reg_rtx (DFmode);
1372 operands[5] = gen_reg_rtx (DFmode);
1375 (define_insn "divsi3_i4"
1376 [(set (match_operand:SI 0 "register_operand" "=y")
1377 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1378 (clobber (reg:SI PR_REG))
1379 (clobber (reg:DF DR0_REG))
1380 (clobber (reg:DF DR2_REG))
1381 (use (reg:PSI FPSCR_REG))
1382 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1383 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1385 [(set_attr "type" "sfunc")
1386 (set_attr "fp_mode" "double")
1387 (set_attr "needs_delay_slot" "yes")])
1389 (define_insn "divsi3_i4_single"
1390 [(set (match_operand:SI 0 "register_operand" "=y")
1391 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1392 (clobber (reg:SI PR_REG))
1393 (clobber (reg:DF DR0_REG))
1394 (clobber (reg:DF DR2_REG))
1395 (clobber (reg:SI R2_REG))
1396 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1397 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1399 [(set_attr "type" "sfunc")
1400 (set_attr "needs_delay_slot" "yes")])
1402 (define_expand "divsi3"
1403 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1404 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1405 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1406 (parallel [(set (match_operand:SI 0 "register_operand" "")
1407 (div:SI (reg:SI R4_REG)
1409 (clobber (reg:SI T_REG))
1410 (clobber (reg:SI PR_REG))
1411 (clobber (reg:SI R1_REG))
1412 (clobber (reg:SI R2_REG))
1413 (clobber (reg:SI R3_REG))
1414 (use (match_dup 3))])]
1420 operands[3] = gen_reg_rtx (Pmode);
1421 /* Emit the move of the address to a pseudo outside of the libcall. */
1422 if (TARGET_HARD_SH4 && TARGET_SH2E)
1424 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1425 if (TARGET_FPU_SINGLE)
1426 last = gen_divsi3_i4_single (operands[0], operands[3]);
1428 last = gen_divsi3_i4 (operands[0], operands[3]);
1430 else if (TARGET_SHMEDIA_FPU)
1432 operands[1] = force_reg (SImode, operands[1]);
1433 operands[2] = force_reg (SImode, operands[2]);
1434 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1437 else if (TARGET_SH5)
1439 emit_move_insn (operands[3],
1440 function_symbol (TARGET_FPU_ANY
1445 last = gen_divsi3_i1_media (operands[0],
1448 : gen_rtx_SUBREG (DImode, operands[3],
1450 else if (TARGET_FPU_ANY)
1451 last = gen_divsi3_i4_single (operands[0], operands[3]);
1453 last = gen_divsi3_i1 (operands[0], operands[3]);
1457 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1458 last = gen_divsi3_i1 (operands[0], operands[3]);
1460 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1461 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1462 last = emit_insn (last);
1463 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1464 invariant code motion can move it. */
1465 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1466 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1470 ;; -------------------------------------------------------------------------
1471 ;; Multiplication instructions
1472 ;; -------------------------------------------------------------------------
1474 (define_insn "umulhisi3_i"
1475 [(set (reg:SI MACL_REG)
1476 (mult:SI (zero_extend:SI
1477 (match_operand:HI 0 "arith_reg_operand" "r"))
1479 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1482 [(set_attr "type" "smpy")])
1484 (define_insn "mulhisi3_i"
1485 [(set (reg:SI MACL_REG)
1486 (mult:SI (sign_extend:SI
1487 (match_operand:HI 0 "arith_reg_operand" "r"))
1489 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1492 [(set_attr "type" "smpy")])
1494 (define_expand "mulhisi3"
1495 [(set (reg:SI MACL_REG)
1496 (mult:SI (sign_extend:SI
1497 (match_operand:HI 1 "arith_reg_operand" ""))
1499 (match_operand:HI 2 "arith_reg_operand" ""))))
1500 (set (match_operand:SI 0 "arith_reg_operand" "")
1507 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1508 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1509 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1510 invariant code motion can move it. */
1511 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1512 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1513 /* expand_binop can't find a suitable code in umul_widen_optab to
1514 make a REG_EQUAL note from, so make one here.
1515 See also smulsi3_highpart.
1516 ??? Alternatively, we could put this at the calling site of expand_binop,
1517 i.e. expand_expr. */
1519 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1524 (define_expand "umulhisi3"
1525 [(set (reg:SI MACL_REG)
1526 (mult:SI (zero_extend:SI
1527 (match_operand:HI 1 "arith_reg_operand" ""))
1529 (match_operand:HI 2 "arith_reg_operand" ""))))
1530 (set (match_operand:SI 0 "arith_reg_operand" "")
1537 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1538 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1539 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1540 invariant code motion can move it. */
1541 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1542 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1543 /* expand_binop can't find a suitable code in umul_widen_optab to
1544 make a REG_EQUAL note from, so make one here.
1545 See also smulsi3_highpart.
1546 ??? Alternatively, we could put this at the calling site of expand_binop,
1547 i.e. expand_expr. */
1549 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1554 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1555 ;; a call to a routine which clobbers known registers.
1558 [(set (match_operand:SI 1 "register_operand" "=z")
1559 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1560 (clobber (reg:SI MACL_REG))
1561 (clobber (reg:SI T_REG))
1562 (clobber (reg:SI PR_REG))
1563 (clobber (reg:SI R3_REG))
1564 (clobber (reg:SI R2_REG))
1565 (clobber (reg:SI R1_REG))
1566 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1569 [(set_attr "type" "sfunc")
1570 (set_attr "needs_delay_slot" "yes")])
1572 (define_expand "mulsi3_call"
1573 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1574 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1575 (parallel[(set (match_operand:SI 0 "register_operand" "")
1576 (mult:SI (reg:SI R4_REG)
1578 (clobber (reg:SI MACL_REG))
1579 (clobber (reg:SI T_REG))
1580 (clobber (reg:SI PR_REG))
1581 (clobber (reg:SI R3_REG))
1582 (clobber (reg:SI R2_REG))
1583 (clobber (reg:SI R1_REG))
1584 (use (match_operand:SI 3 "register_operand" ""))])]
1588 (define_insn "mul_l"
1589 [(set (reg:SI MACL_REG)
1590 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1591 (match_operand:SI 1 "arith_reg_operand" "r")))]
1594 [(set_attr "type" "dmpy")])
1596 (define_expand "mulsi3"
1597 [(set (reg:SI MACL_REG)
1598 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1599 (match_operand:SI 2 "arith_reg_operand" "")))
1600 (set (match_operand:SI 0 "arith_reg_operand" "")
1609 /* The address must be set outside the libcall,
1610 since it goes into a pseudo. */
1611 rtx sym = function_symbol (\"__mulsi3\");
1612 rtx addr = force_reg (SImode, sym);
1613 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1616 last = emit_insn (insns);
1620 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1622 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1623 /* consec_sets_giv can only recognize the first insn that sets a
1624 giv as the giv insn. So we must tag this also with a REG_EQUAL
1626 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1628 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1629 invariant code motion can move it. */
1630 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1631 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1635 (define_insn "mulsidi3_i"
1636 [(set (reg:SI MACH_REG)
1640 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1641 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1643 (set (reg:SI MACL_REG)
1644 (mult:SI (match_dup 0)
1648 [(set_attr "type" "dmpy")])
1650 (define_expand "mulsidi3"
1651 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1652 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1653 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1654 "TARGET_SH2 || TARGET_SHMEDIA"
1659 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1665 (define_insn "mulsidi3_media"
1666 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1667 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1668 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1671 [(set_attr "type" "dmpy_media")])
1673 (define_insn "mulsidi3_compact"
1674 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1676 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1677 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1678 (clobber (reg:SI MACH_REG))
1679 (clobber (reg:SI MACL_REG))]
1684 [(set (match_operand:DI 0 "arith_reg_operand" "")
1686 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1687 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1688 (clobber (reg:SI MACH_REG))
1689 (clobber (reg:SI MACL_REG))]
1694 rtx low_dst = gen_lowpart (SImode, operands[0]);
1695 rtx high_dst = gen_highpart (SImode, operands[0]);
1697 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1699 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1700 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1701 /* We need something to tag the possible REG_EQUAL notes on to. */
1702 emit_move_insn (operands[0], operands[0]);
1706 (define_insn "umulsidi3_i"
1707 [(set (reg:SI MACH_REG)
1711 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1712 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1714 (set (reg:SI MACL_REG)
1715 (mult:SI (match_dup 0)
1719 [(set_attr "type" "dmpy")])
1721 (define_expand "umulsidi3"
1722 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1723 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1724 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1725 "TARGET_SH2 || TARGET_SHMEDIA"
1730 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1736 (define_insn "umulsidi3_media"
1737 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1738 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1739 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1742 [(set_attr "type" "dmpy_media")])
1744 (define_insn "umulsidi3_compact"
1745 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1747 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1748 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1749 (clobber (reg:SI MACH_REG))
1750 (clobber (reg:SI MACL_REG))]
1755 [(set (match_operand:DI 0 "arith_reg_operand" "")
1756 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1757 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1758 (clobber (reg:SI MACH_REG))
1759 (clobber (reg:SI MACL_REG))]
1764 rtx low_dst = gen_lowpart (SImode, operands[0]);
1765 rtx high_dst = gen_highpart (SImode, operands[0]);
1767 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1769 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1770 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1771 /* We need something to tag the possible REG_EQUAL notes on to. */
1772 emit_move_insn (operands[0], operands[0]);
1776 (define_insn "smulsi3_highpart_i"
1777 [(set (reg:SI MACH_REG)
1781 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1782 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1784 (clobber (reg:SI MACL_REG))]
1787 [(set_attr "type" "dmpy")])
1789 (define_expand "smulsi3_highpart"
1791 [(set (reg:SI MACH_REG)
1795 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1796 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1798 (clobber (reg:SI MACL_REG))])
1799 (set (match_operand:SI 0 "arith_reg_operand" "")
1806 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1807 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1808 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1809 invariant code motion can move it. */
1810 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1811 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1812 /* expand_binop can't find a suitable code in mul_highpart_optab to
1813 make a REG_EQUAL note from, so make one here.
1814 See also {,u}mulhisi.
1815 ??? Alternatively, we could put this at the calling site of expand_binop,
1816 i.e. expand_mult_highpart. */
1818 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1823 (define_insn "umulsi3_highpart_i"
1824 [(set (reg:SI MACH_REG)
1828 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1829 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1831 (clobber (reg:SI MACL_REG))]
1834 [(set_attr "type" "dmpy")])
1836 (define_expand "umulsi3_highpart"
1838 [(set (reg:SI MACH_REG)
1842 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1843 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1845 (clobber (reg:SI MACL_REG))])
1846 (set (match_operand:SI 0 "arith_reg_operand" "")
1853 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1854 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1855 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1856 invariant code motion can move it. */
1857 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1858 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1862 ;; -------------------------------------------------------------------------
1863 ;; Logical operations
1864 ;; -------------------------------------------------------------------------
1866 (define_insn "*andsi3_compact"
1867 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1868 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1869 (match_operand:SI 2 "logical_operand" "r,K08")))]
1872 [(set_attr "type" "arith")])
1874 ;; If the constant is 255, then emit an extu.b instruction instead of an
1875 ;; and, since that will give better code.
1877 (define_expand "andsi3"
1878 [(set (match_operand:SI 0 "arith_reg_operand" "")
1879 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1880 (match_operand:SI 2 "logical_operand" "")))]
1884 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1886 emit_insn (gen_zero_extendqisi2 (operands[0],
1887 gen_lowpart (QImode, operands[1])));
1892 (define_insn_and_split "anddi3"
1893 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1894 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1895 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1902 && ! logical_operand (operands[2], DImode)"
1906 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1907 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1909 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1912 [(set_attr "type" "arith_media")])
1914 (define_insn "andcdi3"
1915 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1916 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1917 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1920 [(set_attr "type" "arith_media")])
1922 (define_insn "iorsi3"
1923 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1924 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1925 (match_operand:SI 2 "logical_operand" "r,K08")))]
1928 [(set_attr "type" "arith")])
1930 (define_insn "iordi3"
1931 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1932 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1933 (match_operand:DI 2 "logical_operand" "r,I10")))]
1938 [(set_attr "type" "arith_media")])
1940 (define_insn "xorsi3"
1941 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1942 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1943 (match_operand:SI 2 "logical_operand" "K08,r")))]
1946 [(set_attr "type" "arith")])
1948 (define_insn "xordi3"
1949 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1950 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1951 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1956 [(set_attr "type" "arith_media")])
1958 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
1959 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
1961 [(set (match_operand:DI 0 "arith_reg_operand" "")
1962 (sign_extend:DI (match_operator 4 "binary_logical_operator"
1963 [(match_operand 1 "any_register_operand" "")
1964 (match_operand 2 "any_register_operand" "")])))]
1966 [(set (match_dup 5) (match_dup 4))
1967 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
1970 enum machine_mode inmode = GET_MODE (operands[1]);
1973 if (GET_CODE (operands[0]) == SUBREG)
1975 offset = SUBREG_BYTE (operands[0]);
1976 operands[0] = SUBREG_REG (operands[0]);
1978 if (GET_CODE (operands[0]) != REG)
1980 if (! TARGET_LITTLE_ENDIAN)
1981 offset += 8 - GET_MODE_SIZE (inmode);
1982 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
1985 ;; -------------------------------------------------------------------------
1986 ;; Shifts and rotates
1987 ;; -------------------------------------------------------------------------
1989 (define_expand "rotldi3"
1990 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1991 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
1992 (match_operand:HI 2 "mextr_bit_offset" "i")))]
1994 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
1996 (define_insn "rotldi3_mextr"
1997 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1998 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
1999 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2003 static char templ[16];
2005 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2006 8 - (int) (INTVAL (operands[2]) >> 3));
2009 [(set_attr "type" "arith_media")])
2011 (define_expand "rotrdi3"
2012 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2013 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2014 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2016 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2018 (define_insn "rotrdi3_mextr"
2019 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2020 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2021 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2025 static char templ[16];
2027 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2030 [(set_attr "type" "arith_media")])
2032 (define_insn "rotlsi3_1"
2033 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2034 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2037 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2040 [(set_attr "type" "arith")])
2042 (define_insn "rotlsi3_31"
2043 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2044 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2046 (clobber (reg:SI T_REG))]
2049 [(set_attr "type" "arith")])
2051 (define_insn "rotlsi3_16"
2052 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2053 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2057 [(set_attr "type" "arith")])
2059 (define_expand "rotlsi3"
2060 [(set (match_operand:SI 0 "arith_reg_operand" "")
2061 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2062 (match_operand:SI 2 "immediate_operand" "")))]
2066 static const char rot_tab[] = {
2067 000, 000, 000, 000, 000, 000, 010, 001,
2068 001, 001, 011, 013, 003, 003, 003, 003,
2069 003, 003, 003, 003, 003, 013, 012, 002,
2070 002, 002, 010, 000, 000, 000, 000, 000,
2075 if (GET_CODE (operands[2]) != CONST_INT)
2077 count = INTVAL (operands[2]);
2078 choice = rot_tab[count];
2079 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2085 emit_move_insn (operands[0], operands[1]);
2086 count -= (count & 16) * 2;
2089 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2096 parts[0] = gen_reg_rtx (SImode);
2097 parts[1] = gen_reg_rtx (SImode);
2098 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2099 emit_move_insn (parts[choice-1], operands[1]);
2100 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2101 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2102 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2103 count = (count & ~16) - 8;
2107 for (; count > 0; count--)
2108 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2109 for (; count < 0; count++)
2110 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2115 (define_insn "*rotlhi3_8"
2116 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2117 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2121 [(set_attr "type" "arith")])
2123 (define_expand "rotlhi3"
2124 [(set (match_operand:HI 0 "arith_reg_operand" "")
2125 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2126 (match_operand:HI 2 "immediate_operand" "")))]
2130 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2137 ;; This pattern is used by init_expmed for computing the costs of shift
2140 (define_insn_and_split "ashlsi3_std"
2141 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2142 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2143 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2144 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2146 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2147 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2155 && GET_CODE (operands[2]) == CONST_INT
2156 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2157 [(set (match_dup 3) (match_dup 2))
2159 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2160 (clobber (match_dup 4))])]
2161 "operands[4] = gen_rtx_SCRATCH (SImode);"
2162 [(set_attr "length" "*,*,*,4")
2163 (set_attr "type" "dyn_shift,arith,arith,arith")])
2165 (define_insn "ashlhi3_k"
2166 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2167 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2168 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2169 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2173 [(set_attr "type" "arith")])
2175 (define_insn "ashlsi3_n"
2176 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2177 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2178 (match_operand:SI 2 "const_int_operand" "n")))
2179 (clobber (reg:SI T_REG))]
2180 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2182 [(set (attr "length")
2183 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2185 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2187 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2189 (const_string "8")))
2190 (set_attr "type" "arith")])
2193 [(set (match_operand:SI 0 "arith_reg_operand" "")
2194 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2195 (match_operand:SI 2 "const_int_operand" "")))
2196 (clobber (reg:SI T_REG))]
2197 "TARGET_SH1 && reload_completed"
2198 [(use (reg:SI R0_REG))]
2201 gen_shifty_op (ASHIFT, operands);
2205 (define_insn "ashlsi3_media"
2206 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2207 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2208 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2213 [(set_attr "type" "arith_media")])
2215 (define_expand "ashlsi3"
2216 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2217 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2218 (match_operand:SI 2 "nonmemory_operand" "")))
2219 (clobber (reg:SI T_REG))])]
2225 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2228 if (GET_CODE (operands[2]) == CONST_INT
2229 && sh_dynamicalize_shift_p (operands[2]))
2230 operands[2] = force_reg (SImode, operands[2]);
2233 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2236 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2240 (define_insn "ashlhi3"
2241 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2242 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2243 (match_operand:HI 2 "const_int_operand" "n")))
2244 (clobber (reg:SI T_REG))]
2247 [(set (attr "length")
2248 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2250 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2252 (const_string "6")))
2253 (set_attr "type" "arith")])
2256 [(set (match_operand:HI 0 "arith_reg_operand" "")
2257 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2258 (match_operand:HI 2 "const_int_operand" "")))
2259 (clobber (reg:SI T_REG))]
2260 "TARGET_SH1 && reload_completed"
2261 [(use (reg:SI R0_REG))]
2264 gen_shifty_hi_op (ASHIFT, operands);
2269 ; arithmetic shift right
2272 (define_insn "ashrsi3_k"
2273 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2274 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2275 (match_operand:SI 2 "const_int_operand" "M")))
2276 (clobber (reg:SI T_REG))]
2277 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2279 [(set_attr "type" "arith")])
2281 ;; We can't do HImode right shifts correctly unless we start out with an
2282 ;; explicit zero / sign extension; doing that would result in worse overall
2283 ;; code, so just let the machine independent code widen the mode.
2284 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2287 ;; ??? This should be a define expand.
2289 (define_insn "ashrsi2_16"
2290 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2291 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2295 [(set_attr "length" "4")])
2298 [(set (match_operand:SI 0 "arith_reg_operand" "")
2299 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2302 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2303 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2304 "operands[2] = gen_lowpart (HImode, operands[0]);")
2306 ;; ??? This should be a define expand.
2308 (define_insn "ashrsi2_31"
2309 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2310 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2312 (clobber (reg:SI T_REG))]
2315 [(set_attr "length" "4")])
2318 [(set (match_operand:SI 0 "arith_reg_operand" "")
2319 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2321 (clobber (reg:SI T_REG))]
2326 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2327 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2331 (define_insn "ashlsi_c"
2332 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2333 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2335 (lt:SI (match_dup 1) (const_int 0)))]
2338 [(set_attr "type" "arith")])
2340 (define_insn "ashrsi3_d"
2341 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2342 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2343 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2346 [(set_attr "type" "dyn_shift")])
2348 (define_insn "ashrsi3_n"
2349 [(set (reg:SI R4_REG)
2350 (ashiftrt:SI (reg:SI R4_REG)
2351 (match_operand:SI 0 "const_int_operand" "i")))
2352 (clobber (reg:SI T_REG))
2353 (clobber (reg:SI PR_REG))
2354 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2357 [(set_attr "type" "sfunc")
2358 (set_attr "needs_delay_slot" "yes")])
2360 (define_insn "ashrsi3_media"
2361 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2362 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2363 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2368 [(set_attr "type" "arith_media")])
2370 (define_expand "ashrsi3"
2371 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2372 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2373 (match_operand:SI 2 "nonmemory_operand" "")))
2374 (clobber (reg:SI T_REG))])]
2380 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2383 if (expand_ashiftrt (operands))
2389 ;; logical shift right
2391 (define_insn "lshrsi3_d"
2392 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2393 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2394 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2397 [(set_attr "type" "dyn_shift")])
2399 ;; Only the single bit shift clobbers the T bit.
2401 (define_insn "lshrsi3_m"
2402 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2403 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2404 (match_operand:SI 2 "const_int_operand" "M")))
2405 (clobber (reg:SI T_REG))]
2406 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2408 [(set_attr "type" "arith")])
2410 (define_insn "lshrsi3_k"
2411 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2412 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2413 (match_operand:SI 2 "const_int_operand" "P27")))]
2414 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2415 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2417 [(set_attr "type" "arith")])
2419 (define_insn "lshrsi3_n"
2420 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2421 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2422 (match_operand:SI 2 "const_int_operand" "n")))
2423 (clobber (reg:SI T_REG))]
2424 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2426 [(set (attr "length")
2427 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2429 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2431 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2433 (const_string "8")))
2434 (set_attr "type" "arith")])
2437 [(set (match_operand:SI 0 "arith_reg_operand" "")
2438 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2439 (match_operand:SI 2 "const_int_operand" "")))
2440 (clobber (reg:SI T_REG))]
2441 "TARGET_SH1 && reload_completed"
2442 [(use (reg:SI R0_REG))]
2445 gen_shifty_op (LSHIFTRT, operands);
2449 (define_insn "lshrsi3_media"
2450 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2451 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2452 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2457 [(set_attr "type" "arith_media")])
2459 (define_expand "lshrsi3"
2460 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2461 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2462 (match_operand:SI 2 "nonmemory_operand" "")))
2463 (clobber (reg:SI T_REG))])]
2469 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2472 if (GET_CODE (operands[2]) == CONST_INT
2473 && sh_dynamicalize_shift_p (operands[2]))
2474 operands[2] = force_reg (SImode, operands[2]);
2475 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2477 rtx count = copy_to_mode_reg (SImode, operands[2]);
2478 emit_insn (gen_negsi2 (count, count));
2479 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2482 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2486 ;; ??? This should be a define expand.
2488 (define_insn "ashldi3_k"
2489 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2490 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2492 (clobber (reg:SI T_REG))]
2494 "shll %R0\;rotcl %S0"
2495 [(set_attr "length" "4")
2496 (set_attr "type" "arith")])
2498 (define_insn "ashldi3_media"
2499 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2500 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2501 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2506 [(set_attr "type" "arith_media")])
2508 (define_expand "ashldi3"
2509 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2510 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2511 (match_operand:DI 2 "immediate_operand" "")))
2512 (clobber (reg:SI T_REG))])]
2518 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2521 if (GET_CODE (operands[2]) != CONST_INT
2522 || INTVAL (operands[2]) != 1)
2526 ;; ??? This should be a define expand.
2528 (define_insn "lshrdi3_k"
2529 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2530 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2532 (clobber (reg:SI T_REG))]
2534 "shlr %S0\;rotcr %R0"
2535 [(set_attr "length" "4")
2536 (set_attr "type" "arith")])
2538 (define_insn "lshrdi3_media"
2539 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2540 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2541 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2546 [(set_attr "type" "arith_media")])
2548 (define_expand "lshrdi3"
2549 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2550 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2551 (match_operand:DI 2 "immediate_operand" "")))
2552 (clobber (reg:SI T_REG))])]
2558 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2561 if (GET_CODE (operands[2]) != CONST_INT
2562 || INTVAL (operands[2]) != 1)
2566 ;; ??? This should be a define expand.
2568 (define_insn "ashrdi3_k"
2569 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2570 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2572 (clobber (reg:SI T_REG))]
2574 "shar %S0\;rotcr %R0"
2575 [(set_attr "length" "4")
2576 (set_attr "type" "arith")])
2578 (define_insn "ashrdi3_media"
2579 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2580 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2581 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2586 [(set_attr "type" "arith_media")])
2588 (define_expand "ashrdi3"
2589 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2590 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2591 (match_operand:DI 2 "immediate_operand" "")))
2592 (clobber (reg:SI T_REG))])]
2598 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2601 if (GET_CODE (operands[2]) != CONST_INT
2602 || INTVAL (operands[2]) != 1)
2606 ;; combined left/right shift
2609 [(set (match_operand:SI 0 "register_operand" "")
2610 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2611 (match_operand:SI 2 "const_int_operand" ""))
2612 (match_operand:SI 3 "const_int_operand" "")))]
2613 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2614 [(use (reg:SI R0_REG))]
2615 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2619 [(set (match_operand:SI 0 "register_operand" "")
2620 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2621 (match_operand:SI 2 "const_int_operand" ""))
2622 (match_operand:SI 3 "const_int_operand" "")))
2623 (clobber (reg:SI T_REG))]
2624 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2625 [(use (reg:SI R0_REG))]
2626 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2630 [(set (match_operand:SI 0 "register_operand" "=r")
2631 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2632 (match_operand:SI 2 "const_int_operand" "n"))
2633 (match_operand:SI 3 "const_int_operand" "n")))
2634 (clobber (reg:SI T_REG))]
2635 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2637 [(set (attr "length")
2638 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2640 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2642 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2644 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2646 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2648 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2650 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2651 (const_string "16")]
2652 (const_string "18")))
2653 (set_attr "type" "arith")])
2656 [(set (match_operand:SI 0 "register_operand" "=z")
2657 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2658 (match_operand:SI 2 "const_int_operand" "n"))
2659 (match_operand:SI 3 "const_int_operand" "n")))
2660 (clobber (reg:SI T_REG))]
2661 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2663 [(set (attr "length")
2664 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2666 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2668 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2670 (const_string "10")))
2671 (set_attr "type" "arith")])
2673 ;; shift left / and combination with a scratch register: The combine pass
2674 ;; does not accept the individual instructions, even though they are
2675 ;; cheap. But it needs a precise description so that it is usable after
2677 (define_insn "and_shl_scratch"
2678 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2682 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2683 (match_operand:SI 2 "const_int_operand" "N,n"))
2684 (match_operand:SI 3 "" "0,r"))
2685 (match_operand:SI 4 "const_int_operand" "n,n"))
2686 (match_operand:SI 5 "const_int_operand" "n,n")))
2687 (clobber (reg:SI T_REG))]
2690 [(set (attr "length")
2691 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2693 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2695 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2697 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2698 (const_string "10")]
2699 (const_string "12")))
2700 (set_attr "type" "arith")])
2703 [(set (match_operand:SI 0 "register_operand" "")
2707 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2708 (match_operand:SI 2 "const_int_operand" ""))
2709 (match_operand:SI 3 "register_operand" ""))
2710 (match_operand:SI 4 "const_int_operand" ""))
2711 (match_operand:SI 5 "const_int_operand" "")))
2712 (clobber (reg:SI T_REG))]
2714 [(use (reg:SI R0_REG))]
2717 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2719 if (INTVAL (operands[2]))
2721 gen_shifty_op (LSHIFTRT, operands);
2723 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2724 operands[2] = operands[4];
2725 gen_shifty_op (ASHIFT, operands);
2726 if (INTVAL (operands[5]))
2728 operands[2] = operands[5];
2729 gen_shifty_op (LSHIFTRT, operands);
2734 ;; signed left/right shift combination.
2736 [(set (match_operand:SI 0 "register_operand" "")
2738 (ashift:SI (match_operand:SI 1 "register_operand" "")
2739 (match_operand:SI 2 "const_int_operand" ""))
2740 (match_operand:SI 3 "const_int_operand" "")
2742 (clobber (reg:SI T_REG))]
2744 [(use (reg:SI R0_REG))]
2745 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2748 (define_insn "shl_sext_ext"
2749 [(set (match_operand:SI 0 "register_operand" "=r")
2751 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2752 (match_operand:SI 2 "const_int_operand" "n"))
2753 (match_operand:SI 3 "const_int_operand" "n")
2755 (clobber (reg:SI T_REG))]
2756 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2758 [(set (attr "length")
2759 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2761 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2763 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2765 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2767 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2769 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2771 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2773 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2774 (const_string "16")]
2775 (const_string "18")))
2776 (set_attr "type" "arith")])
2778 (define_insn "shl_sext_sub"
2779 [(set (match_operand:SI 0 "register_operand" "=z")
2781 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2782 (match_operand:SI 2 "const_int_operand" "n"))
2783 (match_operand:SI 3 "const_int_operand" "n")
2785 (clobber (reg:SI T_REG))]
2786 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2788 [(set (attr "length")
2789 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2791 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2793 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2795 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2796 (const_string "12")]
2797 (const_string "14")))
2798 (set_attr "type" "arith")])
2800 ;; These patterns are found in expansions of DImode shifts by 16, and
2801 ;; allow the xtrct instruction to be generated from C source.
2803 (define_insn "xtrct_left"
2804 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2805 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2807 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2811 [(set_attr "type" "arith")])
2813 (define_insn "xtrct_right"
2814 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2815 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2817 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2821 [(set_attr "type" "arith")])
2823 ;; -------------------------------------------------------------------------
2825 ;; -------------------------------------------------------------------------
2828 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2829 (neg:SI (plus:SI (reg:SI T_REG)
2830 (match_operand:SI 1 "arith_reg_operand" "r"))))
2832 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2836 [(set_attr "type" "arith")])
2838 (define_insn "*negdi_media"
2839 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2840 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2843 [(set_attr "type" "arith_media")])
2845 (define_expand "negdi2"
2846 [(set (match_operand:DI 0 "arith_reg_operand" "")
2847 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2853 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2854 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2856 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2857 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2859 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2860 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2862 emit_insn (gen_clrt ());
2863 emit_insn (gen_negc (low_dst, low_src));
2864 emit_insn (gen_negc (high_dst, high_src));
2869 (define_insn "negsi2"
2870 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2871 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2874 [(set_attr "type" "arith")])
2876 (define_insn "one_cmplsi2"
2877 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2878 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2881 [(set_attr "type" "arith")])
2883 (define_expand "one_cmpldi2"
2884 [(set (match_operand:DI 0 "arith_reg_operand" "")
2885 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2887 "TARGET_SHMEDIA" "")
2889 ;; -------------------------------------------------------------------------
2890 ;; Zero extension instructions
2891 ;; -------------------------------------------------------------------------
2893 (define_insn "zero_extendsidi2"
2894 [(set (match_operand:DI 0 "register_operand" "=r")
2895 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2897 "addz.l %1, r63, %0"
2898 [(set_attr "type" "arith_media")])
2900 (define_insn "zero_extendhidi2"
2901 [(set (match_operand:DI 0 "register_operand" "=r,r")
2902 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2907 [(set_attr "type" "*,load_media")])
2910 [(set (match_operand:DI 0 "register_operand" "")
2911 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2912 "TARGET_SHMEDIA && reload_completed"
2913 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2914 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2917 if (GET_CODE (operands[1]) == TRUNCATE)
2918 operands[1] = XEXP (operands[1], 0);
2921 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2922 ;; reload the entire truncate expression.
2923 (define_insn_and_split "*loaddi_trunc"
2924 [(set (match_operand 0 "int_gpr_dest" "=r")
2925 (truncate (match_operand:DI 1 "memory_operand" "m")))]
2926 "TARGET_SHMEDIA && reload_completed"
2928 "TARGET_SHMEDIA && reload_completed"
2929 [(set (match_dup 0) (match_dup 1))]
2930 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
2932 (define_insn "zero_extendqidi2"
2933 [(set (match_operand:DI 0 "register_operand" "=r,r")
2934 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
2939 [(set_attr "type" "arith_media,load_media")])
2941 (define_expand "zero_extendhisi2"
2942 [(set (match_operand:SI 0 "arith_reg_operand" "")
2943 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
2947 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
2948 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2951 (define_insn "*zero_extendhisi2_compact"
2952 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2953 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2956 [(set_attr "type" "arith")])
2958 (define_insn "*zero_extendhisi2_media"
2959 [(set (match_operand:SI 0 "register_operand" "=r,r")
2960 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2965 [(set_attr "type" "arith_media,load_media")])
2968 [(set (match_operand:SI 0 "register_operand" "")
2969 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
2970 "TARGET_SHMEDIA && reload_completed"
2971 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
2972 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
2975 if (GET_CODE (operands[1]) == TRUNCATE)
2976 operands[1] = XEXP (operands[1], 0);
2979 (define_expand "zero_extendqisi2"
2980 [(set (match_operand:SI 0 "arith_reg_operand" "")
2981 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
2985 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
2986 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2989 (define_insn "*zero_extendqisi2_compact"
2990 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2991 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2994 [(set_attr "type" "arith")])
2996 (define_insn "*zero_extendqisi2_media"
2997 [(set (match_operand:SI 0 "register_operand" "=r,r")
2998 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3003 [(set_attr "type" "arith_media,load_media")])
3005 (define_insn "zero_extendqihi2"
3006 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3007 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3010 [(set_attr "type" "arith")])
3012 ;; -------------------------------------------------------------------------
3013 ;; Sign extension instructions
3014 ;; -------------------------------------------------------------------------
3016 ;; ??? This should be a define expand.
3017 ;; ??? Or perhaps it should be dropped?
3019 ;; convert_move generates good code for SH[1-4].
3020 (define_insn "extendsidi2"
3021 [(set (match_operand:DI 0 "register_operand" "=r,r")
3022 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3027 [(set_attr "type" "arith_media,load_media")])
3029 (define_insn "extendhidi2"
3030 [(set (match_operand:DI 0 "register_operand" "=r,r")
3031 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3036 [(set_attr "type" "*,load_media")])
3039 [(set (match_operand:DI 0 "register_operand" "")
3040 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3041 "TARGET_SHMEDIA && reload_completed"
3042 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3043 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3046 if (GET_CODE (operands[1]) == TRUNCATE)
3047 operands[1] = XEXP (operands[1], 0);
3050 (define_insn "extendqidi2"
3051 [(set (match_operand:DI 0 "register_operand" "=r,r")
3052 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3057 [(set_attr "type" "*,load_media")])
3060 [(set (match_operand:DI 0 "register_operand" "")
3061 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3062 "TARGET_SHMEDIA && reload_completed"
3063 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3064 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3067 if (GET_CODE (operands[1]) == TRUNCATE)
3068 operands[1] = XEXP (operands[1], 0);
3071 (define_expand "extendhisi2"
3072 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3073 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3077 (define_insn "*extendhisi2_compact"
3078 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3079 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3084 [(set_attr "type" "arith,load")])
3086 (define_insn "*extendhisi2_media"
3087 [(set (match_operand:SI 0 "register_operand" "=r,r")
3088 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3093 [(set_attr "type" "arith_media,load_media")])
3096 [(set (match_operand:SI 0 "register_operand" "")
3097 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3098 "TARGET_SHMEDIA && reload_completed"
3099 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3100 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3103 if (GET_CODE (operands[1]) == TRUNCATE)
3104 operands[1] = XEXP (operands[1], 0);
3107 (define_expand "extendqisi2"
3108 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3109 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3113 (define_insn "*extendqisi2_compact"
3114 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3115 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3120 [(set_attr "type" "arith,load")])
3122 (define_insn "*extendqisi2_media"
3123 [(set (match_operand:SI 0 "register_operand" "=r,r")
3124 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3129 [(set_attr "type" "arith_media,load_media")])
3132 [(set (match_operand:SI 0 "register_operand" "")
3133 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3134 "TARGET_SHMEDIA && reload_completed"
3135 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3136 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3139 if (GET_CODE (operands[1]) == TRUNCATE)
3140 operands[1] = XEXP (operands[1], 0);
3143 (define_insn "extendqihi2"
3144 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3145 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3150 [(set_attr "type" "arith,load")])
3152 /* It would seem useful to combine the truncXi patterns into the movXi
3153 patterns, but unary operators are ignored when matching constraints,
3154 so we need separate patterns. */
3155 (define_insn "truncdisi2"
3156 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3157 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3166 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3169 (define_insn "truncdihi2"
3170 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3171 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3174 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3176 [(set_attr "type" "arith_media,store_media")
3177 (set_attr "length" "8,4")])
3179 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3180 ; Because we use zero extension, we can't provide signed QImode compares
3181 ; using a simple compare or conditional banch insn.
3182 (define_insn "truncdiqi2"
3183 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3184 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3189 [(set_attr "type" "arith_media,store")])
3191 ;; -------------------------------------------------------------------------
3192 ;; Move instructions
3193 ;; -------------------------------------------------------------------------
3195 ;; define push and pop so it is easy for sh.c
3196 ;; We can't use push and pop on SHcompact because the stack must always
3197 ;; be 8-byte aligned.
3199 (define_expand "push"
3200 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3201 (match_operand:SI 0 "register_operand" "r,l,x"))]
3202 "TARGET_SH1 && ! TARGET_SH5"
3205 (define_expand "pop"
3206 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3207 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3208 "TARGET_SH1 && ! TARGET_SH5"
3211 (define_expand "push_e"
3212 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3213 (match_operand:SF 0 "" ""))
3214 (use (reg:PSI FPSCR_REG))
3215 (clobber (scratch:SI))])]
3216 "TARGET_SH1 && ! TARGET_SH5"
3219 (define_insn "push_fpul"
3220 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3221 "TARGET_SH2E && ! TARGET_SH5"
3223 [(set_attr "type" "store")
3224 (set_attr "late_fp_use" "yes")
3225 (set_attr "hit_stack" "yes")])
3227 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3229 (define_expand "push_4"
3230 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3231 (match_operand:DF 0 "" ""))
3232 (use (reg:PSI FPSCR_REG))
3233 (clobber (scratch:SI))])]
3234 "TARGET_SH1 && ! TARGET_SH5"
3237 (define_expand "pop_e"
3238 [(parallel [(set (match_operand:SF 0 "" "")
3239 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3240 (use (reg:PSI FPSCR_REG))
3241 (clobber (scratch:SI))])]
3242 "TARGET_SH1 && ! TARGET_SH5"
3245 (define_insn "pop_fpul"
3246 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3247 "TARGET_SH2E && ! TARGET_SH5"
3249 [(set_attr "type" "load")
3250 (set_attr "hit_stack" "yes")])
3252 (define_expand "pop_4"
3253 [(parallel [(set (match_operand:DF 0 "" "")
3254 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3255 (use (reg:PSI FPSCR_REG))
3256 (clobber (scratch:SI))])]
3257 "TARGET_SH1 && ! TARGET_SH5"
3260 (define_expand "push_fpscr"
3265 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3266 gen_rtx_PRE_DEC (Pmode,
3267 stack_pointer_rtx)),
3269 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3273 (define_expand "pop_fpscr"
3278 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3279 gen_rtx_MEM (PSImode,
3280 gen_rtx_POST_INC (Pmode,
3281 stack_pointer_rtx))));
3282 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3286 ;; These two patterns can happen as the result of optimization, when
3287 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3288 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3291 [(set (reg:SI T_REG) (const_int 0))]
3296 [(set (reg:SI T_REG) (const_int 1))]
3300 ;; t/r must come after r/r, lest reload will try to reload stuff like
3301 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3302 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3303 (define_insn "movsi_i"
3304 [(set (match_operand:SI 0 "general_movdst_operand"
3305 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3306 (match_operand:SI 1 "general_movsrc_operand"
3307 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3310 && (register_operand (operands[0], SImode)
3311 || register_operand (operands[1], SImode))"
3328 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3329 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3331 ;; t/r must come after r/r, lest reload will try to reload stuff like
3332 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3333 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3334 ;; will require a reload.
3335 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3336 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3337 (define_insn "movsi_ie"
3338 [(set (match_operand:SI 0 "general_movdst_operand"
3339 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3340 (match_operand:SI 1 "general_movsrc_operand"
3341 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3343 && (register_operand (operands[0], SImode)
3344 || register_operand (operands[1], SImode))"
3368 ! move optimized away"
3369 [(set_attr "type" "pcload_si,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")
3370 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3371 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3373 (define_insn "movsi_i_lowpart"
3374 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3375 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3377 && (register_operand (operands[0], SImode)
3378 || register_operand (operands[1], SImode))"
3388 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3390 (define_insn_and_split "load_ra"
3391 [(set (match_operand:SI 0 "general_movdst_operand" "")
3392 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3395 "&& ! rtx_equal_function_value_matters"
3396 [(set (match_dup 0) (match_dup 1))]
3399 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3400 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3403 (define_insn "*movsi_media"
3404 [(set (match_operand:SI 0 "general_movdst_operand"
3405 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3406 (match_operand:SI 1 "general_movsrc_operand"
3407 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3409 && (register_operand (operands[0], SImode)
3410 || sh_register_operand (operands[1], SImode))"
3425 [(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")
3426 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3428 (define_insn "*movsi_media_nofpu"
3429 [(set (match_operand:SI 0 "general_movdst_operand"
3430 "=r,r,r,r,m,*b,r,b")
3431 (match_operand:SI 1 "general_movsrc_operand"
3432 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3434 && (register_operand (operands[0], SImode)
3435 || sh_register_operand (operands[1], SImode))"
3445 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3446 (set_attr "length" "4,4,8,4,4,4,4,12")])
3449 [(set (match_operand:SI 0 "arith_reg_operand" "")
3450 (match_operand:SI 1 "immediate_operand" ""))]
3451 "TARGET_SHMEDIA && reload_completed
3452 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3453 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3456 operands[2] = shallow_copy_rtx (operands[1]);
3457 PUT_MODE (operands[2], DImode);
3461 [(set (match_operand:SI 0 "register_operand" "")
3462 (match_operand:SI 1 "immediate_operand" ""))]
3463 "TARGET_SHMEDIA && reload_completed
3464 && ((GET_CODE (operands[1]) == CONST_INT
3465 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3466 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3467 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3469 (define_expand "movsi"
3470 [(set (match_operand:SI 0 "general_movdst_operand" "")
3471 (match_operand:SI 1 "general_movsrc_operand" ""))]
3473 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3475 (define_expand "ic_invalidate_line"
3476 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3477 (match_dup 1)] UNSPEC_ICACHE)
3478 (clobber (scratch:SI))])]
3479 "TARGET_HARD_SH4 || TARGET_SH5"
3484 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3487 else if (TARGET_SHCOMPACT)
3489 operands[1] = function_symbol (\"__ic_invalidate\");
3490 operands[1] = force_reg (Pmode, operands[1]);
3491 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3494 else if (TARGET_SH4A_ARCH)
3496 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3499 operands[0] = force_reg (Pmode, operands[0]);
3500 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3504 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3505 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3506 ;; the requirement *1*00 for associative address writes. The alignment of
3507 ;; %0 implies that its least significant bit is cleared,
3508 ;; thus we clear the V bit of a matching entry if there is one.
3509 (define_insn "ic_invalidate_line_i"
3510 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3511 (match_operand:SI 1 "register_operand" "r")]
3513 (clobber (match_scratch:SI 2 "=&r"))]
3515 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3516 [(set_attr "length" "8")
3517 (set_attr "type" "cwb")])
3519 (define_insn "ic_invalidate_line_sh4a"
3520 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3523 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3524 [(set_attr "length" "16")
3525 (set_attr "type" "cwb")])
3527 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3528 ;; an add in the code that calculates the address.
3529 (define_insn "ic_invalidate_line_media"
3530 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3533 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3534 [(set_attr "length" "16")
3535 (set_attr "type" "invalidate_line_media")])
3537 (define_insn "ic_invalidate_line_compact"
3538 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3539 (match_operand:SI 1 "register_operand" "r")]
3541 (clobber (reg:SI PR_REG))]
3544 [(set_attr "type" "sfunc")
3545 (set_attr "needs_delay_slot" "yes")])
3547 (define_expand "initialize_trampoline"
3548 [(match_operand:SI 0 "" "")
3549 (match_operand:SI 1 "" "")
3550 (match_operand:SI 2 "" "")]
3556 tramp = force_reg (Pmode, operands[0]);
3557 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3558 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3559 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3561 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3565 (define_insn "initialize_trampoline_compact"
3566 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3567 (match_operand:SI 1 "register_operand" "r")
3568 (reg:SI R2_REG) (reg:SI R3_REG)]
3571 (clobber (reg:SI PR_REG))]
3574 [(set_attr "type" "sfunc")
3575 (set_attr "needs_delay_slot" "yes")])
3577 (define_insn "movqi_i"
3578 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3579 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3581 && (arith_reg_operand (operands[0], QImode)
3582 || arith_reg_operand (operands[1], QImode))"
3590 [(set_attr "type" "move,load,store,move,move,move")])
3592 (define_insn "*movqi_media"
3593 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3594 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3596 && (arith_reg_operand (operands[0], QImode)
3597 || arith_reg_or_0_operand (operands[1], QImode))"
3603 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3605 (define_expand "movqi"
3606 [(set (match_operand:QI 0 "general_operand" "")
3607 (match_operand:QI 1 "general_operand" ""))]
3609 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3611 (define_expand "reload_inqi"
3612 [(set (match_operand:SI 2 "" "=&r")
3613 (match_operand:QI 1 "inqhi_operand" ""))
3614 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3615 (truncate:QI (match_dup 3)))]
3619 rtx inner = XEXP (operands[1], 0);
3620 int regno = REGNO (inner);
3622 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3623 operands[1] = gen_rtx_REG (SImode, regno);
3624 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3627 /* When storing r0, we have to avoid reg+reg addressing. */
3628 (define_insn "movhi_i"
3629 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3630 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3632 && (arith_reg_operand (operands[0], HImode)
3633 || arith_reg_operand (operands[1], HImode))
3634 && (GET_CODE (operands[0]) != MEM
3635 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3636 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3637 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3647 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3649 (define_insn "*movhi_media"
3650 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3651 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3653 && (arith_reg_operand (operands[0], HImode)
3654 || arith_reg_or_0_operand (operands[1], HImode))"
3661 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3664 [(set (match_operand:HI 0 "register_operand" "")
3665 (match_operand:HI 1 "immediate_operand" ""))]
3666 "TARGET_SHMEDIA && reload_completed
3667 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3668 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3670 (define_expand "movhi"
3671 [(set (match_operand:HI 0 "general_movdst_operand" "")
3672 (match_operand:HI 1 "general_movsrc_operand" ""))]
3674 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3676 (define_expand "reload_inhi"
3677 [(set (match_operand:SI 2 "" "=&r")
3678 (match_operand:HI 1 "inqhi_operand" ""))
3679 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3680 (truncate:HI (match_dup 3)))]
3684 rtx inner = XEXP (operands[1], 0);
3685 int regno = REGNO (inner);
3687 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3688 operands[1] = gen_rtx_REG (SImode, regno);
3689 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3692 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3693 ;; compiled with -m2 -ml -O3 -funroll-loops
3694 (define_insn "*movdi_i"
3695 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3696 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3698 && (arith_reg_operand (operands[0], DImode)
3699 || arith_reg_operand (operands[1], DImode))"
3700 "* return output_movedouble (insn, operands, DImode);"
3701 [(set_attr "length" "4")
3702 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3704 ;; If the output is a register and the input is memory or a register, we have
3705 ;; to be careful and see which word needs to be loaded first.
3708 [(set (match_operand:DI 0 "general_movdst_operand" "")
3709 (match_operand:DI 1 "general_movsrc_operand" ""))]
3710 "TARGET_SH1 && reload_completed"
3711 [(set (match_dup 2) (match_dup 3))
3712 (set (match_dup 4) (match_dup 5))]
3717 if ((GET_CODE (operands[0]) == MEM
3718 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3719 || (GET_CODE (operands[1]) == MEM
3720 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3723 if (GET_CODE (operands[0]) == REG)
3724 regno = REGNO (operands[0]);
3725 else if (GET_CODE (operands[0]) == SUBREG)
3726 regno = subreg_regno (operands[0]);
3727 else if (GET_CODE (operands[0]) == MEM)
3733 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3735 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3736 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3737 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3738 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3742 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3743 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3744 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3745 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3748 if (operands[2] == 0 || operands[3] == 0
3749 || operands[4] == 0 || operands[5] == 0)
3753 (define_insn "*movdi_media"
3754 [(set (match_operand:DI 0 "general_movdst_operand"
3755 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3756 (match_operand:DI 1 "general_movsrc_operand"
3757 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3759 && (register_operand (operands[0], DImode)
3760 || sh_register_operand (operands[1], DImode))"
3775 [(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")
3776 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3778 (define_insn "*movdi_media_nofpu"
3779 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3780 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3782 && (register_operand (operands[0], DImode)
3783 || sh_register_operand (operands[1], DImode))"
3793 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3794 (set_attr "length" "4,4,16,4,4,4,4,*")])
3797 [(set (match_operand:DI 0 "arith_reg_operand" "")
3798 (match_operand:DI 1 "immediate_operand" ""))]
3799 "TARGET_SHMEDIA && reload_completed
3800 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3801 [(set (match_dup 0) (match_dup 1))]
3806 if (TARGET_SHMEDIA64)
3807 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3809 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3811 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3817 (define_expand "movdi_const"
3818 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3819 (const:DI (sign_extend:DI
3822 (match_operand:DI 1 "immediate_operand" "s")
3825 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3833 (const_int 32)))))))))
3835 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3843 (const_int 16)))))))))
3845 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3851 (match_dup 1))))))))]
3852 "TARGET_SHMEDIA64 && reload_completed
3853 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3856 sh_mark_label (operands[1], 4);
3859 (define_expand "movdi_const_32bit"
3860 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3861 (const:DI (sign_extend:DI
3864 (match_operand:DI 1 "immediate_operand" "s")
3867 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3873 (match_dup 1))))))))]
3874 "TARGET_SHMEDIA32 && reload_completed
3875 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3878 sh_mark_label (operands[1], 2);
3881 (define_expand "movdi_const_16bit"
3882 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3883 (const:DI (sign_extend:DI
3885 (match_operand:DI 1 "immediate_operand" "s")))))]
3886 "TARGET_SHMEDIA && flag_pic && reload_completed
3887 && GET_CODE (operands[1]) == SYMBOL_REF"
3891 [(set (match_operand:DI 0 "arith_reg_operand" "")
3892 (match_operand:DI 1 "immediate_operand" ""))]
3893 "TARGET_SHMEDIA && reload_completed
3894 && GET_CODE (operands[1]) == CONST_INT
3895 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3896 [(set (match_dup 0) (match_dup 2))
3900 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3901 unsigned HOST_WIDE_INT low = val;
3902 unsigned HOST_WIDE_INT high = val;
3903 unsigned HOST_WIDE_INT sign;
3904 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3906 /* Sign-extend the 16 least-significant bits. */
3911 /* Arithmetic shift right the word by 16 bits. */
3914 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3919 /* If we can't generate the constant with a two-insn movi / shori
3920 sequence, try some other strategies. */
3921 if (! CONST_OK_FOR_I16 (high))
3923 /* Try constant load / left shift. We know VAL != 0. */
3924 val2 = val ^ (val-1);
3927 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3929 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
3930 || (! CONST_OK_FOR_I16 (high >> 16)
3931 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
3933 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3934 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3935 GEN_INT (trailing_zeroes));
3939 /* Try constant load / right shift. */
3940 val2 = (val >> 15) + 1;
3941 if (val2 == (val2 & -val2))
3943 int shift = 49 - exact_log2 (val2);
3945 val2 = trunc_int_for_mode (val << shift, DImode);
3946 if (CONST_OK_FOR_I16 (val2))
3948 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3954 val2 = val & 0xffff;
3955 if ((val >> 16 & 0xffff) == val2
3956 && (val >> 32 & 0xffff) == val2
3957 && (val >> 48 & 0xffff) == val2)
3959 val2 = (HOST_WIDE_INT) val >> 48;
3960 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3961 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3964 /* Try movi / mshflo.l */
3965 val2 = (HOST_WIDE_INT) val >> 32;
3966 if (val2 == ((unsigned HOST_WIDE_INT)
3967 trunc_int_for_mode (val, SImode)))
3969 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3973 /* Try movi / mshflo.l w/ r63. */
3974 val2 = val + ((HOST_WIDE_INT) -1 << 32);
3975 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
3977 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3983 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
3986 operands[2] = GEN_INT (val2);
3990 [(set (match_operand:DI 0 "arith_reg_operand" "")
3991 (match_operand:DI 1 "immediate_operand" ""))]
3992 "TARGET_SHMEDIA && reload_completed
3993 && GET_CODE (operands[1]) == CONST_DOUBLE"
3994 [(set (match_dup 0) (match_dup 2))
3996 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3997 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4000 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4001 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4002 unsigned HOST_WIDE_INT val = low;
4003 unsigned HOST_WIDE_INT sign;
4005 /* Sign-extend the 16 least-significant bits. */
4009 operands[1] = GEN_INT (val);
4011 /* Arithmetic shift right the double-word by 16 bits. */
4013 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4016 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4020 /* This will only be true if high is a sign-extension of low, i.e.,
4021 it must be either 0 or (unsigned)-1, and be zero iff the
4022 most-significant bit of low is set. */
4023 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4024 operands[2] = GEN_INT (low);
4026 operands[2] = immed_double_const (low, high, DImode);
4029 (define_insn "shori_media"
4030 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4031 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4035 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4040 [(set_attr "type" "arith_media,*")])
4042 (define_expand "movdi"
4043 [(set (match_operand:DI 0 "general_movdst_operand" "")
4044 (match_operand:DI 1 "general_movsrc_operand" ""))]
4046 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4048 (define_insn "movdf_media"
4049 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4050 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4052 && (register_operand (operands[0], DFmode)
4053 || sh_register_operand (operands[1], DFmode))"
4064 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4066 (define_insn "movdf_media_nofpu"
4067 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4068 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4070 && (register_operand (operands[0], DFmode)
4071 || sh_register_operand (operands[1], DFmode))"
4077 [(set_attr "type" "arith_media,*,load_media,store_media")])
4080 [(set (match_operand:DF 0 "arith_reg_operand" "")
4081 (match_operand:DF 1 "immediate_operand" ""))]
4082 "TARGET_SHMEDIA && reload_completed"
4083 [(set (match_dup 3) (match_dup 2))]
4086 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4088 REAL_VALUE_TYPE value;
4090 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4091 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4093 if (HOST_BITS_PER_WIDE_INT >= 64)
4094 operands[2] = immed_double_const ((unsigned long) values[endian]
4095 | ((HOST_WIDE_INT) values[1 - endian]
4097 else if (HOST_BITS_PER_WIDE_INT == 32)
4098 operands[2] = immed_double_const (values[endian], values[1 - endian],
4103 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4106 ;; ??? This should be a define expand.
4108 (define_insn "movdf_k"
4109 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4110 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4112 && (! TARGET_SH4 || reload_completed
4113 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4114 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4115 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4116 && (arith_reg_operand (operands[0], DFmode)
4117 || arith_reg_operand (operands[1], DFmode))"
4118 "* return output_movedouble (insn, operands, DFmode);"
4119 [(set_attr "length" "4")
4120 (set_attr "type" "move,pcload,load,store")])
4122 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4123 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4124 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4125 ;; the d/m/c/X alternative, which is split later into single-precision
4126 ;; instructions. And when not optimizing, no splits are done before fixing
4127 ;; up pcloads, so we need usable length information for that.
4128 (define_insn "movdf_i4"
4129 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4130 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4131 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4132 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4134 && (arith_reg_operand (operands[0], DFmode)
4135 || arith_reg_operand (operands[1], DFmode))"
4147 [(set_attr_alternative "length"
4148 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4150 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4151 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4152 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4154 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4155 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4156 ;; increment or decrement r15 explicitly.
4158 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4159 (const_int 10) (const_int 8))
4161 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4162 (const_int 10) (const_int 8))])
4163 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4164 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4165 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4166 (const_string "double")
4167 (const_string "none")))])
4169 ;; Moving DFmode between fp/general registers through memory
4170 ;; (the top of the stack) is faster than moving through fpul even for
4171 ;; little endian. Because the type of an instruction is important for its
4172 ;; scheduling, it is beneficial to split these operations, rather than
4173 ;; emitting them in one single chunk, even if this will expose a stack
4174 ;; use that will prevent scheduling of other stack accesses beyond this
4177 [(set (match_operand:DF 0 "register_operand" "")
4178 (match_operand:DF 1 "register_operand" ""))
4179 (use (match_operand:PSI 2 "fpscr_operand" ""))
4180 (clobber (match_scratch:SI 3 "=X"))]
4181 "TARGET_SH4 && reload_completed
4182 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4188 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4190 emit_move_insn (stack_pointer_rtx,
4191 plus_constant (stack_pointer_rtx, -8));
4192 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4195 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4196 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4197 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4198 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4199 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4200 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4202 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4203 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4204 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4205 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4207 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4211 ;; local-alloc sometimes allocates scratch registers even when not required,
4212 ;; so we must be prepared to handle these.
4214 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4216 [(set (match_operand:DF 0 "general_movdst_operand" "")
4217 (match_operand:DF 1 "general_movsrc_operand" ""))
4218 (use (match_operand:PSI 2 "fpscr_operand" ""))
4219 (clobber (match_scratch:SI 3 ""))]
4222 && true_regnum (operands[0]) < 16
4223 && true_regnum (operands[1]) < 16"
4224 [(set (match_dup 0) (match_dup 1))]
4227 /* If this was a reg <-> mem operation with base + index reg addressing,
4228 we have to handle this in a special way. */
4229 rtx mem = operands[0];
4231 if (! memory_operand (mem, DFmode))
4236 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4237 mem = SUBREG_REG (mem);
4238 if (GET_CODE (mem) == MEM)
4240 rtx addr = XEXP (mem, 0);
4241 if (GET_CODE (addr) == PLUS
4242 && GET_CODE (XEXP (addr, 0)) == REG
4243 && GET_CODE (XEXP (addr, 1)) == REG)
4246 rtx reg0 = gen_rtx_REG (Pmode, 0);
4247 rtx regop = operands[store_p], word0 ,word1;
4249 if (GET_CODE (regop) == SUBREG)
4250 alter_subreg (®op);
4251 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4255 mem = copy_rtx (mem);
4256 PUT_MODE (mem, SImode);
4257 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4258 alter_subreg (&word0);
4259 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4260 alter_subreg (&word1);
4261 if (store_p || ! refers_to_regno_p (REGNO (word0),
4262 REGNO (word0) + 1, addr, 0))
4265 ? gen_movsi_ie (mem, word0)
4266 : gen_movsi_ie (word0, mem));
4267 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4268 mem = copy_rtx (mem);
4270 ? gen_movsi_ie (mem, word1)
4271 : gen_movsi_ie (word1, mem));
4272 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4276 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4277 emit_insn (gen_movsi_ie (word1, mem));
4278 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4279 mem = copy_rtx (mem);
4280 emit_insn (gen_movsi_ie (word0, mem));
4287 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4289 [(set (match_operand:DF 0 "register_operand" "")
4290 (match_operand:DF 1 "memory_operand" ""))
4291 (use (match_operand:PSI 2 "fpscr_operand" ""))
4292 (clobber (reg:SI R0_REG))]
4293 "TARGET_SH4 && reload_completed"
4294 [(parallel [(set (match_dup 0) (match_dup 1))
4296 (clobber (scratch:SI))])]
4299 (define_expand "reload_indf"
4300 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4301 (match_operand:DF 1 "immediate_operand" "FQ"))
4302 (use (reg:PSI FPSCR_REG))
4303 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4307 (define_expand "reload_outdf"
4308 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4309 (match_operand:DF 1 "register_operand" "af,r"))
4310 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4314 ;; Simplify no-op moves.
4316 [(set (match_operand:SF 0 "register_operand" "")
4317 (match_operand:SF 1 "register_operand" ""))
4318 (use (match_operand:PSI 2 "fpscr_operand" ""))
4319 (clobber (match_scratch:SI 3 ""))]
4320 "TARGET_SH2E && reload_completed
4321 && true_regnum (operands[0]) == true_regnum (operands[1])"
4322 [(set (match_dup 0) (match_dup 0))]
4325 ;; fmovd substitute post-reload splits
4327 [(set (match_operand:DF 0 "register_operand" "")
4328 (match_operand:DF 1 "register_operand" ""))
4329 (use (match_operand:PSI 2 "fpscr_operand" ""))
4330 (clobber (match_scratch:SI 3 ""))]
4331 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4332 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4333 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4337 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4338 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4339 gen_rtx_REG (SFmode, src), operands[2]));
4340 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4341 gen_rtx_REG (SFmode, src + 1), operands[2]));
4346 [(set (match_operand:DF 0 "register_operand" "")
4347 (mem:DF (match_operand:SI 1 "register_operand" "")))
4348 (use (match_operand:PSI 2 "fpscr_operand" ""))
4349 (clobber (match_scratch:SI 3 ""))]
4350 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4351 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4352 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4356 int regno = true_regnum (operands[0]);
4358 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4360 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4361 regno + !! TARGET_LITTLE_ENDIAN),
4362 mem2, operands[2]));
4363 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4364 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4365 regno + ! TARGET_LITTLE_ENDIAN),
4366 gen_rtx_MEM (SFmode, operands[1]),
4372 [(set (match_operand:DF 0 "register_operand" "")
4373 (match_operand:DF 1 "memory_operand" ""))
4374 (use (match_operand:PSI 2 "fpscr_operand" ""))
4375 (clobber (match_scratch:SI 3 ""))]
4376 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4377 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4381 int regno = true_regnum (operands[0]);
4382 rtx addr, insn, adjust = NULL_RTX;
4383 rtx mem2 = copy_rtx (operands[1]);
4384 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4385 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4387 PUT_MODE (mem2, SFmode);
4388 operands[1] = copy_rtx (mem2);
4389 addr = XEXP (mem2, 0);
4390 if (GET_CODE (addr) != POST_INC)
4392 /* If we have to modify the stack pointer, the value that we have
4393 read with post-increment might be modified by an interrupt,
4394 so write it back. */
4395 if (REGNO (addr) == STACK_POINTER_REGNUM)
4396 adjust = gen_push_e (reg0);
4398 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4399 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4401 addr = XEXP (addr, 0);
4402 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4403 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4404 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4408 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4413 [(set (match_operand:DF 0 "memory_operand" "")
4414 (match_operand:DF 1 "register_operand" ""))
4415 (use (match_operand:PSI 2 "fpscr_operand" ""))
4416 (clobber (match_scratch:SI 3 ""))]
4417 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4418 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4422 int regno = true_regnum (operands[1]);
4423 rtx insn, addr, adjust = NULL_RTX;
4425 operands[0] = copy_rtx (operands[0]);
4426 PUT_MODE (operands[0], SFmode);
4427 insn = emit_insn (gen_movsf_ie (operands[0],
4428 gen_rtx_REG (SFmode,
4429 regno + ! TARGET_LITTLE_ENDIAN),
4431 operands[0] = copy_rtx (operands[0]);
4432 addr = XEXP (operands[0], 0);
4433 if (GET_CODE (addr) != PRE_DEC)
4435 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4436 emit_insn_before (adjust, insn);
4437 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4439 addr = XEXP (addr, 0);
4441 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4442 insn = emit_insn (gen_movsf_ie (operands[0],
4443 gen_rtx_REG (SFmode,
4444 regno + !! TARGET_LITTLE_ENDIAN),
4446 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4450 ;; If the output is a register and the input is memory or a register, we have
4451 ;; to be careful and see which word needs to be loaded first.
4454 [(set (match_operand:DF 0 "general_movdst_operand" "")
4455 (match_operand:DF 1 "general_movsrc_operand" ""))]
4456 "TARGET_SH1 && reload_completed"
4457 [(set (match_dup 2) (match_dup 3))
4458 (set (match_dup 4) (match_dup 5))]
4463 if ((GET_CODE (operands[0]) == MEM
4464 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4465 || (GET_CODE (operands[1]) == MEM
4466 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4469 if (GET_CODE (operands[0]) == REG)
4470 regno = REGNO (operands[0]);
4471 else if (GET_CODE (operands[0]) == SUBREG)
4472 regno = subreg_regno (operands[0]);
4473 else if (GET_CODE (operands[0]) == MEM)
4479 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4481 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4482 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4483 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4484 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4488 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4489 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4490 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4491 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4494 if (operands[2] == 0 || operands[3] == 0
4495 || operands[4] == 0 || operands[5] == 0)
4499 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4500 ;; used only once, let combine add in the index again.
4503 [(set (match_operand:SI 0 "register_operand" "")
4504 (match_operand:SI 1 "" ""))
4505 (clobber (match_operand 2 "register_operand" ""))]
4506 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4507 [(use (reg:SI R0_REG))]
4510 rtx addr, reg, const_int;
4512 if (GET_CODE (operands[1]) != MEM)
4514 addr = XEXP (operands[1], 0);
4515 if (GET_CODE (addr) != PLUS)
4517 reg = XEXP (addr, 0);
4518 const_int = XEXP (addr, 1);
4519 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4520 && GET_CODE (const_int) == CONST_INT))
4522 emit_move_insn (operands[2], const_int);
4523 emit_move_insn (operands[0],
4524 change_address (operands[1], VOIDmode,
4525 gen_rtx_PLUS (SImode, reg, operands[2])));
4530 [(set (match_operand:SI 1 "" "")
4531 (match_operand:SI 0 "register_operand" ""))
4532 (clobber (match_operand 2 "register_operand" ""))]
4533 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4534 [(use (reg:SI R0_REG))]
4537 rtx addr, reg, const_int;
4539 if (GET_CODE (operands[1]) != MEM)
4541 addr = XEXP (operands[1], 0);
4542 if (GET_CODE (addr) != PLUS)
4544 reg = XEXP (addr, 0);
4545 const_int = XEXP (addr, 1);
4546 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4547 && GET_CODE (const_int) == CONST_INT))
4549 emit_move_insn (operands[2], const_int);
4550 emit_move_insn (change_address (operands[1], VOIDmode,
4551 gen_rtx_PLUS (SImode, reg, operands[2])),
4556 (define_expand "movdf"
4557 [(set (match_operand:DF 0 "general_movdst_operand" "")
4558 (match_operand:DF 1 "general_movsrc_operand" ""))]
4562 if (prepare_move_operands (operands, DFmode)) DONE;
4565 if (TARGET_SHMEDIA_FPU)
4566 emit_insn (gen_movdf_media (operands[0], operands[1]));
4568 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4573 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4578 ;;This is incompatible with the way gcc uses subregs.
4579 ;;(define_insn "movv2sf_i"
4580 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4581 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4582 ;; "TARGET_SHMEDIA_FPU
4583 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4584 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4588 ;; fst%M0.p %m0, %1"
4589 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4591 (define_insn_and_split "movv2sf_i"
4592 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4593 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4594 "TARGET_SHMEDIA_FPU"
4596 "TARGET_SHMEDIA_FPU && reload_completed"
4597 [(set (match_dup 0) (match_dup 1))]
4600 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4601 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4604 (define_expand "movv2sf"
4605 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4606 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4607 "TARGET_SHMEDIA_FPU"
4610 if (prepare_move_operands (operands, V2SFmode))
4614 (define_expand "addv2sf3"
4615 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4616 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4617 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4618 "TARGET_SHMEDIA_FPU"
4621 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4625 (define_expand "subv2sf3"
4626 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4627 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4628 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4629 "TARGET_SHMEDIA_FPU"
4632 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4636 (define_expand "mulv2sf3"
4637 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4638 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4639 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4640 "TARGET_SHMEDIA_FPU"
4643 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4647 (define_expand "divv2sf3"
4648 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4649 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4650 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4651 "TARGET_SHMEDIA_FPU"
4654 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4658 (define_insn_and_split "*movv4sf_i"
4659 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4660 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4661 "TARGET_SHMEDIA_FPU"
4663 "&& reload_completed"
4669 for (i = 0; i < 4/2; i++)
4673 if (GET_CODE (operands[0]) == MEM)
4674 x = gen_rtx_MEM (V2SFmode,
4675 plus_constant (XEXP (operands[0], 0),
4676 i * GET_MODE_SIZE (V2SFmode)));
4678 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4680 if (GET_CODE (operands[1]) == MEM)
4681 y = gen_rtx_MEM (V2SFmode,
4682 plus_constant (XEXP (operands[1], 0),
4683 i * GET_MODE_SIZE (V2SFmode)));
4685 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4687 emit_insn (gen_movv2sf_i (x, y));
4692 [(set_attr "length" "8")])
4694 (define_expand "movv4sf"
4695 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4696 (match_operand:V4SF 1 "general_operand" ""))]
4697 "TARGET_SHMEDIA_FPU"
4700 if (prepare_move_operands (operands, V4SFmode))
4704 (define_insn_and_split "*movv16sf_i"
4705 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4706 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4707 "TARGET_SHMEDIA_FPU"
4709 "&& reload_completed"
4715 for (i = 0; i < 16/2; i++)
4719 if (GET_CODE (operands[0]) == MEM)
4720 x = gen_rtx_MEM (V2SFmode,
4721 plus_constant (XEXP (operands[0], 0),
4722 i * GET_MODE_SIZE (V2SFmode)));
4725 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4729 if (GET_CODE (operands[1]) == MEM)
4730 y = gen_rtx_MEM (V2SFmode,
4731 plus_constant (XEXP (operands[1], 0),
4732 i * GET_MODE_SIZE (V2SFmode)));
4735 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4739 emit_insn (gen_movv2sf_i (x, y));
4744 [(set_attr "length" "32")])
4746 (define_expand "movv16sf"
4747 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4748 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4749 "TARGET_SHMEDIA_FPU"
4752 if (prepare_move_operands (operands, V16SFmode))
4756 (define_insn "movsf_media"
4757 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4758 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4760 && (register_operand (operands[0], SFmode)
4761 || sh_register_operand (operands[1], SFmode))"
4772 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4774 (define_insn "movsf_media_nofpu"
4775 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4776 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4778 && (register_operand (operands[0], SFmode)
4779 || sh_register_operand (operands[1], SFmode))"
4785 [(set_attr "type" "arith_media,*,load_media,store_media")])
4788 [(set (match_operand:SF 0 "arith_reg_operand" "")
4789 (match_operand:SF 1 "immediate_operand" ""))]
4790 "TARGET_SHMEDIA && reload_completed
4791 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4792 [(set (match_dup 3) (match_dup 2))]
4796 REAL_VALUE_TYPE value;
4798 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4799 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4800 operands[2] = GEN_INT (values);
4802 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4805 (define_insn "movsf_i"
4806 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4807 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4810 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4811 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4812 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4813 && (arith_reg_operand (operands[0], SFmode)
4814 || arith_reg_operand (operands[1], SFmode))"
4823 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4825 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4826 ;; update_flow_info would not know where to put REG_EQUAL notes
4827 ;; when the destination changes mode.
4828 (define_insn "movsf_ie"
4829 [(set (match_operand:SF 0 "general_movdst_operand"
4830 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4831 (match_operand:SF 1 "general_movsrc_operand"
4832 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4833 (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"))
4834 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4837 && (arith_reg_operand (operands[0], SFmode)
4838 || arith_reg_operand (operands[1], SFmode)
4839 || arith_reg_operand (operands[3], SImode)
4840 || (fpul_operand (operands[0], SFmode)
4841 && memory_operand (operands[1], SFmode)
4842 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4843 || (fpul_operand (operands[1], SFmode)
4844 && memory_operand (operands[0], SFmode)
4845 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4865 ! move optimized away"
4866 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4867 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4868 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4869 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4870 (const_string "single")
4871 (const_string "none")))])
4874 [(set (match_operand:SF 0 "register_operand" "")
4875 (match_operand:SF 1 "register_operand" ""))
4876 (use (match_operand:PSI 2 "fpscr_operand" ""))
4877 (clobber (reg:SI FPUL_REG))]
4879 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4881 (clobber (scratch:SI))])
4882 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4884 (clobber (scratch:SI))])]
4887 (define_expand "movsf"
4888 [(set (match_operand:SF 0 "general_movdst_operand" "")
4889 (match_operand:SF 1 "general_movsrc_operand" ""))]
4893 if (prepare_move_operands (operands, SFmode))
4897 if (TARGET_SHMEDIA_FPU)
4898 emit_insn (gen_movsf_media (operands[0], operands[1]));
4900 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4905 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4910 (define_insn "mov_nop"
4911 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4914 [(set_attr "length" "0")
4915 (set_attr "type" "nil")])
4917 (define_expand "reload_insf"
4918 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4919 (match_operand:SF 1 "immediate_operand" "FQ"))
4920 (use (reg:PSI FPSCR_REG))
4921 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4925 (define_expand "reload_insi"
4926 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4927 (match_operand:SF 1 "immediate_operand" "FQ"))
4928 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4932 (define_insn "*movsi_y"
4933 [(set (match_operand:SI 0 "register_operand" "=y,y")
4934 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
4935 (clobber (match_scratch:SI 2 "=&z,r"))]
4937 && (reload_in_progress || reload_completed)"
4939 [(set_attr "length" "4")
4940 (set_attr "type" "pcload,move")])
4943 [(set (match_operand:SI 0 "register_operand" "")
4944 (match_operand:SI 1 "immediate_operand" ""))
4945 (clobber (match_operand:SI 2 "register_operand" ""))]
4947 [(set (match_dup 2) (match_dup 1))
4948 (set (match_dup 0) (match_dup 2))]
4952 [(set (match_operand:SI 0 "register_operand" "")
4953 (match_operand:SI 1 "memory_operand" ""))
4954 (clobber (reg:SI R0_REG))]
4956 [(set (match_dup 0) (match_dup 1))]
4959 ;; ------------------------------------------------------------------------
4960 ;; Define the real conditional branch instructions.
4961 ;; ------------------------------------------------------------------------
4963 (define_insn "branch_true"
4964 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4965 (label_ref (match_operand 0 "" ""))
4968 "* return output_branch (1, insn, operands);"
4969 [(set_attr "type" "cbranch")])
4971 (define_insn "branch_false"
4972 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4973 (label_ref (match_operand 0 "" ""))
4976 "* return output_branch (0, insn, operands);"
4977 [(set_attr "type" "cbranch")])
4979 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4980 ;; which destination is too far away.
4981 ;; The const_int_operand is distinct for each branch target; it avoids
4982 ;; unwanted matches with redundant_insn.
4983 (define_insn "block_branch_redirect"
4984 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4987 [(set_attr "length" "0")])
4989 ;; This one has the additional purpose to record a possible scratch register
4990 ;; for the following branch.
4991 ;; ??? Unfortunately, just setting the scratch register is not good enough,
4992 ;; because the insn then might be deemed dead and deleted. And we can't
4993 ;; make the use in the jump insn explicit because that would disable
4994 ;; delay slot scheduling from the target.
4995 (define_insn "indirect_jump_scratch"
4996 [(set (match_operand:SI 0 "register_operand" "=r")
4997 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
4998 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5001 [(set_attr "length" "0")])
5003 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5004 ;; being pulled into the delay slot of a condbranch that has been made to
5005 ;; jump around the unconditional jump because it was out of range.
5006 (define_insn "stuff_delay_slot"
5008 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5009 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5012 [(set_attr "length" "0")
5013 (set_attr "cond_delay_slot" "yes")])
5015 ;; Conditional branch insns
5017 (define_expand "beq_media"
5019 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5020 (match_operand:DI 2 "arith_operand" "r,I06"))
5021 (label_ref:DI (match_operand 0 "" ""))
5026 (define_insn "*beq_media_i"
5028 (if_then_else (match_operator 3 "equality_comparison_operator"
5029 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5030 (match_operand:DI 2 "arith_operand" "r,I06")])
5031 (match_operand:DI 0 "target_operand" "b,b")
5037 [(set_attr "type" "cbranch_media")])
5039 (define_expand "bne_media"
5041 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5042 (match_operand:DI 2 "arith_operand" "r,I06"))
5043 (label_ref:DI (match_operand 0 "" ""))
5048 (define_expand "bgt_media"
5050 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5051 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5052 (label_ref:DI (match_operand 0 "" ""))
5057 (define_expand "bge_media"
5059 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5060 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5061 (label_ref:DI (match_operand 0 "" ""))
5066 (define_expand "bgtu_media"
5068 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5069 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5070 (label_ref:DI (match_operand 0 "" ""))
5075 (define_expand "bgeu_media"
5077 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5078 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5079 (label_ref:DI (match_operand 0 "" ""))
5084 (define_insn "*bgt_media_i"
5086 (if_then_else (match_operator 3 "greater_comparison_operator"
5087 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5088 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5089 (match_operand:DI 0 "target_operand" "b")
5092 "b%o3%' %N1, %N2, %0"
5093 [(set_attr "type" "cbranch_media")])
5095 ;; These are only needed to make invert_jump() happy.
5096 (define_insn "*blt_media_i"
5098 (if_then_else (match_operator 3 "less_comparison_operator"
5099 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5100 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5101 (match_operand:DI 0 "target_operand" "b")
5104 "b%o3%' %N2, %N1, %0"
5105 [(set_attr "type" "cbranch_media")])
5107 (define_expand "beq"
5109 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5110 (label_ref (match_operand 0 "" ""))
5117 if (GET_MODE (sh_compare_op0) != DImode)
5119 rtx tmp = gen_reg_rtx (DImode);
5121 emit_insn (gen_seq (tmp));
5122 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5126 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5127 emit_jump_insn (gen_beq_media (operands[0],
5128 sh_compare_op0, sh_compare_op1));
5132 from_compare (operands, EQ);
5135 (define_expand "bne"
5137 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5138 (label_ref (match_operand 0 "" ""))
5145 if (GET_MODE (sh_compare_op0) != DImode)
5147 rtx tmp = gen_reg_rtx (DImode);
5149 emit_insn (gen_seq (tmp));
5150 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5154 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5155 emit_jump_insn (gen_bne_media (operands[0],
5156 sh_compare_op0, sh_compare_op1));
5160 from_compare (operands, EQ);
5163 (define_expand "bgt"
5165 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5166 (label_ref (match_operand 0 "" ""))
5173 if (GET_MODE (sh_compare_op0) != DImode)
5175 rtx tmp = gen_reg_rtx (DImode);
5177 emit_insn (gen_sgt (tmp));
5178 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5182 if (sh_compare_op0 != const0_rtx)
5183 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5184 if (sh_compare_op1 != const0_rtx)
5185 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5186 emit_jump_insn (gen_bgt_media (operands[0],
5187 sh_compare_op0, sh_compare_op1));
5191 from_compare (operands, GT);
5194 (define_expand "blt"
5196 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5197 (label_ref (match_operand 0 "" ""))
5204 if (GET_MODE (sh_compare_op0) != DImode)
5206 rtx tmp = gen_reg_rtx (DImode);
5208 emit_insn (gen_slt (tmp));
5209 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5213 if (sh_compare_op0 != const0_rtx)
5214 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5215 if (sh_compare_op1 != const0_rtx)
5216 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5217 emit_jump_insn (gen_bgt_media (operands[0],
5218 sh_compare_op1, sh_compare_op0));
5222 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5224 rtx tmp = sh_compare_op0;
5225 sh_compare_op0 = sh_compare_op1;
5226 sh_compare_op1 = tmp;
5227 emit_insn (gen_bgt (operands[0]));
5230 from_compare (operands, GE);
5233 (define_expand "ble"
5235 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5236 (label_ref (match_operand 0 "" ""))
5243 if (GET_MODE (sh_compare_op0) != DImode)
5245 rtx tmp = gen_reg_rtx (DImode);
5247 emit_insn (gen_sle (tmp));
5248 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5252 if (sh_compare_op0 != const0_rtx)
5253 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5254 if (sh_compare_op1 != const0_rtx)
5255 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5256 emit_jump_insn (gen_bge_media (operands[0],
5257 sh_compare_op1, sh_compare_op0));
5263 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5265 rtx tmp = sh_compare_op0;
5266 sh_compare_op0 = sh_compare_op1;
5267 sh_compare_op1 = tmp;
5268 emit_insn (gen_bge (operands[0]));
5271 from_compare (operands, GT);
5274 (define_expand "bge"
5276 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5277 (label_ref (match_operand 0 "" ""))
5284 if (GET_MODE (sh_compare_op0) != DImode)
5286 rtx tmp = gen_reg_rtx (DImode);
5288 emit_insn (gen_sge (tmp));
5289 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5293 if (sh_compare_op0 != const0_rtx)
5294 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5295 if (sh_compare_op1 != const0_rtx)
5296 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5297 emit_jump_insn (gen_bge_media (operands[0],
5298 sh_compare_op0, sh_compare_op1));
5304 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5306 rtx tmp = sh_compare_op0;
5307 sh_compare_op0 = sh_compare_op1;
5308 sh_compare_op1 = tmp;
5309 emit_insn (gen_ble (operands[0]));
5312 from_compare (operands, GE);
5315 (define_expand "bgtu"
5317 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5318 (label_ref (match_operand 0 "" ""))
5325 if (sh_compare_op0 != const0_rtx)
5326 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5327 if (sh_compare_op1 != const0_rtx)
5328 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5329 emit_jump_insn (gen_bgtu_media (operands[0],
5330 sh_compare_op0, sh_compare_op1));
5334 from_compare (operands, GTU);
5337 (define_expand "bltu"
5339 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5340 (label_ref (match_operand 0 "" ""))
5347 if (sh_compare_op0 != const0_rtx)
5348 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5349 if (sh_compare_op1 != const0_rtx)
5350 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5351 emit_jump_insn (gen_bgtu_media (operands[0],
5352 sh_compare_op1, sh_compare_op0));
5356 from_compare (operands, GEU);
5359 (define_expand "bgeu"
5361 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5362 (label_ref (match_operand 0 "" ""))
5369 if (sh_compare_op0 != const0_rtx)
5370 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5371 if (sh_compare_op1 != const0_rtx)
5372 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5373 emit_jump_insn (gen_bgeu_media (operands[0],
5374 sh_compare_op0, sh_compare_op1));
5378 from_compare (operands, GEU);
5381 (define_expand "bleu"
5383 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5384 (label_ref (match_operand 0 "" ""))
5391 if (sh_compare_op0 != const0_rtx)
5392 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5393 if (sh_compare_op1 != const0_rtx)
5394 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5395 emit_jump_insn (gen_bgeu_media (operands[0],
5396 sh_compare_op1, sh_compare_op0));
5400 from_compare (operands, GTU);
5403 (define_expand "bunordered"
5404 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5406 (if_then_else (ne (match_dup 1) (const_int 0))
5407 (label_ref:DI (match_operand 0 "" ""))
5412 operands[1] = gen_reg_rtx (DImode);
5413 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5414 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5417 ;; ------------------------------------------------------------------------
5418 ;; Jump and linkage insns
5419 ;; ------------------------------------------------------------------------
5421 (define_insn "jump_compact"
5423 (label_ref (match_operand 0 "" "")))]
5427 /* The length is 16 if the delay slot is unfilled. */
5428 if (get_attr_length(insn) > 4)
5429 return output_far_jump(insn, operands[0]);
5431 return \"bra %l0%#\";
5433 [(set_attr "type" "jump")
5434 (set_attr "needs_delay_slot" "yes")])
5436 ;; ??? It would be much saner to explicitly use the scratch register
5437 ;; in the jump insn, and have indirect_jump_scratch only set it,
5438 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5439 ;; from the target then, as it uses simplejump_p.
5440 ;;(define_insn "jump_compact_far"
5442 ;; (label_ref (match_operand 0 "" "")))
5443 ;; (use (match_operand 1 "register_operand" "r")]
5445 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5446 ;; [(set_attr "type" "jump")
5447 ;; (set_attr "needs_delay_slot" "yes")])
5449 (define_insn "jump_media"
5451 (match_operand:DI 0 "target_operand" "b"))]
5454 [(set_attr "type" "jump_media")])
5456 (define_expand "jump"
5458 (label_ref (match_operand 0 "" "")))]
5463 emit_jump_insn (gen_jump_compact (operands[0]));
5464 else if (TARGET_SHMEDIA)
5466 if (reload_in_progress || reload_completed)
5468 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5474 (define_insn "force_mode_for_call"
5475 [(use (reg:PSI FPSCR_REG))]
5478 [(set_attr "length" "0")
5479 (set (attr "fp_mode")
5480 (if_then_else (eq_attr "fpu_single" "yes")
5481 (const_string "single") (const_string "double")))])
5483 (define_insn "calli"
5484 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5485 (match_operand 1 "" ""))
5486 (use (reg:PSI FPSCR_REG))
5487 (clobber (reg:SI PR_REG))]
5490 [(set_attr "type" "call")
5491 (set (attr "fp_mode")
5492 (if_then_else (eq_attr "fpu_single" "yes")
5493 (const_string "single") (const_string "double")))
5494 (set_attr "needs_delay_slot" "yes")
5495 (set_attr "fp_set" "unknown")])
5497 ;; This is a pc-rel call, using bsrf, for use with PIC.
5499 (define_insn "calli_pcrel"
5500 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5501 (match_operand 1 "" ""))
5502 (use (reg:PSI FPSCR_REG))
5503 (use (reg:SI PIC_REG))
5504 (use (match_operand 2 "" ""))
5505 (clobber (reg:SI PR_REG))]
5508 [(set_attr "type" "call")
5509 (set (attr "fp_mode")
5510 (if_then_else (eq_attr "fpu_single" "yes")
5511 (const_string "single") (const_string "double")))
5512 (set_attr "needs_delay_slot" "yes")
5513 (set_attr "fp_set" "unknown")])
5515 (define_insn_and_split "call_pcrel"
5516 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5517 (match_operand 1 "" ""))
5518 (use (reg:PSI FPSCR_REG))
5519 (use (reg:SI PIC_REG))
5520 (clobber (reg:SI PR_REG))
5521 (clobber (match_scratch:SI 2 "=r"))]
5528 rtx lab = PATTERN (gen_call_site ());
5530 if (SYMBOL_REF_LOCAL_P (operands[0]))
5531 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5533 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5534 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5537 [(set_attr "type" "call")
5538 (set (attr "fp_mode")
5539 (if_then_else (eq_attr "fpu_single" "yes")
5540 (const_string "single") (const_string "double")))
5541 (set_attr "needs_delay_slot" "yes")
5542 (set_attr "fp_set" "unknown")])
5544 (define_insn "call_compact"
5545 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5546 (match_operand 1 "" ""))
5547 (match_operand 2 "immediate_operand" "n")
5548 (use (reg:SI R0_REG))
5549 (use (reg:SI R1_REG))
5550 (use (reg:PSI FPSCR_REG))
5551 (clobber (reg:SI PR_REG))]
5552 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5554 [(set_attr "type" "call")
5555 (set (attr "fp_mode")
5556 (if_then_else (eq_attr "fpu_single" "yes")
5557 (const_string "single") (const_string "double")))
5558 (set_attr "needs_delay_slot" "yes")])
5560 (define_insn "call_compact_rettramp"
5561 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5562 (match_operand 1 "" ""))
5563 (match_operand 2 "immediate_operand" "n")
5564 (use (reg:SI R0_REG))
5565 (use (reg:SI R1_REG))
5566 (use (reg:PSI FPSCR_REG))
5567 (clobber (reg:SI R10_REG))
5568 (clobber (reg:SI PR_REG))]
5569 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5571 [(set_attr "type" "call")
5572 (set (attr "fp_mode")
5573 (if_then_else (eq_attr "fpu_single" "yes")
5574 (const_string "single") (const_string "double")))
5575 (set_attr "needs_delay_slot" "yes")])
5577 (define_insn "call_media"
5578 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5579 (match_operand 1 "" ""))
5580 (clobber (reg:DI PR_MEDIA_REG))]
5583 [(set_attr "type" "jump_media")])
5585 (define_insn "call_valuei"
5586 [(set (match_operand 0 "" "=rf")
5587 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5588 (match_operand 2 "" "")))
5589 (use (reg:PSI FPSCR_REG))
5590 (clobber (reg:SI PR_REG))]
5593 [(set_attr "type" "call")
5594 (set (attr "fp_mode")
5595 (if_then_else (eq_attr "fpu_single" "yes")
5596 (const_string "single") (const_string "double")))
5597 (set_attr "needs_delay_slot" "yes")
5598 (set_attr "fp_set" "unknown")])
5600 (define_insn "call_valuei_pcrel"
5601 [(set (match_operand 0 "" "=rf")
5602 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5603 (match_operand 2 "" "")))
5604 (use (reg:PSI FPSCR_REG))
5605 (use (reg:SI PIC_REG))
5606 (use (match_operand 3 "" ""))
5607 (clobber (reg:SI PR_REG))]
5610 [(set_attr "type" "call")
5611 (set (attr "fp_mode")
5612 (if_then_else (eq_attr "fpu_single" "yes")
5613 (const_string "single") (const_string "double")))
5614 (set_attr "needs_delay_slot" "yes")
5615 (set_attr "fp_set" "unknown")])
5617 (define_insn_and_split "call_value_pcrel"
5618 [(set (match_operand 0 "" "=rf")
5619 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5620 (match_operand 2 "" "")))
5621 (use (reg:PSI FPSCR_REG))
5622 (use (reg:SI PIC_REG))
5623 (clobber (reg:SI PR_REG))
5624 (clobber (match_scratch:SI 3 "=r"))]
5631 rtx lab = PATTERN (gen_call_site ());
5633 if (SYMBOL_REF_LOCAL_P (operands[1]))
5634 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5636 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5637 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5641 [(set_attr "type" "call")
5642 (set (attr "fp_mode")
5643 (if_then_else (eq_attr "fpu_single" "yes")
5644 (const_string "single") (const_string "double")))
5645 (set_attr "needs_delay_slot" "yes")
5646 (set_attr "fp_set" "unknown")])
5648 (define_insn "call_value_compact"
5649 [(set (match_operand 0 "" "=rf")
5650 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5651 (match_operand 2 "" "")))
5652 (match_operand 3 "immediate_operand" "n")
5653 (use (reg:SI R0_REG))
5654 (use (reg:SI R1_REG))
5655 (use (reg:PSI FPSCR_REG))
5656 (clobber (reg:SI PR_REG))]
5657 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5659 [(set_attr "type" "call")
5660 (set (attr "fp_mode")
5661 (if_then_else (eq_attr "fpu_single" "yes")
5662 (const_string "single") (const_string "double")))
5663 (set_attr "needs_delay_slot" "yes")])
5665 (define_insn "call_value_compact_rettramp"
5666 [(set (match_operand 0 "" "=rf")
5667 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5668 (match_operand 2 "" "")))
5669 (match_operand 3 "immediate_operand" "n")
5670 (use (reg:SI R0_REG))
5671 (use (reg:SI R1_REG))
5672 (use (reg:PSI FPSCR_REG))
5673 (clobber (reg:SI R10_REG))
5674 (clobber (reg:SI PR_REG))]
5675 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5677 [(set_attr "type" "call")
5678 (set (attr "fp_mode")
5679 (if_then_else (eq_attr "fpu_single" "yes")
5680 (const_string "single") (const_string "double")))
5681 (set_attr "needs_delay_slot" "yes")])
5683 (define_insn "call_value_media"
5684 [(set (match_operand 0 "" "=rf")
5685 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5686 (match_operand 2 "" "")))
5687 (clobber (reg:DI PR_MEDIA_REG))]
5690 [(set_attr "type" "jump_media")])
5692 (define_expand "call"
5693 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5694 (match_operand 1 "" ""))
5695 (match_operand 2 "" "")
5696 (use (reg:PSI FPSCR_REG))
5697 (clobber (reg:SI PR_REG))])]
5703 operands[0] = XEXP (operands[0], 0);
5704 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5706 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5708 rtx reg = gen_reg_rtx (Pmode);
5710 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5715 operands[0] = gen_sym2PIC (operands[0]);
5716 PUT_MODE (operands[0], Pmode);
5719 if (GET_MODE (operands[0]) == SImode)
5721 if (GET_CODE (operands[0]) == REG)
5722 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5723 else if (GET_CODE (operands[0]) == SUBREG)
5725 operands[0] = SUBREG_REG (operands[0]);
5726 if (GET_MODE (operands[0]) != DImode)
5727 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5731 operands[0] = shallow_copy_rtx (operands[0]);
5732 PUT_MODE (operands[0], DImode);
5735 if (! target_reg_operand (operands[0], DImode))
5736 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5737 emit_call_insn (gen_call_media (operands[0], operands[1]));
5740 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5742 rtx cookie_rtx = operands[2];
5743 long cookie = INTVAL (cookie_rtx);
5744 rtx func = XEXP (operands[0], 0);
5749 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5751 rtx reg = gen_reg_rtx (Pmode);
5753 emit_insn (gen_symGOTPLT2reg (reg, func));
5757 func = legitimize_pic_address (func, Pmode, 0);
5760 r0 = gen_rtx_REG (SImode, R0_REG);
5761 r1 = gen_rtx_REG (SImode, R1_REG);
5763 /* Since such a call function may use all call-clobbered
5764 registers, we force a mode switch earlier, so that we don't
5765 run out of registers when adjusting fpscr for the call. */
5766 emit_insn (gen_force_mode_for_call ());
5768 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5771 rtx reg = gen_reg_rtx (Pmode);
5773 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5776 operands[0] = force_reg (SImode, operands[0]);
5778 emit_move_insn (r0, func);
5779 emit_move_insn (r1, cookie_rtx);
5781 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5782 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5785 emit_call_insn (gen_call_compact (operands[0], operands[1],
5790 else if (TARGET_SHCOMPACT && flag_pic
5791 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5792 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5794 rtx reg = gen_reg_rtx (Pmode);
5796 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5797 XEXP (operands[0], 0) = reg;
5799 if (flag_pic && TARGET_SH2
5800 && GET_CODE (operands[0]) == MEM
5801 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5803 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5808 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5809 operands[1] = operands[2];
5812 emit_call_insn (gen_calli (operands[0], operands[1]));
5816 (define_insn "call_pop_compact"
5817 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5818 (match_operand 1 "" ""))
5819 (match_operand 2 "immediate_operand" "n")
5820 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5821 (match_operand 3 "immediate_operand" "n")))
5822 (use (reg:SI R0_REG))
5823 (use (reg:SI R1_REG))
5824 (use (reg:PSI FPSCR_REG))
5825 (clobber (reg:SI PR_REG))]
5826 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5828 [(set_attr "type" "call")
5829 (set (attr "fp_mode")
5830 (if_then_else (eq_attr "fpu_single" "yes")
5831 (const_string "single") (const_string "double")))
5832 (set_attr "needs_delay_slot" "yes")])
5834 (define_insn "call_pop_compact_rettramp"
5835 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5836 (match_operand 1 "" ""))
5837 (match_operand 2 "immediate_operand" "n")
5838 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5839 (match_operand 3 "immediate_operand" "n")))
5840 (use (reg:SI R0_REG))
5841 (use (reg:SI R1_REG))
5842 (use (reg:PSI FPSCR_REG))
5843 (clobber (reg:SI R10_REG))
5844 (clobber (reg:SI PR_REG))]
5845 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5847 [(set_attr "type" "call")
5848 (set (attr "fp_mode")
5849 (if_then_else (eq_attr "fpu_single" "yes")
5850 (const_string "single") (const_string "double")))
5851 (set_attr "needs_delay_slot" "yes")])
5853 (define_expand "call_pop"
5854 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5855 (match_operand 1 "" ""))
5856 (match_operand 2 "" "")
5857 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5858 (match_operand 3 "" "")))])]
5862 if (operands[2] && INTVAL (operands[2]))
5864 rtx cookie_rtx = operands[2];
5865 long cookie = INTVAL (cookie_rtx);
5866 rtx func = XEXP (operands[0], 0);
5871 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5873 rtx reg = gen_reg_rtx (Pmode);
5875 emit_insn (gen_symGOTPLT2reg (reg, func));
5879 func = legitimize_pic_address (func, Pmode, 0);
5882 r0 = gen_rtx_REG (SImode, R0_REG);
5883 r1 = gen_rtx_REG (SImode, R1_REG);
5885 /* Since such a call function may use all call-clobbered
5886 registers, we force a mode switch earlier, so that we don't
5887 run out of registers when adjusting fpscr for the call. */
5888 emit_insn (gen_force_mode_for_call ());
5890 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5893 rtx reg = gen_reg_rtx (Pmode);
5895 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5898 operands[0] = force_reg (SImode, operands[0]);
5900 emit_move_insn (r0, func);
5901 emit_move_insn (r1, cookie_rtx);
5903 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5904 emit_call_insn (gen_call_pop_compact_rettramp
5905 (operands[0], operands[1], operands[2], operands[3]));
5907 emit_call_insn (gen_call_pop_compact
5908 (operands[0], operands[1], operands[2], operands[3]));
5916 (define_expand "call_value"
5917 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5918 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5919 (match_operand 2 "" "")))
5920 (match_operand 3 "" "")
5921 (use (reg:PSI FPSCR_REG))
5922 (clobber (reg:SI PR_REG))])]
5928 operands[1] = XEXP (operands[1], 0);
5929 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5931 if (! SYMBOL_REF_LOCAL_P (operands[1]))
5933 rtx reg = gen_reg_rtx (Pmode);
5935 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5940 operands[1] = gen_sym2PIC (operands[1]);
5941 PUT_MODE (operands[1], Pmode);
5944 if (GET_MODE (operands[1]) == SImode)
5946 if (GET_CODE (operands[1]) == REG)
5947 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5948 else if (GET_CODE (operands[1]) == SUBREG)
5950 operands[1] = SUBREG_REG (operands[1]);
5951 if (GET_MODE (operands[1]) != DImode)
5952 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5956 operands[1] = shallow_copy_rtx (operands[1]);
5957 PUT_MODE (operands[1], DImode);
5960 if (! target_reg_operand (operands[1], DImode))
5961 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5962 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5966 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5968 rtx cookie_rtx = operands[3];
5969 long cookie = INTVAL (cookie_rtx);
5970 rtx func = XEXP (operands[1], 0);
5975 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5977 rtx reg = gen_reg_rtx (Pmode);
5979 emit_insn (gen_symGOTPLT2reg (reg, func));
5983 func = legitimize_pic_address (func, Pmode, 0);
5986 r0 = gen_rtx_REG (SImode, R0_REG);
5987 r1 = gen_rtx_REG (SImode, R1_REG);
5989 /* Since such a call function may use all call-clobbered
5990 registers, we force a mode switch earlier, so that we don't
5991 run out of registers when adjusting fpscr for the call. */
5992 emit_insn (gen_force_mode_for_call ());
5994 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5997 rtx reg = gen_reg_rtx (Pmode);
5999 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6002 operands[1] = force_reg (SImode, operands[1]);
6004 emit_move_insn (r0, func);
6005 emit_move_insn (r1, cookie_rtx);
6007 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6008 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6013 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6014 operands[2], operands[3]));
6018 else if (TARGET_SHCOMPACT && flag_pic
6019 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6020 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6022 rtx reg = gen_reg_rtx (Pmode);
6024 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6025 XEXP (operands[1], 0) = reg;
6027 if (flag_pic && TARGET_SH2
6028 && GET_CODE (operands[1]) == MEM
6029 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6031 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6036 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6038 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6042 (define_insn "sibcalli"
6043 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6044 (match_operand 1 "" ""))
6045 (use (reg:PSI FPSCR_REG))
6049 [(set_attr "needs_delay_slot" "yes")
6050 (set (attr "fp_mode")
6051 (if_then_else (eq_attr "fpu_single" "yes")
6052 (const_string "single") (const_string "double")))
6053 (set_attr "type" "jump_ind")])
6055 (define_insn "sibcalli_pcrel"
6056 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6057 (match_operand 1 "" ""))
6058 (use (match_operand 2 "" ""))
6059 (use (reg:PSI FPSCR_REG))
6063 [(set_attr "needs_delay_slot" "yes")
6064 (set (attr "fp_mode")
6065 (if_then_else (eq_attr "fpu_single" "yes")
6066 (const_string "single") (const_string "double")))
6067 (set_attr "type" "jump_ind")])
6069 (define_insn_and_split "sibcall_pcrel"
6070 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6071 (match_operand 1 "" ""))
6072 (use (reg:PSI FPSCR_REG))
6073 (clobber (match_scratch:SI 2 "=k"))
6081 rtx lab = PATTERN (gen_call_site ());
6084 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6085 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6087 SIBLING_CALL_P (call_insn) = 1;
6090 [(set_attr "needs_delay_slot" "yes")
6091 (set (attr "fp_mode")
6092 (if_then_else (eq_attr "fpu_single" "yes")
6093 (const_string "single") (const_string "double")))
6094 (set_attr "type" "jump_ind")])
6096 (define_insn "sibcall_compact"
6097 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6098 (match_operand 1 "" ""))
6100 (use (match_operand:SI 2 "register_operand" "z,x"))
6101 (use (reg:SI R1_REG))
6102 (use (reg:PSI FPSCR_REG))
6103 ;; We want to make sure the `x' above will only match MACH_REG
6104 ;; because sibcall_epilogue may clobber MACL_REG.
6105 (clobber (reg:SI MACL_REG))]
6109 jmp @%0\\n sts %2, r0"
6110 [(set_attr "needs_delay_slot" "yes,no")
6111 (set_attr "length" "2,4")
6112 (set (attr "fp_mode") (const_string "single"))
6113 (set_attr "type" "jump_ind")])
6115 (define_insn "sibcall_media"
6116 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6117 (match_operand 1 "" ""))
6118 (use (reg:SI PR_MEDIA_REG))
6122 [(set_attr "type" "jump_media")])
6124 (define_expand "sibcall"
6126 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6127 (match_operand 1 "" ""))
6128 (match_operand 2 "" "")
6129 (use (reg:PSI FPSCR_REG))
6136 operands[0] = XEXP (operands[0], 0);
6137 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6139 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6141 rtx reg = gen_reg_rtx (Pmode);
6143 /* We must not use GOTPLT for sibcalls, because PIC_REG
6144 must be restored before the PLT code gets to run. */
6145 emit_insn (gen_symGOT2reg (reg, operands[0]));
6150 operands[0] = gen_sym2PIC (operands[0]);
6151 PUT_MODE (operands[0], Pmode);
6154 if (GET_MODE (operands[0]) == SImode)
6156 if (GET_CODE (operands[0]) == REG)
6157 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6158 else if (GET_CODE (operands[0]) == SUBREG)
6160 operands[0] = SUBREG_REG (operands[0]);
6161 if (GET_MODE (operands[0]) != DImode)
6162 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6166 operands[0] = shallow_copy_rtx (operands[0]);
6167 PUT_MODE (operands[0], DImode);
6170 if (! target_reg_operand (operands[0], DImode))
6171 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6172 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6175 else if (TARGET_SHCOMPACT && operands[2]
6176 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6178 rtx cookie_rtx = operands[2];
6179 long cookie = INTVAL (cookie_rtx);
6180 rtx func = XEXP (operands[0], 0);
6185 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6187 rtx reg = gen_reg_rtx (Pmode);
6189 emit_insn (gen_symGOT2reg (reg, func));
6193 func = legitimize_pic_address (func, Pmode, 0);
6196 /* FIXME: if we could tell whether all argument registers are
6197 already taken, we could decide whether to force the use of
6198 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6199 simple way to tell. We could use the CALL_COOKIE, but we
6200 can't currently tell a register used for regular argument
6201 passing from one that is unused. If we leave it up to reload
6202 to decide which register to use, it seems to always choose
6203 R0_REG, which leaves no available registers in SIBCALL_REGS
6204 to hold the address of the trampoline. */
6205 mach = gen_rtx_REG (SImode, MACH_REG);
6206 r1 = gen_rtx_REG (SImode, R1_REG);
6208 /* Since such a call function may use all call-clobbered
6209 registers, we force a mode switch earlier, so that we don't
6210 run out of registers when adjusting fpscr for the call. */
6211 emit_insn (gen_force_mode_for_call ());
6213 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6216 rtx reg = gen_reg_rtx (Pmode);
6218 emit_insn (gen_symGOT2reg (reg, operands[0]));
6221 operands[0] = force_reg (SImode, operands[0]);
6223 /* We don't need a return trampoline, since the callee will
6224 return directly to the upper caller. */
6225 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6227 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6228 cookie_rtx = GEN_INT (cookie);
6231 emit_move_insn (mach, func);
6232 emit_move_insn (r1, cookie_rtx);
6234 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6237 else if (TARGET_SHCOMPACT && flag_pic
6238 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6239 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6241 rtx reg = gen_reg_rtx (Pmode);
6243 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6244 XEXP (operands[0], 0) = reg;
6246 if (flag_pic && TARGET_SH2
6247 && GET_CODE (operands[0]) == MEM
6248 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6249 /* The PLT needs the PIC register, but the epilogue would have
6250 to restore it, so we can only use PC-relative PIC calls for
6251 static functions. */
6252 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6254 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6258 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6260 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6264 (define_expand "sibcall_value"
6265 [(set (match_operand 0 "" "")
6266 (call (match_operand 1 "" "")
6267 (match_operand 2 "" "")))
6268 (match_operand 3 "" "")]
6272 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6276 (define_insn "call_value_pop_compact"
6277 [(set (match_operand 0 "" "=rf")
6278 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6279 (match_operand 2 "" "")))
6280 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6281 (match_operand 4 "immediate_operand" "n")))
6282 (match_operand 3 "immediate_operand" "n")
6283 (use (reg:SI R0_REG))
6284 (use (reg:SI R1_REG))
6285 (use (reg:PSI FPSCR_REG))
6286 (clobber (reg:SI PR_REG))]
6287 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6289 [(set_attr "type" "call")
6290 (set (attr "fp_mode")
6291 (if_then_else (eq_attr "fpu_single" "yes")
6292 (const_string "single") (const_string "double")))
6293 (set_attr "needs_delay_slot" "yes")])
6295 (define_insn "call_value_pop_compact_rettramp"
6296 [(set (match_operand 0 "" "=rf")
6297 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6298 (match_operand 2 "" "")))
6299 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6300 (match_operand 4 "immediate_operand" "n")))
6301 (match_operand 3 "immediate_operand" "n")
6302 (use (reg:SI R0_REG))
6303 (use (reg:SI R1_REG))
6304 (use (reg:PSI FPSCR_REG))
6305 (clobber (reg:SI R10_REG))
6306 (clobber (reg:SI PR_REG))]
6307 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6309 [(set_attr "type" "call")
6310 (set (attr "fp_mode")
6311 (if_then_else (eq_attr "fpu_single" "yes")
6312 (const_string "single") (const_string "double")))
6313 (set_attr "needs_delay_slot" "yes")])
6315 (define_expand "call_value_pop"
6316 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6317 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6318 (match_operand 2 "" "")))
6319 (match_operand 3 "" "")
6320 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6321 (match_operand 4 "" "")))])]
6325 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6327 rtx cookie_rtx = operands[3];
6328 long cookie = INTVAL (cookie_rtx);
6329 rtx func = XEXP (operands[1], 0);
6334 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6336 rtx reg = gen_reg_rtx (Pmode);
6338 emit_insn (gen_symGOTPLT2reg (reg, func));
6342 func = legitimize_pic_address (func, Pmode, 0);
6345 r0 = gen_rtx_REG (SImode, R0_REG);
6346 r1 = gen_rtx_REG (SImode, R1_REG);
6348 /* Since such a call function may use all call-clobbered
6349 registers, we force a mode switch earlier, so that we don't
6350 run out of registers when adjusting fpscr for the call. */
6351 emit_insn (gen_force_mode_for_call ());
6353 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6356 rtx reg = gen_reg_rtx (Pmode);
6358 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6361 operands[1] = force_reg (SImode, operands[1]);
6363 emit_move_insn (r0, func);
6364 emit_move_insn (r1, cookie_rtx);
6366 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6367 emit_call_insn (gen_call_value_pop_compact_rettramp
6368 (operands[0], operands[1], operands[2],
6369 operands[3], operands[4]));
6371 emit_call_insn (gen_call_value_pop_compact
6372 (operands[0], operands[1], operands[2],
6373 operands[3], operands[4]));
6381 (define_expand "sibcall_epilogue"
6386 sh_expand_epilogue (1);
6387 if (TARGET_SHCOMPACT)
6391 /* If epilogue clobbers r0, preserve it in macl. */
6392 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6393 if ((set = single_set (insn))
6394 && GET_CODE (SET_DEST (set)) == REG
6395 && REGNO (SET_DEST (set)) == R0_REG)
6397 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6398 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6401 /* We can't tell at this point whether the sibcall is a
6402 sibcall_compact and, if it is, whether it uses r0 or
6403 mach as operand 2, so let the instructions that
6404 preserve r0 be optimized away if r0 turns out to be
6406 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6407 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6409 i = emit_move_insn (r0, tmp);
6410 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6418 (define_insn "indirect_jump_compact"
6420 (match_operand:SI 0 "arith_reg_operand" "r"))]
6423 [(set_attr "needs_delay_slot" "yes")
6424 (set_attr "type" "jump_ind")])
6426 (define_expand "indirect_jump"
6428 (match_operand 0 "register_operand" ""))]
6432 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6433 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6436 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6437 ;; which can be present in structured code from indirect jumps which can not
6438 ;; be present in structured code. This allows -fprofile-arcs to work.
6440 ;; For SH1 processors.
6441 (define_insn "casesi_jump_1"
6443 (match_operand:SI 0 "register_operand" "r"))
6444 (use (label_ref (match_operand 1 "" "")))]
6447 [(set_attr "needs_delay_slot" "yes")
6448 (set_attr "type" "jump_ind")])
6450 ;; For all later processors.
6451 (define_insn "casesi_jump_2"
6452 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6453 (label_ref (match_operand 1 "" ""))))
6454 (use (label_ref (match_operand 2 "" "")))]
6456 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6458 [(set_attr "needs_delay_slot" "yes")
6459 (set_attr "type" "jump_ind")])
6461 (define_insn "casesi_jump_media"
6462 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6463 (use (label_ref (match_operand 1 "" "")))]
6466 [(set_attr "type" "jump_media")])
6468 ;; Call subroutine returning any type.
6469 ;; ??? This probably doesn't work.
6471 (define_expand "untyped_call"
6472 [(parallel [(call (match_operand 0 "" "")
6474 (match_operand 1 "" "")
6475 (match_operand 2 "" "")])]
6476 "TARGET_SH2E || TARGET_SHMEDIA"
6481 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6483 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6485 rtx set = XVECEXP (operands[2], 0, i);
6486 emit_move_insn (SET_DEST (set), SET_SRC (set));
6489 /* The optimizer does not know that the call sets the function value
6490 registers we stored in the result block. We avoid problems by
6491 claiming that all hard registers are used and clobbered at this
6493 emit_insn (gen_blockage ());
6498 ;; ------------------------------------------------------------------------
6500 ;; ------------------------------------------------------------------------
6503 [(set (reg:SI T_REG)
6504 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6505 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6508 [(set_attr "type" "arith")])
6515 ;; Load address of a label. This is only generated by the casesi expand,
6516 ;; and by machine_dependent_reorg (fixing up fp moves).
6517 ;; This must use unspec, because this only works for labels that are
6521 [(set (reg:SI R0_REG)
6522 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6525 [(set_attr "in_delay_slot" "no")
6526 (set_attr "type" "arith")])
6528 ;; machine_dependent_reorg will make this a `mova'.
6529 (define_insn "mova_const"
6530 [(set (reg:SI R0_REG)
6531 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6534 [(set_attr "in_delay_slot" "no")
6535 (set_attr "type" "arith")])
6537 (define_expand "GOTaddr2picreg"
6538 [(set (reg:SI R0_REG)
6539 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6541 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6542 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6545 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6546 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6549 operands[1] = gen_datalabel_ref (operands[1]);
6553 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6554 rtx dipic = operands[0];
6555 rtx lab = PATTERN (gen_call_site ());
6558 equiv = operands[1];
6559 operands[1] = gen_rtx_MINUS (DImode,
6563 gen_rtx_MINUS (DImode,
6564 gen_rtx_CONST (DImode,
6567 operands[1] = gen_sym2PIC (operands[1]);
6568 PUT_MODE (operands[1], DImode);
6570 if (GET_MODE (dipic) != DImode)
6571 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6573 if (TARGET_SHMEDIA64)
6574 emit_insn (gen_movdi_const (dipic, operands[1]));
6576 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6578 emit_insn (gen_ptrel (tr, dipic, lab));
6580 if (GET_MODE (operands[0]) != GET_MODE (tr))
6581 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6583 insn = emit_move_insn (operands[0], tr);
6585 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6594 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6595 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6596 UNSPEC_DATALABEL)))]
6597 "TARGET_SHMEDIA && flag_pic
6598 && EXTRA_CONSTRAINT_Csy (operands[1])"
6599 "ptb/u datalabel %1, %0"
6600 [(set_attr "type" "pt_media")
6601 (set_attr "length" "*")])
6603 (define_insn "ptrel"
6604 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6605 (plus:DI (match_operand:DI 1 "register_operand" "r")
6607 (match_operand:DI 2 "" "")]
6609 "%O2: ptrel/u %1, %0"
6610 [(set_attr "type" "ptabs_media")])
6612 (define_expand "builtin_setjmp_receiver"
6613 [(match_operand 0 "" "")]
6617 emit_insn (gen_GOTaddr2picreg ());
6621 (define_expand "call_site"
6622 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6626 static HOST_WIDE_INT i = 0;
6627 operands[0] = GEN_INT (i);
6631 (define_expand "sym_label2reg"
6632 [(set (match_operand:SI 0 "" "")
6635 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6638 (match_operand:SI 2 "" "")
6642 (define_expand "symGOT_load"
6643 [(set (match_dup 2) (match_operand 1 "" ""))
6644 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6645 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6651 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6652 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6656 rtx reg = operands[2];
6658 if (GET_MODE (reg) != DImode)
6659 reg = gen_rtx_SUBREG (DImode, reg, 0);
6662 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6664 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6667 emit_move_insn (operands[2], operands[1]);
6669 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6671 gen_rtx_REG (Pmode, PIC_REG)));
6673 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6675 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6682 (define_expand "sym2GOT"
6683 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6687 (define_expand "symGOT2reg"
6688 [(match_operand 0 "" "") (match_operand 1 "" "")]
6694 gotsym = gen_sym2GOT (operands[1]);
6695 PUT_MODE (gotsym, Pmode);
6696 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6698 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6703 (define_expand "sym2GOTPLT"
6704 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6708 (define_expand "symGOTPLT2reg"
6709 [(match_operand 0 "" "") (match_operand 1 "" "")]
6713 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6717 (define_expand "sym2GOTOFF"
6718 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6722 (define_expand "symGOTOFF2reg"
6723 [(match_operand 0 "" "") (match_operand 1 "" "")]
6727 rtx gotoffsym, insn;
6728 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6730 gotoffsym = gen_sym2GOTOFF (operands[1]);
6731 PUT_MODE (gotoffsym, Pmode);
6732 emit_move_insn (t, gotoffsym);
6733 insn = emit_move_insn (operands[0],
6734 gen_rtx_PLUS (Pmode, t,
6735 gen_rtx_REG (Pmode, PIC_REG)));
6737 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6743 (define_expand "symPLT_label2reg"
6744 [(set (match_operand:SI 0 "" "")
6747 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6751 (match_operand:SI 2 "" "")
6753 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6754 ;; Even though the PIC register is not really used by the call
6755 ;; sequence in which this is expanded, the PLT code assumes the PIC
6756 ;; register is set, so we must not skip its initialization. Since
6757 ;; we only use this expand as part of calling sequences, and never
6758 ;; to take the address of a function, this is the best point to
6759 ;; insert the (use). Using the PLT to take the address of a
6760 ;; function would be wrong, not only because the PLT entry could
6761 ;; then be called from a function that doesn't initialize the PIC
6762 ;; register to the proper GOT, but also because pointers to the
6763 ;; same function might not compare equal, should they be set by
6764 ;; different shared libraries.
6765 (use (reg:SI PIC_REG))]
6769 (define_expand "sym2PIC"
6770 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6774 ;; TLS code generation.
6775 ;; ??? this should be a define_insn_and_split
6776 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6777 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6780 (define_insn "tls_global_dynamic"
6781 [(set (match_operand:SI 0 "register_operand" "=&z")
6782 (call (unspec:SI [(match_operand:SI 1 "" "")]
6785 (use (reg:PSI FPSCR_REG))
6786 (use (reg:SI PIC_REG))
6787 (clobber (reg:SI PR_REG))
6788 (clobber (scratch:SI))]
6794 \\tmova\\t2f,r0\\n\\
6795 \\tmov.l\\t2f,r1\\n\\
6798 \\tadd\\tr12,r4\\n\\
6802 1:\\t.long\\t%a1@TLSGD\\n\\
6803 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6806 [(set_attr "type" "tls_load")
6807 (set_attr "length" "26")])
6809 (define_insn "tls_local_dynamic"
6810 [(set (match_operand:SI 0 "register_operand" "=&z")
6811 (call (unspec:SI [(match_operand:SI 1 "" "")]
6814 (use (reg:PSI FPSCR_REG))
6815 (use (reg:SI PIC_REG))
6816 (clobber (reg:SI PR_REG))
6817 (clobber (scratch:SI))]
6823 \\tmova\\t2f,r0\\n\\
6824 \\tmov.l\\t2f,r1\\n\\
6827 \\tadd\\tr12,r4\\n\\
6831 1:\\t.long\\t%a1@TLSLDM\\n\\
6832 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6835 [(set_attr "type" "tls_load")
6836 (set_attr "length" "26")])
6838 (define_expand "sym2DTPOFF"
6839 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6843 (define_expand "symDTPOFF2reg"
6844 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6848 rtx dtpoffsym, insn;
6849 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6851 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6852 PUT_MODE (dtpoffsym, Pmode);
6853 emit_move_insn (t, dtpoffsym);
6854 insn = emit_move_insn (operands[0],
6855 gen_rtx_PLUS (Pmode, t, operands[2]));
6859 (define_expand "sym2GOTTPOFF"
6860 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6864 (define_insn "tls_initial_exec"
6865 [(set (match_operand:SI 0 "register_operand" "=&r")
6866 (unspec:SI [(match_operand:SI 1 "" "")]
6868 (use (reg:SI GBR_REG))
6869 (use (reg:SI PIC_REG))
6870 (clobber (reg:SI R0_REG))]
6876 \\tstc\\tgbr,%0\\n\\
6877 \\tmov.l\\t@(r0,r12),r0\\n\\
6881 1:\\t.long\\t%a1\\n\\
6884 [(set_attr "type" "tls_load")
6885 (set_attr "length" "16")])
6887 (define_expand "sym2TPOFF"
6888 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6892 (define_expand "symTPOFF2reg"
6893 [(match_operand 0 "" "") (match_operand 1 "" "")]
6899 tpoffsym = gen_sym2TPOFF (operands[1]);
6900 PUT_MODE (tpoffsym, Pmode);
6901 insn = emit_move_insn (operands[0], tpoffsym);
6905 (define_insn "load_gbr"
6906 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6907 (use (reg:SI GBR_REG))]
6910 [(set_attr "type" "tls_load")])
6912 ;; case instruction for switch statements.
6914 ;; Operand 0 is index
6915 ;; operand 1 is the minimum bound
6916 ;; operand 2 is the maximum bound - minimum bound + 1
6917 ;; operand 3 is CODE_LABEL for the table;
6918 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6920 (define_expand "casesi"
6921 [(match_operand:SI 0 "arith_reg_operand" "")
6922 (match_operand:SI 1 "arith_reg_operand" "")
6923 (match_operand:SI 2 "arith_reg_operand" "")
6924 (match_operand 3 "" "") (match_operand 4 "" "")]
6928 rtx reg = gen_reg_rtx (SImode);
6929 rtx reg2 = gen_reg_rtx (SImode);
6932 rtx reg = gen_reg_rtx (DImode);
6933 rtx reg2 = gen_reg_rtx (DImode);
6934 rtx reg3 = gen_reg_rtx (DImode);
6935 rtx reg4 = gen_reg_rtx (DImode);
6936 rtx reg5 = gen_reg_rtx (DImode);
6938 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6939 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6940 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6942 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6943 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6944 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6945 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6946 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6947 (DImode, operands[3])));
6948 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6949 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6950 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6954 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6955 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6956 /* If optimizing, casesi_worker depends on the mode of the instruction
6957 before label it 'uses' - operands[3]. */
6958 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6960 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6962 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6964 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6965 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6966 operands[3], but to lab. We will fix this up in
6967 machine_dependent_reorg. */
6972 (define_expand "casesi_0"
6973 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6974 (set (match_dup 4) (minus:SI (match_dup 4)
6975 (match_operand:SI 1 "arith_operand" "")))
6977 (gtu:SI (match_dup 4)
6978 (match_operand:SI 2 "arith_reg_operand" "")))
6980 (if_then_else (ne (reg:SI T_REG)
6982 (label_ref (match_operand 3 "" ""))
6987 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6988 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6989 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6991 (define_insn "casesi_worker_0"
6992 [(set (match_operand:SI 0 "register_operand" "=r,r")
6993 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6994 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6995 (clobber (match_scratch:SI 3 "=X,1"))
6996 (clobber (match_scratch:SI 4 "=&z,z"))]
7001 [(set (match_operand:SI 0 "register_operand" "")
7002 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7003 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7004 (clobber (match_scratch:SI 3 ""))
7005 (clobber (match_scratch:SI 4 ""))]
7006 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7007 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7008 (parallel [(set (match_dup 0)
7009 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7010 (label_ref (match_dup 2))] UNSPEC_CASESI))
7011 (clobber (match_dup 3))])
7012 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7013 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7016 [(set (match_operand:SI 0 "register_operand" "")
7017 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7018 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7019 (clobber (match_scratch:SI 3 ""))
7020 (clobber (match_scratch:SI 4 ""))]
7021 "TARGET_SH2 && reload_completed"
7022 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7023 (parallel [(set (match_dup 0)
7024 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7025 (label_ref (match_dup 2))] UNSPEC_CASESI))
7026 (clobber (match_dup 3))])]
7027 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7029 (define_insn "casesi_worker_1"
7030 [(set (match_operand:SI 0 "register_operand" "=r,r")
7031 (unspec:SI [(reg:SI R0_REG)
7032 (match_operand:SI 1 "register_operand" "0,r")
7033 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7034 (clobber (match_scratch:SI 3 "=X,1"))]
7038 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7040 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7043 switch (GET_MODE (diff_vec))
7046 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7048 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7050 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7051 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7052 return \"mov.b @(r0,%1),%0\";
7057 [(set_attr "length" "4")])
7059 (define_insn "casesi_worker_2"
7060 [(set (match_operand:SI 0 "register_operand" "=r,r")
7061 (unspec:SI [(reg:SI R0_REG)
7062 (match_operand:SI 1 "register_operand" "0,r")
7063 (label_ref (match_operand 2 "" ""))
7064 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7065 (clobber (match_operand:SI 4 "" "=X,1"))]
7066 "TARGET_SH2 && reload_completed && flag_pic"
7069 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7072 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7075 switch (GET_MODE (diff_vec))
7078 output_asm_insn (\"shll2 %1\", operands);
7079 load = \"mov.l @(r0,%1),%0\"; break;
7081 output_asm_insn (\"add %1,%1\", operands);
7082 load = \"mov.w @(r0,%1),%0\"; break;
7084 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7085 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7087 load = \"mov.b @(r0,%1),%0\";
7092 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7095 [(set_attr "length" "8")])
7097 (define_insn "casesi_shift_media"
7098 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7099 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7100 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7105 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7107 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7110 switch (GET_MODE (diff_vec))
7113 return \"shlli %1, 2, %0\";
7115 return \"shlli %1, 1, %0\";
7117 if (rtx_equal_p (operands[0], operands[1]))
7119 return \"add %1, r63, %0\";
7124 [(set_attr "type" "arith_media")])
7126 (define_insn "casesi_load_media"
7127 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7128 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7129 (match_operand 2 "arith_reg_operand" "r")
7130 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7134 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7136 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7139 switch (GET_MODE (diff_vec))
7142 return \"ldx.l %1, %2, %0\";
7145 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7146 return \"ldx.uw %1, %2, %0\";
7148 return \"ldx.w %1, %2, %0\";
7150 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7151 return \"ldx.ub %1, %2, %0\";
7152 return \"ldx.b %1, %2, %0\";
7157 [(set_attr "type" "load_media")])
7159 (define_expand "return"
7161 "reload_completed && ! sh_need_epilogue ()"
7166 emit_jump_insn (gen_return_media ());
7170 if (TARGET_SHCOMPACT
7171 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7173 emit_jump_insn (gen_shcompact_return_tramp ());
7178 (define_insn "*return_i"
7180 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7181 && (current_function_args_info.call_cookie
7182 & CALL_COOKIE_RET_TRAMP (1)))
7183 && reload_completed"
7185 [(set_attr "type" "return")
7186 (set_attr "needs_delay_slot" "yes")])
7188 (define_expand "shcompact_return_tramp"
7191 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7194 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7195 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7198 emit_insn (gen_symGOTPLT2reg (reg, sym));
7200 emit_move_insn (reg, sym);
7202 emit_jump_insn (gen_shcompact_return_tramp_i ());
7206 (define_insn "shcompact_return_tramp_i"
7207 [(parallel [(return) (use (reg:SI R0_REG))])]
7209 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7211 [(set_attr "type" "jump_ind")
7212 (set_attr "needs_delay_slot" "yes")])
7214 (define_insn "return_media_i"
7215 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7216 "TARGET_SHMEDIA && reload_completed"
7218 [(set_attr "type" "jump_media")])
7220 (define_insn "return_media_rte"
7222 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7224 [(set_attr "type" "jump_media")])
7226 (define_expand "return_media"
7228 "TARGET_SHMEDIA && reload_completed"
7231 int tr_regno = sh_media_register_for_return ();
7234 if (current_function_interrupt)
7236 emit_jump_insn (gen_return_media_rte ());
7241 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7243 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7246 tr = gen_rtx_REG (DImode, tr_regno);
7247 emit_move_insn (tr, r18);
7250 tr = gen_rtx_REG (DImode, tr_regno);
7252 emit_jump_insn (gen_return_media_i (tr));
7256 (define_insn "shcompact_preserve_incoming_args"
7257 [(set (match_operand:SI 0 "register_operand" "+r")
7258 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7261 [(set_attr "length" "0")])
7263 (define_insn "shcompact_incoming_args"
7264 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7265 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7266 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7267 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7268 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7269 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7270 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7271 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7272 (set (mem:BLK (reg:SI MACL_REG))
7273 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7274 (use (reg:SI R0_REG))
7275 (clobber (reg:SI R0_REG))
7276 (clobber (reg:SI MACL_REG))
7277 (clobber (reg:SI MACH_REG))
7278 (clobber (reg:SI PR_REG))]
7281 [(set_attr "needs_delay_slot" "yes")])
7283 (define_insn "shmedia_save_restore_regs_compact"
7284 [(set (reg:SI SP_REG)
7285 (plus:SI (reg:SI SP_REG)
7286 (match_operand:SI 0 "immediate_operand" "i")))
7287 (use (reg:SI R0_REG))
7288 (clobber (reg:SI PR_REG))]
7290 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7291 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7293 [(set_attr "needs_delay_slot" "yes")])
7295 (define_expand "prologue"
7298 "sh_expand_prologue (); DONE;")
7300 (define_expand "epilogue"
7305 sh_expand_epilogue (0);
7306 emit_jump_insn (gen_return ());
7310 (define_expand "eh_return"
7311 [(use (match_operand 0 "register_operand" ""))]
7314 rtx ra = operands[0];
7316 if (TARGET_SHMEDIA64)
7317 emit_insn (gen_eh_set_ra_di (ra));
7319 emit_insn (gen_eh_set_ra_si (ra));
7324 ;; Clobber the return address on the stack. We can't expand this
7325 ;; until we know where it will be put in the stack frame.
7327 (define_insn "eh_set_ra_si"
7328 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7329 (clobber (match_scratch:SI 1 "=&r"))]
7330 "! TARGET_SHMEDIA64"
7333 (define_insn "eh_set_ra_di"
7334 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7335 (clobber (match_scratch:DI 1 "=&r"))]
7340 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7341 (clobber (match_scratch 1 ""))]
7346 sh_set_return_address (operands[0], operands[1]);
7350 (define_insn "blockage"
7351 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7354 [(set_attr "length" "0")])
7356 ;; ------------------------------------------------------------------------
7358 ;; ------------------------------------------------------------------------
7361 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7362 (eq:SI (reg:SI T_REG) (const_int 1)))]
7365 [(set_attr "type" "arith")])
7367 (define_expand "seq"
7368 [(set (match_operand:SI 0 "arith_reg_operand" "")
7375 if (GET_MODE (operands[0]) != DImode)
7376 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7377 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7378 if (sh_compare_op1 != const0_rtx)
7379 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7380 ? GET_MODE (sh_compare_op0)
7381 : GET_MODE (sh_compare_op1),
7384 switch (GET_MODE (sh_compare_op0))
7387 emit_insn (gen_cmpeqdi_media (operands[0],
7388 sh_compare_op0, sh_compare_op1));
7392 if (! TARGET_SHMEDIA_FPU)
7394 emit_insn (gen_cmpeqsf_media (operands[0],
7395 sh_compare_op0, sh_compare_op1));
7399 if (! TARGET_SHMEDIA_FPU)
7401 emit_insn (gen_cmpeqdf_media (operands[0],
7402 sh_compare_op0, sh_compare_op1));
7410 if (sh_expand_t_scc (EQ, operands[0]))
7412 if (! rtx_equal_function_value_matters)
7414 operands[1] = prepare_scc_operands (EQ);
7417 (define_expand "slt"
7418 [(set (match_operand:SI 0 "arith_reg_operand" "")
7425 if (GET_MODE (operands[0]) != DImode)
7426 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7427 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7428 if (sh_compare_op1 != const0_rtx)
7429 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7430 ? GET_MODE (sh_compare_op0)
7431 : GET_MODE (sh_compare_op1),
7434 switch (GET_MODE (sh_compare_op0))
7437 emit_insn (gen_cmpgtdi_media (operands[0],
7438 sh_compare_op1, sh_compare_op0));
7442 if (! TARGET_SHMEDIA_FPU)
7444 emit_insn (gen_cmpgtsf_media (operands[0],
7445 sh_compare_op1, sh_compare_op0));
7449 if (! TARGET_SHMEDIA_FPU)
7451 emit_insn (gen_cmpgtdf_media (operands[0],
7452 sh_compare_op1, sh_compare_op0));
7460 if (! rtx_equal_function_value_matters)
7462 operands[1] = prepare_scc_operands (LT);
7465 (define_expand "sle"
7466 [(match_operand:SI 0 "arith_reg_operand" "")]
7470 rtx tmp = sh_compare_op0;
7474 if (GET_MODE (operands[0]) != DImode)
7475 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7476 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7477 if (sh_compare_op1 != const0_rtx)
7478 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7479 ? GET_MODE (sh_compare_op0)
7480 : GET_MODE (sh_compare_op1),
7483 switch (GET_MODE (sh_compare_op0))
7487 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7489 emit_insn (gen_cmpgtdi_media (tmp,
7490 sh_compare_op0, sh_compare_op1));
7491 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7496 if (! TARGET_SHMEDIA_FPU)
7498 emit_insn (gen_cmpgesf_media (operands[0],
7499 sh_compare_op1, sh_compare_op0));
7503 if (! TARGET_SHMEDIA_FPU)
7505 emit_insn (gen_cmpgedf_media (operands[0],
7506 sh_compare_op1, sh_compare_op0));
7515 sh_compare_op0 = sh_compare_op1;
7516 sh_compare_op1 = tmp;
7517 emit_insn (gen_sge (operands[0]));
7521 (define_expand "sgt"
7522 [(set (match_operand:SI 0 "arith_reg_operand" "")
7529 if (GET_MODE (operands[0]) != DImode)
7530 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7531 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7532 if (sh_compare_op1 != const0_rtx)
7533 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7534 ? GET_MODE (sh_compare_op0)
7535 : GET_MODE (sh_compare_op1),
7538 switch (GET_MODE (sh_compare_op0))
7541 emit_insn (gen_cmpgtdi_media (operands[0],
7542 sh_compare_op0, sh_compare_op1));
7546 if (! TARGET_SHMEDIA_FPU)
7548 emit_insn (gen_cmpgtsf_media (operands[0],
7549 sh_compare_op0, sh_compare_op1));
7553 if (! TARGET_SHMEDIA_FPU)
7555 emit_insn (gen_cmpgtdf_media (operands[0],
7556 sh_compare_op0, sh_compare_op1));
7564 if (! rtx_equal_function_value_matters)
7566 operands[1] = prepare_scc_operands (GT);
7569 (define_expand "sge"
7570 [(set (match_operand:SI 0 "arith_reg_operand" "")
7577 if (GET_MODE (operands[0]) != DImode)
7578 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7579 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7580 if (sh_compare_op1 != const0_rtx)
7581 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7582 ? GET_MODE (sh_compare_op0)
7583 : GET_MODE (sh_compare_op1),
7586 switch (GET_MODE (sh_compare_op0))
7590 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7592 emit_insn (gen_cmpgtdi_media (tmp,
7593 sh_compare_op1, sh_compare_op0));
7594 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7599 if (! TARGET_SHMEDIA_FPU)
7601 emit_insn (gen_cmpgesf_media (operands[0],
7602 sh_compare_op0, sh_compare_op1));
7606 if (! TARGET_SHMEDIA_FPU)
7608 emit_insn (gen_cmpgedf_media (operands[0],
7609 sh_compare_op0, sh_compare_op1));
7618 if (! rtx_equal_function_value_matters)
7620 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7624 rtx lab = gen_label_rtx ();
7625 prepare_scc_operands (EQ);
7626 emit_jump_insn (gen_branch_true (lab));
7627 prepare_scc_operands (GT);
7629 emit_insn (gen_movt (operands[0]));
7632 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7635 operands[1] = prepare_scc_operands (GE);
7638 (define_expand "sgtu"
7639 [(set (match_operand:SI 0 "arith_reg_operand" "")
7646 if (GET_MODE (operands[0]) != DImode)
7647 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7648 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7649 if (sh_compare_op1 != const0_rtx)
7650 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7651 ? GET_MODE (sh_compare_op0)
7652 : GET_MODE (sh_compare_op1),
7655 emit_insn (gen_cmpgtudi_media (operands[0],
7656 sh_compare_op0, sh_compare_op1));
7659 if (! rtx_equal_function_value_matters)
7661 operands[1] = prepare_scc_operands (GTU);
7664 (define_expand "sltu"
7665 [(set (match_operand:SI 0 "arith_reg_operand" "")
7672 if (GET_MODE (operands[0]) != DImode)
7673 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7674 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7675 if (sh_compare_op1 != const0_rtx)
7676 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7677 ? GET_MODE (sh_compare_op0)
7678 : GET_MODE (sh_compare_op1),
7681 emit_insn (gen_cmpgtudi_media (operands[0],
7682 sh_compare_op1, sh_compare_op0));
7685 if (! rtx_equal_function_value_matters)
7687 operands[1] = prepare_scc_operands (LTU);
7690 (define_expand "sleu"
7691 [(set (match_operand:SI 0 "arith_reg_operand" "")
7700 if (GET_MODE (operands[0]) != DImode)
7701 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7702 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7703 if (sh_compare_op1 != const0_rtx)
7704 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7705 ? GET_MODE (sh_compare_op0)
7706 : GET_MODE (sh_compare_op1),
7709 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7711 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7712 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7716 if (! rtx_equal_function_value_matters)
7718 operands[1] = prepare_scc_operands (LEU);
7721 (define_expand "sgeu"
7722 [(set (match_operand:SI 0 "arith_reg_operand" "")
7731 if (GET_MODE (operands[0]) != DImode)
7732 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7733 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7734 if (sh_compare_op1 != const0_rtx)
7735 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7736 ? GET_MODE (sh_compare_op0)
7737 : GET_MODE (sh_compare_op1),
7740 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7742 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7743 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7748 if (! rtx_equal_function_value_matters)
7750 operands[1] = prepare_scc_operands (GEU);
7753 ;; sne moves the complement of the T reg to DEST like this:
7757 ;; This is better than xoring compare result with 1 because it does
7758 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7761 (define_expand "sne"
7762 [(set (match_dup 2) (const_int -1))
7763 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7764 (neg:SI (plus:SI (match_dup 1)
7767 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7776 if (GET_MODE (operands[0]) != DImode)
7777 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7779 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7782 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7783 if (sh_compare_op1 != const0_rtx)
7784 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7785 ? GET_MODE (sh_compare_op0)
7786 : GET_MODE (sh_compare_op1),
7789 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7791 emit_insn (gen_seq (tmp));
7792 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7797 if (sh_expand_t_scc (NE, operands[0]))
7799 if (! rtx_equal_function_value_matters)
7801 operands[1] = prepare_scc_operands (EQ);
7802 operands[2] = gen_reg_rtx (SImode);
7805 (define_expand "sunordered"
7806 [(set (match_operand:DI 0 "arith_reg_operand" "")
7807 (unordered:DI (match_dup 1) (match_dup 2)))]
7808 "TARGET_SHMEDIA_FPU"
7811 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7812 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7815 ;; Use the same trick for FP sle / sge
7816 (define_expand "movnegt"
7817 [(set (match_dup 2) (const_int -1))
7818 (parallel [(set (match_operand 0 "" "")
7819 (neg:SI (plus:SI (match_dup 1)
7822 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7825 "operands[2] = gen_reg_rtx (SImode);")
7827 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7828 ;; This prevents a regression that occurred when we switched from xor to
7832 [(set (match_operand:SI 0 "arith_reg_operand" "")
7833 (plus:SI (reg:SI T_REG)
7836 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7837 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7840 ;; -------------------------------------------------------------------------
7841 ;; Instructions to cope with inline literal tables
7842 ;; -------------------------------------------------------------------------
7844 ; 2 byte integer in line
7846 (define_insn "consttable_2"
7847 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7848 (match_operand 1 "" "")]
7853 if (operands[1] != const0_rtx)
7854 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7857 [(set_attr "length" "2")
7858 (set_attr "in_delay_slot" "no")])
7860 ; 4 byte integer in line
7862 (define_insn "consttable_4"
7863 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7864 (match_operand 1 "" "")]
7869 if (operands[1] != const0_rtx)
7870 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7873 [(set_attr "length" "4")
7874 (set_attr "in_delay_slot" "no")])
7876 ; 8 byte integer in line
7878 (define_insn "consttable_8"
7879 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7880 (match_operand 1 "" "")]
7885 if (operands[1] != const0_rtx)
7886 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7889 [(set_attr "length" "8")
7890 (set_attr "in_delay_slot" "no")])
7892 ; 4 byte floating point
7894 (define_insn "consttable_sf"
7895 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7896 (match_operand 1 "" "")]
7901 if (operands[1] != const0_rtx)
7904 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7905 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7909 [(set_attr "length" "4")
7910 (set_attr "in_delay_slot" "no")])
7912 ; 8 byte floating point
7914 (define_insn "consttable_df"
7915 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7916 (match_operand 1 "" "")]
7921 if (operands[1] != const0_rtx)
7924 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7925 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7929 [(set_attr "length" "8")
7930 (set_attr "in_delay_slot" "no")])
7932 ;; Alignment is needed for some constant tables; it may also be added for
7933 ;; Instructions at the start of loops, or after unconditional branches.
7934 ;; ??? We would get more accurate lengths if we did instruction
7935 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7936 ;; here is too conservative.
7938 ; align to a two byte boundary
7940 (define_expand "align_2"
7941 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7945 ; align to a four byte boundary
7946 ;; align_4 and align_log are instructions for the starts of loops, or
7947 ;; after unconditional branches, which may take up extra room.
7949 (define_expand "align_4"
7950 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7954 ; align to a cache line boundary
7956 (define_insn "align_log"
7957 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7960 [(set_attr "length" "0")
7961 (set_attr "in_delay_slot" "no")])
7963 ; emitted at the end of the literal table, used to emit the
7964 ; 32bit branch labels if needed.
7966 (define_insn "consttable_end"
7967 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7969 "* return output_jump_label_table ();"
7970 [(set_attr "in_delay_slot" "no")])
7972 ; emitted at the end of the window in the literal table.
7974 (define_insn "consttable_window_end"
7975 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7978 [(set_attr "length" "0")
7979 (set_attr "in_delay_slot" "no")])
7981 ;; -------------------------------------------------------------------------
7983 ;; -------------------------------------------------------------------------
7985 ;; String/block move insn.
7987 (define_expand "movmemsi"
7988 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7989 (mem:BLK (match_operand:BLK 1 "" "")))
7990 (use (match_operand:SI 2 "nonmemory_operand" ""))
7991 (use (match_operand:SI 3 "immediate_operand" ""))
7992 (clobber (reg:SI PR_REG))
7993 (clobber (reg:SI R4_REG))
7994 (clobber (reg:SI R5_REG))
7995 (clobber (reg:SI R0_REG))])]
7996 "TARGET_SH1 && ! TARGET_SH5"
7999 if(expand_block_move (operands))
8004 (define_insn "block_move_real"
8005 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8006 (mem:BLK (reg:SI R5_REG)))
8007 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8008 (clobber (reg:SI PR_REG))
8009 (clobber (reg:SI R0_REG))])]
8010 "TARGET_SH1 && ! TARGET_HARD_SH4"
8012 [(set_attr "type" "sfunc")
8013 (set_attr "needs_delay_slot" "yes")])
8015 (define_insn "block_lump_real"
8016 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8017 (mem:BLK (reg:SI R5_REG)))
8018 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8019 (use (reg:SI R6_REG))
8020 (clobber (reg:SI PR_REG))
8021 (clobber (reg:SI T_REG))
8022 (clobber (reg:SI R4_REG))
8023 (clobber (reg:SI R5_REG))
8024 (clobber (reg:SI R6_REG))
8025 (clobber (reg:SI R0_REG))])]
8026 "TARGET_SH1 && ! TARGET_HARD_SH4"
8028 [(set_attr "type" "sfunc")
8029 (set_attr "needs_delay_slot" "yes")])
8031 (define_insn "block_move_real_i4"
8032 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8033 (mem:BLK (reg:SI R5_REG)))
8034 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8035 (clobber (reg:SI PR_REG))
8036 (clobber (reg:SI R0_REG))
8037 (clobber (reg:SI R1_REG))
8038 (clobber (reg:SI R2_REG))])]
8041 [(set_attr "type" "sfunc")
8042 (set_attr "needs_delay_slot" "yes")])
8044 (define_insn "block_lump_real_i4"
8045 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8046 (mem:BLK (reg:SI R5_REG)))
8047 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8048 (use (reg:SI R6_REG))
8049 (clobber (reg:SI PR_REG))
8050 (clobber (reg:SI T_REG))
8051 (clobber (reg:SI R4_REG))
8052 (clobber (reg:SI R5_REG))
8053 (clobber (reg:SI R6_REG))
8054 (clobber (reg:SI R0_REG))
8055 (clobber (reg:SI R1_REG))
8056 (clobber (reg:SI R2_REG))
8057 (clobber (reg:SI R3_REG))])]
8060 [(set_attr "type" "sfunc")
8061 (set_attr "needs_delay_slot" "yes")])
8063 ;; -------------------------------------------------------------------------
8064 ;; Floating point instructions.
8065 ;; -------------------------------------------------------------------------
8067 ;; ??? All patterns should have a type attribute.
8069 (define_expand "fpu_switch0"
8070 [(set (match_operand:SI 0 "" "") (match_dup 2))
8071 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8075 operands[1] = get_fpscr_rtx ();
8076 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8078 operands[2] = legitimize_pic_address (operands[2], SImode,
8079 no_new_pseudos ? operands[0] : 0);
8082 (define_expand "fpu_switch1"
8083 [(set (match_operand:SI 0 "" "") (match_dup 2))
8084 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8085 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8089 operands[1] = get_fpscr_rtx ();
8090 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8092 operands[2] = legitimize_pic_address (operands[2], SImode,
8093 no_new_pseudos ? operands[0] : 0);
8094 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8097 (define_expand "movpsi"
8098 [(set (match_operand:PSI 0 "register_operand" "")
8099 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8103 ;; The c / m alternative is a fake to guide reload to load directly into
8104 ;; fpscr, since reload doesn't know how to use post-increment.
8105 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8106 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8107 ;; predicate after reload.
8108 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8109 ;; like a mac -> gpr move.
8110 (define_insn "fpu_switch"
8111 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8112 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8114 && (! reload_completed
8115 || true_regnum (operands[0]) != FPSCR_REG
8116 || GET_CODE (operands[1]) != MEM
8117 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8119 ! precision stays the same
8128 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8129 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8132 [(set (reg:PSI FPSCR_REG)
8133 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8134 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8135 [(set (match_dup 0) (match_dup 0))]
8138 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8139 gen_rtx_MEM (PSImode,
8140 gen_rtx_POST_INC (Pmode,
8142 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8146 [(set (reg:PSI FPSCR_REG)
8147 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8149 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8152 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8153 gen_rtx_MEM (PSImode,
8154 gen_rtx_POST_INC (Pmode,
8156 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8159 ;; ??? This uses the fp unit, but has no type indicating that.
8160 ;; If we did that, this would either give a bogus latency or introduce
8161 ;; a bogus FIFO constraint.
8162 ;; Since this insn is currently only used for prologues/epilogues,
8163 ;; it is probably best to claim no function unit, which matches the
8165 (define_insn "toggle_sz"
8166 [(set (reg:PSI FPSCR_REG)
8167 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8170 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8172 ;; There's no way we can use it today, since optimize mode switching
8173 ;; doesn't enable us to know from which mode we're switching to the
8174 ;; mode it requests, to tell whether we can use a relative mode switch
8175 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8177 (define_insn "toggle_pr"
8178 [(set (reg:PSI FPSCR_REG)
8179 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8180 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8182 [(set_attr "type" "fp")])
8184 (define_expand "addsf3"
8185 [(set (match_operand:SF 0 "arith_reg_operand" "")
8186 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8187 (match_operand:SF 2 "arith_reg_operand" "")))]
8188 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8193 expand_sf_binop (&gen_addsf3_i, operands);
8198 (define_insn "*addsf3_media"
8199 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8200 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8201 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8202 "TARGET_SHMEDIA_FPU"
8204 [(set_attr "type" "fparith_media")])
8206 (define_insn_and_split "unary_sf_op"
8207 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8212 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8213 (match_operator:SF 2 "unary_float_operator"
8214 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8215 (parallel [(match_operand 4
8216 "const_int_operand" "n")]))]))
8217 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8218 "TARGET_SHMEDIA_FPU"
8220 "TARGET_SHMEDIA_FPU && reload_completed"
8221 [(set (match_dup 5) (match_dup 6))]
8224 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8225 rtx op1 = gen_rtx_REG (SFmode,
8226 (true_regnum (operands[1])
8227 + (INTVAL (operands[4]) ^ endian)));
8229 operands[7] = gen_rtx_REG (SFmode,
8230 (true_regnum (operands[0])
8231 + (INTVAL (operands[3]) ^ endian)));
8232 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8234 [(set_attr "type" "fparith_media")])
8236 (define_insn_and_split "binary_sf_op"
8237 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8242 (parallel [(match_operand 7 "const_int_operand" "n")]))
8243 (match_operator:SF 3 "binary_float_operator"
8244 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8245 (parallel [(match_operand 5
8246 "const_int_operand" "n")]))
8247 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8248 (parallel [(match_operand 6
8249 "const_int_operand" "n")]))]))
8250 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8251 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8253 "&& reload_completed"
8254 [(set (match_dup 8) (match_dup 9))]
8257 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8258 rtx op1 = gen_rtx_REG (SFmode,
8259 (true_regnum (operands[1])
8260 + (INTVAL (operands[5]) ^ endian)));
8261 rtx op2 = gen_rtx_REG (SFmode,
8262 (true_regnum (operands[2])
8263 + (INTVAL (operands[6]) ^ endian)));
8265 operands[8] = gen_rtx_REG (SFmode,
8266 (true_regnum (operands[0])
8267 + (INTVAL (operands[4]) ^ endian)));
8268 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8270 [(set_attr "type" "fparith_media")])
8272 (define_insn "addsf3_i"
8273 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8274 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8275 (match_operand:SF 2 "arith_reg_operand" "f")))
8276 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8279 [(set_attr "type" "fp")
8280 (set_attr "fp_mode" "single")])
8282 (define_expand "subsf3"
8283 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8284 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8285 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8286 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8291 expand_sf_binop (&gen_subsf3_i, operands);
8296 (define_insn "*subsf3_media"
8297 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8298 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8299 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8300 "TARGET_SHMEDIA_FPU"
8302 [(set_attr "type" "fparith_media")])
8304 (define_insn "subsf3_i"
8305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8306 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8307 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8308 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8311 [(set_attr "type" "fp")
8312 (set_attr "fp_mode" "single")])
8314 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8315 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8316 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8317 ;; SH3E, we use a separate insn for SH3E mulsf3.
8319 (define_expand "mulsf3"
8320 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8321 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8322 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8323 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8327 expand_sf_binop (&gen_mulsf3_i4, operands);
8328 else if (TARGET_SH2E)
8329 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8330 if (! TARGET_SHMEDIA)
8334 (define_insn "*mulsf3_media"
8335 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8336 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8337 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8338 "TARGET_SHMEDIA_FPU"
8340 [(set_attr "type" "fparith_media")])
8342 (define_insn "mulsf3_i4"
8343 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8344 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8345 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8346 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8349 [(set_attr "type" "fp")
8350 (set_attr "fp_mode" "single")])
8352 (define_insn "mulsf3_ie"
8353 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8354 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8355 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8356 "TARGET_SH2E && ! TARGET_SH4"
8358 [(set_attr "type" "fp")])
8360 (define_insn "*mac_media"
8361 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8362 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8363 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8364 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8365 "TARGET_SHMEDIA_FPU"
8367 [(set_attr "type" "fparith_media")])
8369 (define_insn "*macsf3"
8370 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8371 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8372 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8373 (match_operand:SF 3 "arith_reg_operand" "0")))
8374 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8375 "TARGET_SH2E && ! TARGET_SH4"
8377 [(set_attr "type" "fp")
8378 (set_attr "fp_mode" "single")])
8380 (define_expand "divsf3"
8381 [(set (match_operand:SF 0 "arith_reg_operand" "")
8382 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8383 (match_operand:SF 2 "arith_reg_operand" "")))]
8384 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8389 expand_sf_binop (&gen_divsf3_i, operands);
8394 (define_insn "*divsf3_media"
8395 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8396 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8397 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8398 "TARGET_SHMEDIA_FPU"
8400 [(set_attr "type" "fdiv_media")])
8402 (define_insn "divsf3_i"
8403 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8404 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8405 (match_operand:SF 2 "arith_reg_operand" "f")))
8406 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8409 [(set_attr "type" "fdiv")
8410 (set_attr "fp_mode" "single")])
8412 (define_insn "floatdisf2"
8413 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8414 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8415 "TARGET_SHMEDIA_FPU"
8417 [(set_attr "type" "fpconv_media")])
8419 (define_expand "floatsisf2"
8420 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8421 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8422 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8427 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8432 (define_insn "*floatsisf2_media"
8433 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8434 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8435 "TARGET_SHMEDIA_FPU"
8437 [(set_attr "type" "fpconv_media")])
8439 (define_insn "floatsisf2_i4"
8440 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8441 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8442 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8445 [(set_attr "type" "fp")
8446 (set_attr "fp_mode" "single")])
8448 (define_insn "*floatsisf2_ie"
8449 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8450 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8451 "TARGET_SH2E && ! TARGET_SH4"
8453 [(set_attr "type" "fp")])
8455 (define_insn "fix_truncsfdi2"
8456 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8457 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8458 "TARGET_SHMEDIA_FPU"
8460 [(set_attr "type" "fpconv_media")])
8462 (define_expand "fix_truncsfsi2"
8463 [(set (match_operand:SI 0 "fpul_operand" "=y")
8464 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8465 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8470 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8475 (define_insn "*fix_truncsfsi2_media"
8476 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8477 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8478 "TARGET_SHMEDIA_FPU"
8480 [(set_attr "type" "fpconv_media")])
8482 (define_insn "fix_truncsfsi2_i4"
8483 [(set (match_operand:SI 0 "fpul_operand" "=y")
8484 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8485 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8488 [(set_attr "type" "ftrc_s")
8489 (set_attr "fp_mode" "single")])
8491 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8492 ;; fix_truncsfsi2_i4.
8493 ;; (define_insn "fix_truncsfsi2_i4_2"
8494 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8495 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8496 ;; (use (reg:PSI FPSCR_REG))
8497 ;; (clobber (reg:SI FPUL_REG))]
8500 ;; [(set_attr "length" "4")
8501 ;; (set_attr "fp_mode" "single")])
8504 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8505 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8506 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8507 ;; (clobber (reg:SI FPUL_REG))]
8509 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8510 ;; (use (match_dup 2))])
8511 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8513 (define_insn "*fixsfsi"
8514 [(set (match_operand:SI 0 "fpul_operand" "=y")
8515 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8516 "TARGET_SH2E && ! TARGET_SH4"
8518 [(set_attr "type" "fp")])
8520 (define_insn "cmpgtsf_t"
8521 [(set (reg:SI T_REG)
8522 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8523 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8524 "TARGET_SH2E && ! TARGET_SH4"
8526 [(set_attr "type" "fp")
8527 (set_attr "fp_mode" "single")])
8529 (define_insn "cmpeqsf_t"
8530 [(set (reg:SI T_REG)
8531 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8532 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8533 "TARGET_SH2E && ! TARGET_SH4"
8535 [(set_attr "type" "fp")
8536 (set_attr "fp_mode" "single")])
8538 (define_insn "ieee_ccmpeqsf_t"
8539 [(set (reg:SI T_REG)
8540 (ior:SI (reg:SI T_REG)
8541 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8542 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8543 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8544 "* return output_ieee_ccmpeq (insn, operands);"
8545 [(set_attr "length" "4")])
8548 (define_insn "cmpgtsf_t_i4"
8549 [(set (reg:SI T_REG)
8550 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8551 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8552 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8555 [(set_attr "type" "fp")
8556 (set_attr "fp_mode" "single")])
8558 (define_insn "cmpeqsf_t_i4"
8559 [(set (reg:SI T_REG)
8560 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8561 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8562 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8565 [(set_attr "type" "fp")
8566 (set_attr "fp_mode" "single")])
8568 (define_insn "*ieee_ccmpeqsf_t_4"
8569 [(set (reg:SI T_REG)
8570 (ior:SI (reg:SI T_REG)
8571 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8572 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8573 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8574 "TARGET_IEEE && TARGET_SH4"
8575 "* return output_ieee_ccmpeq (insn, operands);"
8576 [(set_attr "length" "4")
8577 (set_attr "fp_mode" "single")])
8579 (define_insn "cmpeqsf_media"
8580 [(set (match_operand:DI 0 "register_operand" "=r")
8581 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8582 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8583 "TARGET_SHMEDIA_FPU"
8584 "fcmpeq.s %1, %2, %0"
8585 [(set_attr "type" "fcmp_media")])
8587 (define_insn "cmpgtsf_media"
8588 [(set (match_operand:DI 0 "register_operand" "=r")
8589 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8590 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8591 "TARGET_SHMEDIA_FPU"
8592 "fcmpgt.s %1, %2, %0"
8593 [(set_attr "type" "fcmp_media")])
8595 (define_insn "cmpgesf_media"
8596 [(set (match_operand:DI 0 "register_operand" "=r")
8597 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8598 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8599 "TARGET_SHMEDIA_FPU"
8600 "fcmpge.s %1, %2, %0"
8601 [(set_attr "type" "fcmp_media")])
8603 (define_insn "cmpunsf_media"
8604 [(set (match_operand:DI 0 "register_operand" "=r")
8605 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8606 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8607 "TARGET_SHMEDIA_FPU"
8608 "fcmpun.s %1, %2, %0"
8609 [(set_attr "type" "fcmp_media")])
8611 (define_expand "cmpsf"
8612 [(set (reg:SI T_REG)
8613 (compare (match_operand:SF 0 "arith_operand" "")
8614 (match_operand:SF 1 "arith_operand" "")))]
8615 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8618 sh_compare_op0 = operands[0];
8619 sh_compare_op1 = operands[1];
8623 (define_expand "negsf2"
8624 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8625 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8626 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8631 expand_sf_unop (&gen_negsf2_i, operands);
8636 (define_insn "*negsf2_media"
8637 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8638 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8639 "TARGET_SHMEDIA_FPU"
8641 [(set_attr "type" "fmove_media")])
8643 (define_insn "negsf2_i"
8644 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8645 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8646 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8649 [(set_attr "type" "fmove")
8650 (set_attr "fp_mode" "single")])
8652 (define_expand "sqrtsf2"
8653 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8654 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8655 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8660 expand_sf_unop (&gen_sqrtsf2_i, operands);
8665 (define_insn "*sqrtsf2_media"
8666 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8667 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8668 "TARGET_SHMEDIA_FPU"
8670 [(set_attr "type" "fdiv_media")])
8672 (define_insn "sqrtsf2_i"
8673 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8674 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8675 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8678 [(set_attr "type" "fdiv")
8679 (set_attr "fp_mode" "single")])
8681 (define_insn "rsqrtsf2"
8682 [(set (match_operand:SF 0 "register_operand" "=f")
8683 (div:SF (match_operand:SF 1 "immediate_operand" "i")
8684 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8685 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8686 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8687 && operands[1] == CONST1_RTX (SFmode)"
8689 [(set_attr "type" "fsrra")
8690 (set_attr "fp_mode" "single")])
8693 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8695 (unspec:SF [(mult:SF
8696 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8697 (match_operand:SF 2 "immediate_operand" "i"))
8699 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8701 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8702 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8703 && operands[2] == sh_fsca_int2sf ()"
8705 [(set_attr "type" "fsca")
8706 (set_attr "fp_mode" "single")])
8708 (define_expand "sinsf2"
8709 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8710 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8712 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8715 rtx scaled = gen_reg_rtx (SFmode);
8716 rtx truncated = gen_reg_rtx (SImode);
8717 rtx fsca = gen_reg_rtx (V2SFmode);
8718 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8720 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8721 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8722 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8724 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8728 (define_expand "cossf2"
8729 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8730 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8732 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8735 rtx scaled = gen_reg_rtx (SFmode);
8736 rtx truncated = gen_reg_rtx (SImode);
8737 rtx fsca = gen_reg_rtx (V2SFmode);
8738 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8740 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8741 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8742 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8744 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8748 (define_expand "sindf2"
8749 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8750 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8752 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8755 rtx scaled = gen_reg_rtx (DFmode);
8756 rtx truncated = gen_reg_rtx (SImode);
8757 rtx fsca = gen_reg_rtx (V2SFmode);
8758 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8759 rtx sfresult = gen_reg_rtx (SFmode);
8761 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8762 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8763 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8765 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8766 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8770 (define_expand "cosdf2"
8771 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8772 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8774 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8777 rtx scaled = gen_reg_rtx (DFmode);
8778 rtx truncated = gen_reg_rtx (SImode);
8779 rtx fsca = gen_reg_rtx (V2SFmode);
8780 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8781 rtx sfresult = gen_reg_rtx (SFmode);
8783 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8784 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8785 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8787 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8788 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8792 (define_expand "abssf2"
8793 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8794 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8795 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8800 expand_sf_unop (&gen_abssf2_i, operands);
8805 (define_insn "*abssf2_media"
8806 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8807 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8808 "TARGET_SHMEDIA_FPU"
8810 [(set_attr "type" "fmove_media")])
8812 (define_insn "abssf2_i"
8813 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8814 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8815 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8818 [(set_attr "type" "fmove")
8819 (set_attr "fp_mode" "single")])
8821 (define_expand "adddf3"
8822 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8823 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8824 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8825 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8830 expand_df_binop (&gen_adddf3_i, operands);
8835 (define_insn "*adddf3_media"
8836 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8837 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8838 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8839 "TARGET_SHMEDIA_FPU"
8841 [(set_attr "type" "dfparith_media")])
8843 (define_insn "adddf3_i"
8844 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8845 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8846 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8847 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8850 [(set_attr "type" "dfp_arith")
8851 (set_attr "fp_mode" "double")])
8853 (define_expand "subdf3"
8854 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8855 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8856 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8857 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8862 expand_df_binop (&gen_subdf3_i, operands);
8867 (define_insn "*subdf3_media"
8868 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8869 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8870 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8871 "TARGET_SHMEDIA_FPU"
8873 [(set_attr "type" "dfparith_media")])
8875 (define_insn "subdf3_i"
8876 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8877 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8878 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8879 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8882 [(set_attr "type" "dfp_arith")
8883 (set_attr "fp_mode" "double")])
8885 (define_expand "muldf3"
8886 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8887 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8888 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8889 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8894 expand_df_binop (&gen_muldf3_i, operands);
8899 (define_insn "*muldf3_media"
8900 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8901 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8902 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8903 "TARGET_SHMEDIA_FPU"
8905 [(set_attr "type" "dfmul_media")])
8907 (define_insn "muldf3_i"
8908 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8909 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8910 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8911 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8914 [(set_attr "type" "dfp_arith")
8915 (set_attr "fp_mode" "double")])
8917 (define_expand "divdf3"
8918 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8919 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8920 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8921 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8926 expand_df_binop (&gen_divdf3_i, operands);
8931 (define_insn "*divdf3_media"
8932 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8933 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8934 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8935 "TARGET_SHMEDIA_FPU"
8937 [(set_attr "type" "dfdiv_media")])
8939 (define_insn "divdf3_i"
8940 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8941 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8942 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8943 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8946 [(set_attr "type" "dfdiv")
8947 (set_attr "fp_mode" "double")])
8949 (define_insn "floatdidf2"
8950 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8951 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8952 "TARGET_SHMEDIA_FPU"
8954 [(set_attr "type" "dfpconv_media")])
8956 (define_expand "floatsidf2"
8957 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8958 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8959 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8964 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8970 (define_insn "*floatsidf2_media"
8971 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8972 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8973 "TARGET_SHMEDIA_FPU"
8975 [(set_attr "type" "dfpconv_media")])
8977 (define_insn "floatsidf2_i"
8978 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8979 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8980 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8983 [(set_attr "type" "dfp_conv")
8984 (set_attr "fp_mode" "double")])
8986 (define_insn "fix_truncdfdi2"
8987 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8988 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8989 "TARGET_SHMEDIA_FPU"
8991 [(set_attr "type" "dfpconv_media")])
8993 (define_expand "fix_truncdfsi2"
8994 [(set (match_operand:SI 0 "fpul_operand" "")
8995 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8996 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9001 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9007 (define_insn "*fix_truncdfsi2_media"
9008 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9009 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9010 "TARGET_SHMEDIA_FPU"
9012 [(set_attr "type" "dfpconv_media")])
9014 (define_insn "fix_truncdfsi2_i"
9015 [(set (match_operand:SI 0 "fpul_operand" "=y")
9016 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9017 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9020 [(set_attr "type" "dfp_conv")
9021 (set_attr "dfp_comp" "no")
9022 (set_attr "fp_mode" "double")])
9024 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
9025 ;; fix_truncdfsi2_i.
9026 ;; (define_insn "fix_truncdfsi2_i4"
9027 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9028 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9029 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9030 ;; (clobber (reg:SI FPUL_REG))]
9033 ;; [(set_attr "length" "4")
9034 ;; (set_attr "fp_mode" "double")])
9037 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9038 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9039 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9040 ;; (clobber (reg:SI FPUL_REG))]
9042 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9043 ;; (use (match_dup 2))])
9044 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
9046 (define_insn "cmpgtdf_t"
9047 [(set (reg:SI T_REG)
9048 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9049 (match_operand:DF 1 "arith_reg_operand" "f")))
9050 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9053 [(set_attr "type" "dfp_cmp")
9054 (set_attr "fp_mode" "double")])
9056 (define_insn "cmpeqdf_t"
9057 [(set (reg:SI T_REG)
9058 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9059 (match_operand:DF 1 "arith_reg_operand" "f")))
9060 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9063 [(set_attr "type" "dfp_cmp")
9064 (set_attr "fp_mode" "double")])
9066 (define_insn "*ieee_ccmpeqdf_t"
9067 [(set (reg:SI T_REG)
9068 (ior:SI (reg:SI T_REG)
9069 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9070 (match_operand:DF 1 "arith_reg_operand" "f"))))
9071 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9072 "TARGET_IEEE && TARGET_SH4"
9073 "* return output_ieee_ccmpeq (insn, operands);"
9074 [(set_attr "length" "4")
9075 (set_attr "fp_mode" "double")])
9077 (define_insn "cmpeqdf_media"
9078 [(set (match_operand:DI 0 "register_operand" "=r")
9079 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9080 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9081 "TARGET_SHMEDIA_FPU"
9083 [(set_attr "type" "fcmp_media")])
9085 (define_insn "cmpgtdf_media"
9086 [(set (match_operand:DI 0 "register_operand" "=r")
9087 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9088 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9089 "TARGET_SHMEDIA_FPU"
9091 [(set_attr "type" "fcmp_media")])
9093 (define_insn "cmpgedf_media"
9094 [(set (match_operand:DI 0 "register_operand" "=r")
9095 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9096 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9097 "TARGET_SHMEDIA_FPU"
9099 [(set_attr "type" "fcmp_media")])
9101 (define_insn "cmpundf_media"
9102 [(set (match_operand:DI 0 "register_operand" "=r")
9103 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9104 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9105 "TARGET_SHMEDIA_FPU"
9107 [(set_attr "type" "fcmp_media")])
9109 (define_expand "cmpdf"
9110 [(set (reg:SI T_REG)
9111 (compare (match_operand:DF 0 "arith_operand" "")
9112 (match_operand:DF 1 "arith_operand" "")))]
9113 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9116 sh_compare_op0 = operands[0];
9117 sh_compare_op1 = operands[1];
9121 (define_expand "negdf2"
9122 [(set (match_operand:DF 0 "arith_reg_operand" "")
9123 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9124 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9129 expand_df_unop (&gen_negdf2_i, operands);
9134 (define_insn "*negdf2_media"
9135 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9136 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9137 "TARGET_SHMEDIA_FPU"
9139 [(set_attr "type" "fmove_media")])
9141 (define_insn "negdf2_i"
9142 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9143 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9144 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9147 [(set_attr "type" "fmove")
9148 (set_attr "fp_mode" "double")])
9150 (define_expand "sqrtdf2"
9151 [(set (match_operand:DF 0 "arith_reg_operand" "")
9152 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9153 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9158 expand_df_unop (&gen_sqrtdf2_i, operands);
9163 (define_insn "*sqrtdf2_media"
9164 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9165 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9166 "TARGET_SHMEDIA_FPU"
9168 [(set_attr "type" "dfdiv_media")])
9170 (define_insn "sqrtdf2_i"
9171 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9172 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9173 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9176 [(set_attr "type" "dfdiv")
9177 (set_attr "fp_mode" "double")])
9179 (define_expand "absdf2"
9180 [(set (match_operand:DF 0 "arith_reg_operand" "")
9181 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9182 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9187 expand_df_unop (&gen_absdf2_i, operands);
9192 (define_insn "*absdf2_media"
9193 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9194 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9195 "TARGET_SHMEDIA_FPU"
9197 [(set_attr "type" "fmove_media")])
9199 (define_insn "absdf2_i"
9200 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9201 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9202 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9205 [(set_attr "type" "fmove")
9206 (set_attr "fp_mode" "double")])
9208 (define_expand "extendsfdf2"
9209 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9210 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9211 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9216 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9222 (define_insn "*extendsfdf2_media"
9223 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9224 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9225 "TARGET_SHMEDIA_FPU"
9227 [(set_attr "type" "dfpconv_media")])
9229 (define_insn "extendsfdf2_i4"
9230 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9231 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9232 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9235 [(set_attr "type" "fp")
9236 (set_attr "fp_mode" "double")])
9238 (define_expand "truncdfsf2"
9239 [(set (match_operand:SF 0 "fpul_operand" "")
9240 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9241 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9246 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9252 (define_insn "*truncdfsf2_media"
9253 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9254 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9255 "TARGET_SHMEDIA_FPU"
9257 [(set_attr "type" "dfpconv_media")])
9259 (define_insn "truncdfsf2_i4"
9260 [(set (match_operand:SF 0 "fpul_operand" "=y")
9261 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9262 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9265 [(set_attr "type" "fp")
9266 (set_attr "fp_mode" "double")])
9268 ;; Bit field extract patterns. These give better code for packed bitfields,
9269 ;; because they allow auto-increment addresses to be generated.
9271 (define_expand "insv"
9272 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9273 (match_operand:SI 1 "immediate_operand" "")
9274 (match_operand:SI 2 "immediate_operand" ""))
9275 (match_operand:SI 3 "general_operand" ""))]
9276 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9279 rtx addr_target, orig_address, shift_reg, qi_val;
9280 HOST_WIDE_INT bitsize, size, v = 0;
9281 rtx x = operands[3];
9283 /* ??? expmed doesn't care for non-register predicates. */
9284 if (! memory_operand (operands[0], VOIDmode)
9285 || ! immediate_operand (operands[1], VOIDmode)
9286 || ! immediate_operand (operands[2], VOIDmode)
9287 || ! general_operand (x, VOIDmode))
9289 /* If this isn't a 16 / 24 / 32 bit field, or if
9290 it doesn't start on a byte boundary, then fail. */
9291 bitsize = INTVAL (operands[1]);
9292 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9293 || (INTVAL (operands[2]) % 8) != 0)
9297 orig_address = XEXP (operands[0], 0);
9298 shift_reg = gen_reg_rtx (SImode);
9299 if (GET_CODE (x) == CONST_INT)
9302 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9306 emit_insn (gen_movsi (shift_reg, operands[3]));
9307 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9309 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9311 operands[0] = replace_equiv_address (operands[0], addr_target);
9312 emit_insn (gen_movqi (operands[0], qi_val));
9316 if (GET_CODE (x) == CONST_INT)
9318 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9321 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9322 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9324 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9325 emit_insn (gen_movqi (operands[0], qi_val));
9331 (define_insn "movua"
9332 [(set (match_operand:SI 0 "register_operand" "=z")
9333 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9334 (const_int 32) (const_int 0)))]
9337 [(set_attr "type" "movua")])
9339 ;; We shouldn't need this, but cse replaces increments with references
9340 ;; to other regs before flow has a chance to create post_inc
9341 ;; addressing modes, and only postreload's cse_move2add brings the
9342 ;; increments back to a usable form.
9344 [(set (match_operand:SI 0 "register_operand" "")
9345 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9346 (const_int 32) (const_int 0)))
9347 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9348 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9349 [(set (match_operand:SI 0 "register_operand" "")
9350 (sign_extract:SI (mem:SI (post_inc:SI
9351 (match_operand:SI 1 "register_operand" "")))
9352 (const_int 32) (const_int 0)))]
9355 (define_expand "extv"
9356 [(set (match_operand:SI 0 "register_operand" "")
9357 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9358 (match_operand 2 "const_int_operand" "")
9359 (match_operand 3 "const_int_operand" "")))]
9362 if (TARGET_SH4A_ARCH
9363 && INTVAL (operands[2]) == 32
9364 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9365 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9367 emit_insn (gen_movua (operands[0],
9368 adjust_address (operands[1], SImode, 0)));
9375 (define_expand "extzv"
9376 [(set (match_operand:SI 0 "register_operand" "")
9377 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9378 (match_operand 2 "const_int_operand" "")
9379 (match_operand 3 "const_int_operand" "")))]
9382 if (TARGET_SH4A_ARCH
9383 && INTVAL (operands[2]) == 32
9384 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9385 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9387 emit_insn (gen_movua (operands[0],
9388 adjust_address (operands[1], SImode, 0)));
9396 ;; -------------------------------------------------------------------------
9398 ;; -------------------------------------------------------------------------
9400 ;; This matches cases where a stack pointer increment at the start of the
9401 ;; epilogue combines with a stack slot read loading the return value.
9404 [(set (match_operand:SI 0 "arith_reg_operand" "")
9405 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9406 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9407 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9410 ;; See the comment on the dt combiner pattern above.
9413 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9414 (plus:SI (match_dup 0)
9417 (eq:SI (match_dup 0)
9422 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9423 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9424 ;; reload when the constant is too large for a reg+offset address.
9426 ;; ??? We would get much better code if this was done in reload. This would
9427 ;; require modifying find_reloads_address to recognize that if the constant
9428 ;; is out-of-range for an immediate add, then we get better code by reloading
9429 ;; the constant into a register than by reloading the sum into a register,
9430 ;; since the former is one instruction shorter if the address does not need
9431 ;; to be offsettable. Unfortunately this does not work, because there is
9432 ;; only one register, r0, that can be used as an index register. This register
9433 ;; is also the function return value register. So, if we try to force reload
9434 ;; to use double-reg addresses, then we end up with some instructions that
9435 ;; need to use r0 twice. The only way to fix this is to change the calling
9436 ;; convention so that r0 is not used to return values.
9439 [(set (match_operand:SI 0 "register_operand" "=r")
9440 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9441 (set (mem:SI (match_dup 0))
9442 (match_operand:SI 2 "general_movsrc_operand" ""))]
9443 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9444 "mov.l %2,@(%0,%1)")
9447 [(set (match_operand:SI 0 "register_operand" "=r")
9448 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9449 (set (match_operand:SI 2 "general_movdst_operand" "")
9450 (mem:SI (match_dup 0)))]
9451 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9452 "mov.l @(%0,%1),%2")
9455 [(set (match_operand:SI 0 "register_operand" "=r")
9456 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9457 (set (mem:HI (match_dup 0))
9458 (match_operand:HI 2 "general_movsrc_operand" ""))]
9459 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9460 "mov.w %2,@(%0,%1)")
9463 [(set (match_operand:SI 0 "register_operand" "=r")
9464 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9465 (set (match_operand:HI 2 "general_movdst_operand" "")
9466 (mem:HI (match_dup 0)))]
9467 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9468 "mov.w @(%0,%1),%2")
9471 [(set (match_operand:SI 0 "register_operand" "=r")
9472 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9473 (set (mem:QI (match_dup 0))
9474 (match_operand:QI 2 "general_movsrc_operand" ""))]
9475 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9476 "mov.b %2,@(%0,%1)")
9479 [(set (match_operand:SI 0 "register_operand" "=r")
9480 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9481 (set (match_operand:QI 2 "general_movdst_operand" "")
9482 (mem:QI (match_dup 0)))]
9483 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9484 "mov.b @(%0,%1),%2")
9487 [(set (match_operand:SI 0 "register_operand" "=r")
9488 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9489 (set (mem:SF (match_dup 0))
9490 (match_operand:SF 2 "general_movsrc_operand" ""))]
9491 "TARGET_SH1 && REGNO (operands[0]) == 0
9492 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9493 || (GET_CODE (operands[2]) == SUBREG
9494 && REGNO (SUBREG_REG (operands[2])) < 16))
9495 && reg_unused_after (operands[0], insn)"
9496 "mov.l %2,@(%0,%1)")
9499 [(set (match_operand:SI 0 "register_operand" "=r")
9500 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9501 (set (match_operand:SF 2 "general_movdst_operand" "")
9503 (mem:SF (match_dup 0)))]
9504 "TARGET_SH1 && REGNO (operands[0]) == 0
9505 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9506 || (GET_CODE (operands[2]) == SUBREG
9507 && REGNO (SUBREG_REG (operands[2])) < 16))
9508 && reg_unused_after (operands[0], insn)"
9509 "mov.l @(%0,%1),%2")
9512 [(set (match_operand:SI 0 "register_operand" "=r")
9513 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9514 (set (mem:SF (match_dup 0))
9515 (match_operand:SF 2 "general_movsrc_operand" ""))]
9516 "TARGET_SH2E && REGNO (operands[0]) == 0
9517 && ((GET_CODE (operands[2]) == REG
9518 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9519 || (GET_CODE (operands[2]) == SUBREG
9520 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9521 && reg_unused_after (operands[0], insn)"
9522 "fmov{.s|} %2,@(%0,%1)")
9525 [(set (match_operand:SI 0 "register_operand" "=r")
9526 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9527 (set (match_operand:SF 2 "general_movdst_operand" "")
9529 (mem:SF (match_dup 0)))]
9530 "TARGET_SH2E && REGNO (operands[0]) == 0
9531 && ((GET_CODE (operands[2]) == REG
9532 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9533 || (GET_CODE (operands[2]) == SUBREG
9534 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9535 && reg_unused_after (operands[0], insn)"
9536 "fmov{.s|} @(%0,%1),%2")
9538 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9539 (define_insn "sp_switch_1"
9546 xoperands[0] = sp_switch;
9547 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9548 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9549 return \"mov r0,r15\";
9551 [(set_attr "length" "10")])
9553 ;; Switch back to the original stack for interrupt functions with the
9554 ;; sp_switch attribute. */
9555 (define_insn "sp_switch_2"
9558 "mov.l @r15+,r15\;mov.l @r15+,r0"
9559 [(set_attr "length" "4")])
9561 ;; Integer vector moves
9563 (define_expand "movv8qi"
9564 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9565 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9567 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9569 (define_insn "movv8qi_i"
9570 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9571 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9573 && (register_operand (operands[0], V8QImode)
9574 || sh_register_operand (operands[1], V8QImode))"
9581 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9582 (set_attr "length" "4,4,16,4,4")])
9585 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9586 (subreg:V8QI (const_int 0) 0))]
9589 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9590 (const_int 0) (const_int 0) (const_int 0)
9591 (const_int 0) (const_int 0)]))])
9594 [(set (match_operand 0 "arith_reg_dest" "")
9595 (match_operand 1 "sh_rep_vec" ""))]
9596 "TARGET_SHMEDIA && reload_completed
9597 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9598 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9599 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9600 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9601 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9602 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9603 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9604 [(set (match_dup 0) (match_dup 1))
9608 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9609 rtx elt1 = XVECEXP (operands[1], 0, 1);
9612 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9616 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9617 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9619 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9620 operands[1] = XVECEXP (operands[1], 0, 0);
9623 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9625 = GEN_INT (TARGET_LITTLE_ENDIAN
9626 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9627 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9630 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9632 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9638 [(set (match_operand 0 "arith_reg_dest" "")
9639 (match_operand 1 "sh_const_vec" ""))]
9640 "TARGET_SHMEDIA && reload_completed
9641 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9642 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9643 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9644 [(set (match_dup 0) (match_dup 1))]
9647 rtx v = operands[1];
9648 enum machine_mode new_mode
9649 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9651 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9653 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9656 (define_expand "movv2hi"
9657 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9658 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9660 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9662 (define_insn "movv2hi_i"
9663 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9664 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9666 && (register_operand (operands[0], V2HImode)
9667 || sh_register_operand (operands[1], V2HImode))"
9674 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9675 (set_attr "length" "4,4,16,4,4")])
9677 (define_expand "movv4hi"
9678 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9679 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9681 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9683 (define_insn "movv4hi_i"
9684 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9685 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9687 && (register_operand (operands[0], V4HImode)
9688 || sh_register_operand (operands[1], V4HImode))"
9695 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9696 (set_attr "length" "4,4,16,4,4")])
9698 (define_expand "movv2si"
9699 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9700 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9702 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9704 (define_insn "movv2si_i"
9705 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9706 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9708 && (register_operand (operands[0], V2SImode)
9709 || sh_register_operand (operands[1], V2SImode))"
9716 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9717 (set_attr "length" "4,4,16,4,4")])
9719 ;; Multimedia Intrinsics
9721 (define_insn "absv2si2"
9722 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9723 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9726 [(set_attr "type" "mcmp_media")])
9728 (define_insn "absv4hi2"
9729 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9730 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9733 [(set_attr "type" "mcmp_media")])
9735 (define_insn "addv2si3"
9736 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9737 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9738 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9741 [(set_attr "type" "arith_media")])
9743 (define_insn "addv4hi3"
9744 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9745 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9746 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9749 [(set_attr "type" "arith_media")])
9751 (define_insn "ssaddv2si3"
9752 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9753 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9754 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9756 "madds.l %1, %2, %0"
9757 [(set_attr "type" "mcmp_media")])
9759 (define_insn "usaddv8qi3"
9760 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9761 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9762 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9764 "madds.ub %1, %2, %0"
9765 [(set_attr "type" "mcmp_media")])
9767 (define_insn "ssaddv4hi3"
9768 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9769 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9770 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9772 "madds.w %1, %2, %0"
9773 [(set_attr "type" "mcmp_media")])
9775 (define_insn "negcmpeqv8qi"
9776 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9777 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9778 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9780 "mcmpeq.b %N1, %N2, %0"
9781 [(set_attr "type" "mcmp_media")])
9783 (define_insn "negcmpeqv2si"
9784 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9785 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9786 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9788 "mcmpeq.l %N1, %N2, %0"
9789 [(set_attr "type" "mcmp_media")])
9791 (define_insn "negcmpeqv4hi"
9792 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9793 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9794 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9796 "mcmpeq.w %N1, %N2, %0"
9797 [(set_attr "type" "mcmp_media")])
9799 (define_insn "negcmpgtuv8qi"
9800 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9801 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9802 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9804 "mcmpgt.ub %N1, %N2, %0"
9805 [(set_attr "type" "mcmp_media")])
9807 (define_insn "negcmpgtv2si"
9808 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9809 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9810 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9812 "mcmpgt.l %N1, %N2, %0"
9813 [(set_attr "type" "mcmp_media")])
9815 (define_insn "negcmpgtv4hi"
9816 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9817 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9818 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9820 "mcmpgt.w %N1, %N2, %0"
9821 [(set_attr "type" "mcmp_media")])
9824 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9825 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9826 (match_operand:DI 2 "arith_reg_operand" "r"))
9827 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9828 (not:DI (match_dup 2)))))]
9831 [(set_attr "type" "arith_media")])
9833 (define_insn "mcnvs_lw"
9834 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9836 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9837 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9839 "mcnvs.lw %N1, %N2, %0"
9840 [(set_attr "type" "mcmp_media")])
9842 (define_insn "mcnvs_wb"
9843 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9845 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9846 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9848 "mcnvs.wb %N1, %N2, %0"
9849 [(set_attr "type" "mcmp_media")])
9851 (define_insn "mcnvs_wub"
9852 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9854 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9855 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9857 "mcnvs.wub %N1, %N2, %0"
9858 [(set_attr "type" "mcmp_media")])
9860 (define_insn "mextr_rl"
9861 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9862 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9863 (match_operand:HI 3 "mextr_bit_offset" "i"))
9864 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9865 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9866 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9869 static char templ[16];
9871 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9872 (int) INTVAL (operands[3]) >> 3);
9875 [(set_attr "type" "arith_media")])
9877 (define_insn "*mextr_lr"
9878 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9879 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9880 (match_operand:HI 3 "mextr_bit_offset" "i"))
9881 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9882 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9883 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9886 static char templ[16];
9888 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9889 (int) INTVAL (operands[4]) >> 3);
9892 [(set_attr "type" "arith_media")])
9894 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9895 ; vector then varies depending on endianness.
9896 (define_expand "mextr1"
9897 [(match_operand:DI 0 "arith_reg_dest" "")
9898 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9899 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9903 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9904 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9908 (define_expand "mextr2"
9909 [(match_operand:DI 0 "arith_reg_dest" "")
9910 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9911 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9915 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9916 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9920 (define_expand "mextr3"
9921 [(match_operand:DI 0 "arith_reg_dest" "")
9922 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9923 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9927 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9928 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9932 (define_expand "mextr4"
9933 [(match_operand:DI 0 "arith_reg_dest" "")
9934 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9935 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9939 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9940 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9944 (define_expand "mextr5"
9945 [(match_operand:DI 0 "arith_reg_dest" "")
9946 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9947 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9951 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9952 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9956 (define_expand "mextr6"
9957 [(match_operand:DI 0 "arith_reg_dest" "")
9958 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9959 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9963 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9964 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9968 (define_expand "mextr7"
9969 [(match_operand:DI 0 "arith_reg_dest" "")
9970 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9971 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9975 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9976 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9980 (define_expand "mmacfx_wl"
9981 [(match_operand:V2SI 0 "arith_reg_dest" "")
9982 (match_operand:V2HI 1 "extend_reg_operand" "")
9983 (match_operand:V2HI 2 "extend_reg_operand" "")
9984 (match_operand:V2SI 3 "arith_reg_operand" "")]
9988 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9989 operands[1], operands[2]));
9993 (define_insn "mmacfx_wl_i"
9994 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9996 (match_operand:V2SI 1 "arith_reg_operand" "0")
10001 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10002 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10005 "mmacfx.wl %2, %3, %0"
10006 [(set_attr "type" "mac_media")])
10008 (define_expand "mmacnfx_wl"
10009 [(match_operand:V2SI 0 "arith_reg_dest" "")
10010 (match_operand:V2HI 1 "extend_reg_operand" "")
10011 (match_operand:V2HI 2 "extend_reg_operand" "")
10012 (match_operand:V2SI 3 "arith_reg_operand" "")]
10016 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10017 operands[1], operands[2]));
10021 (define_insn "mmacnfx_wl_i"
10022 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10024 (match_operand:V2SI 1 "arith_reg_operand" "0")
10029 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10030 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10033 "mmacnfx.wl %2, %3, %0"
10034 [(set_attr "type" "mac_media")])
10036 (define_insn "mulv2si3"
10037 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10038 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10039 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10041 "mmul.l %1, %2, %0"
10042 [(set_attr "type" "d2mpy_media")])
10044 (define_insn "mulv4hi3"
10045 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10046 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10047 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10049 "mmul.w %1, %2, %0"
10050 [(set_attr "type" "dmpy_media")])
10052 (define_insn "mmulfx_l"
10053 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10057 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10058 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10061 "mmulfx.l %1, %2, %0"
10062 [(set_attr "type" "d2mpy_media")])
10064 (define_insn "mmulfx_w"
10065 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10069 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10070 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10073 "mmulfx.w %1, %2, %0"
10074 [(set_attr "type" "dmpy_media")])
10076 (define_insn "mmulfxrp_w"
10077 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10082 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10083 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10087 "mmulfxrp.w %1, %2, %0"
10088 [(set_attr "type" "dmpy_media")])
10090 (define_expand "mmulhi_wl"
10091 [(match_operand:V2SI 0 "arith_reg_dest" "")
10092 (match_operand:V4HI 1 "arith_reg_operand" "")
10093 (match_operand:V4HI 2 "arith_reg_operand" "")]
10097 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10098 (operands[0], operands[1], operands[2]));
10102 (define_expand "mmullo_wl"
10103 [(match_operand:V2SI 0 "arith_reg_dest" "")
10104 (match_operand:V4HI 1 "arith_reg_operand" "")
10105 (match_operand:V4HI 2 "arith_reg_operand" "")]
10109 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10110 (operands[0], operands[1], operands[2]));
10114 (define_insn "mmul23_wl"
10115 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10118 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10119 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10120 (parallel [(const_int 2) (const_int 3)])))]
10122 "* return (TARGET_LITTLE_ENDIAN
10123 ? \"mmulhi.wl %1, %2, %0\"
10124 : \"mmullo.wl %1, %2, %0\");"
10125 [(set_attr "type" "dmpy_media")])
10127 (define_insn "mmul01_wl"
10128 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10131 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10132 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10133 (parallel [(const_int 0) (const_int 1)])))]
10135 "* return (TARGET_LITTLE_ENDIAN
10136 ? \"mmullo.wl %1, %2, %0\"
10137 : \"mmulhi.wl %1, %2, %0\");"
10138 [(set_attr "type" "dmpy_media")])
10140 (define_expand "mmulsum_wq"
10141 [(match_operand:DI 0 "arith_reg_dest" "")
10142 (match_operand:V4HI 1 "arith_reg_operand" "")
10143 (match_operand:V4HI 2 "arith_reg_operand" "")
10144 (match_operand:DI 3 "arith_reg_operand" "")]
10148 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10149 operands[1], operands[2]));
10153 (define_insn "mmulsum_wq_i"
10154 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10155 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10160 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10161 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10162 (parallel [(const_int 0)]))
10163 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10164 (sign_extend:V4DI (match_dup 3)))
10165 (parallel [(const_int 1)])))
10167 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10168 (sign_extend:V4DI (match_dup 3)))
10169 (parallel [(const_int 2)]))
10170 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10171 (sign_extend:V4DI (match_dup 3)))
10172 (parallel [(const_int 3)]))))))]
10174 "mmulsum.wq %2, %3, %0"
10175 [(set_attr "type" "mac_media")])
10177 (define_expand "mperm_w"
10178 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10179 (match_operand:V4HI 1 "arith_reg_operand" "r")
10180 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10184 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10185 (operands[0], operands[1], operands[2]));
10189 ; This use of vec_select isn't exactly correct according to rtl.texi
10190 ; (because not constant), but it seems a straightforward extension.
10191 (define_insn "mperm_w_little"
10192 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10194 (match_operand:V4HI 1 "arith_reg_operand" "r")
10196 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10197 (const_int 2) (const_int 0))
10198 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10199 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10200 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10201 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10202 "mperm.w %1, %N2, %0"
10203 [(set_attr "type" "arith_media")])
10205 (define_insn "mperm_w_big"
10206 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10208 (match_operand:V4HI 1 "arith_reg_operand" "r")
10210 [(zero_extract:QI (not:QI (match_operand:QI 2
10211 "extend_reg_or_0_operand" "rZ"))
10212 (const_int 2) (const_int 0))
10213 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10214 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10215 (zero_extract:QI (not:QI (match_dup 2))
10216 (const_int 2) (const_int 6))])))]
10217 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10218 "mperm.w %1, %N2, %0"
10219 [(set_attr "type" "arith_media")])
10221 (define_insn "mperm_w0"
10222 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10223 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10224 "trunc_hi_operand" "r"))))]
10226 "mperm.w %1, r63, %0"
10227 [(set_attr "type" "arith_media")])
10229 (define_expand "msad_ubq"
10230 [(match_operand:DI 0 "arith_reg_dest" "")
10231 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10232 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10233 (match_operand:DI 3 "arith_reg_operand" "")]
10237 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10238 operands[1], operands[2]));
10242 (define_insn "msad_ubq_i"
10243 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10248 (match_operand:DI 1 "arith_reg_operand" "0")
10249 (abs:DI (vec_select:DI
10252 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10254 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10255 (parallel [(const_int 0)]))))
10256 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10257 (zero_extend:V8DI (match_dup 3)))
10258 (parallel [(const_int 1)]))))
10260 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10261 (zero_extend:V8DI (match_dup 3)))
10262 (parallel [(const_int 2)])))
10263 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10264 (zero_extend:V8DI (match_dup 3)))
10265 (parallel [(const_int 3)])))))
10268 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10269 (zero_extend:V8DI (match_dup 3)))
10270 (parallel [(const_int 4)])))
10271 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10272 (zero_extend:V8DI (match_dup 3)))
10273 (parallel [(const_int 5)]))))
10275 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10276 (zero_extend:V8DI (match_dup 3)))
10277 (parallel [(const_int 6)])))
10278 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10279 (zero_extend:V8DI (match_dup 3)))
10280 (parallel [(const_int 7)])))))))]
10282 "msad.ubq %N2, %N3, %0"
10283 [(set_attr "type" "mac_media")])
10285 (define_insn "mshalds_l"
10286 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10289 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10290 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10291 (const_int 31)))))]
10293 "mshalds.l %1, %2, %0"
10294 [(set_attr "type" "mcmp_media")])
10296 (define_insn "mshalds_w"
10297 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10300 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10301 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10302 (const_int 15)))))]
10304 "mshalds.w %1, %2, %0"
10305 [(set_attr "type" "mcmp_media")])
10307 (define_insn "ashrv2si3"
10308 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10309 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10310 (match_operand:DI 2 "arith_reg_operand" "r")))]
10312 "mshard.l %1, %2, %0"
10313 [(set_attr "type" "arith_media")])
10315 (define_insn "ashrv4hi3"
10316 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10317 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10318 (match_operand:DI 2 "arith_reg_operand" "r")))]
10320 "mshard.w %1, %2, %0"
10321 [(set_attr "type" "arith_media")])
10323 (define_insn "mshards_q"
10324 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10326 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10327 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10329 "mshards.q %1, %N2, %0"
10330 [(set_attr "type" "mcmp_media")])
10332 (define_expand "mshfhi_b"
10333 [(match_operand:V8QI 0 "arith_reg_dest" "")
10334 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10335 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10339 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10340 (operands[0], operands[1], operands[2]));
10344 (define_expand "mshflo_b"
10345 [(match_operand:V8QI 0 "arith_reg_dest" "")
10346 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10347 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10351 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10352 (operands[0], operands[1], operands[2]));
10356 (define_insn "mshf4_b"
10358 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10360 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10361 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10362 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10363 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10365 "* return (TARGET_LITTLE_ENDIAN
10366 ? \"mshfhi.b %N1, %N2, %0\"
10367 : \"mshflo.b %N1, %N2, %0\");"
10368 [(set_attr "type" "arith_media")])
10370 (define_insn "mshf0_b"
10372 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10374 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10375 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10376 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10377 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10379 "* return (TARGET_LITTLE_ENDIAN
10380 ? \"mshflo.b %N1, %N2, %0\"
10381 : \"mshfhi.b %N1, %N2, %0\");"
10382 [(set_attr "type" "arith_media")])
10384 (define_expand "mshfhi_l"
10385 [(match_operand:V2SI 0 "arith_reg_dest" "")
10386 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10387 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10391 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10392 (operands[0], operands[1], operands[2]));
10396 (define_expand "mshflo_l"
10397 [(match_operand:V2SI 0 "arith_reg_dest" "")
10398 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10399 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10403 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10404 (operands[0], operands[1], operands[2]));
10408 (define_insn "mshf4_l"
10409 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10411 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10412 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10413 (parallel [(const_int 1) (const_int 3)])))]
10415 "* return (TARGET_LITTLE_ENDIAN
10416 ? \"mshfhi.l %N1, %N2, %0\"
10417 : \"mshflo.l %N1, %N2, %0\");"
10418 [(set_attr "type" "arith_media")])
10420 (define_insn "mshf0_l"
10421 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10423 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10424 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10425 (parallel [(const_int 0) (const_int 2)])))]
10427 "* return (TARGET_LITTLE_ENDIAN
10428 ? \"mshflo.l %N1, %N2, %0\"
10429 : \"mshfhi.l %N1, %N2, %0\");"
10430 [(set_attr "type" "arith_media")])
10432 (define_expand "mshfhi_w"
10433 [(match_operand:V4HI 0 "arith_reg_dest" "")
10434 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10435 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10439 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10440 (operands[0], operands[1], operands[2]));
10444 (define_expand "mshflo_w"
10445 [(match_operand:V4HI 0 "arith_reg_dest" "")
10446 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10447 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10451 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10452 (operands[0], operands[1], operands[2]));
10456 (define_insn "mshf4_w"
10457 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10459 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10460 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10461 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10463 "* return (TARGET_LITTLE_ENDIAN
10464 ? \"mshfhi.w %N1, %N2, %0\"
10465 : \"mshflo.w %N1, %N2, %0\");"
10466 [(set_attr "type" "arith_media")])
10468 (define_insn "mshf0_w"
10469 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10471 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10472 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10473 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10475 "* return (TARGET_LITTLE_ENDIAN
10476 ? \"mshflo.w %N1, %N2, %0\"
10477 : \"mshfhi.w %N1, %N2, %0\");"
10478 [(set_attr "type" "arith_media")])
10480 (define_insn "mshflo_w_x"
10481 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10483 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10484 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10485 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10487 "mshflo.w %N1, %N2, %0"
10488 [(set_attr "type" "arith_media")])
10490 /* These are useful to expand ANDs and as combiner patterns. */
10491 (define_insn_and_split "mshfhi_l_di"
10492 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10493 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10495 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10496 (const_int -4294967296))))]
10499 mshfhi.l %N1, %N2, %0
10501 "TARGET_SHMEDIA && reload_completed
10502 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10503 [(set (match_dup 3) (match_dup 4))
10504 (set (match_dup 5) (match_dup 6))]
10507 operands[3] = gen_lowpart (SImode, operands[0]);
10508 operands[4] = gen_highpart (SImode, operands[1]);
10509 operands[5] = gen_highpart (SImode, operands[0]);
10510 operands[6] = gen_highpart (SImode, operands[2]);
10512 [(set_attr "type" "arith_media")])
10514 (define_insn "*mshfhi_l_di_rev"
10515 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10516 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10517 (const_int -4294967296))
10518 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10521 "mshfhi.l %N2, %N1, %0"
10522 [(set_attr "type" "arith_media")])
10525 [(set (match_operand:DI 0 "arith_reg_dest" "")
10526 (ior:DI (zero_extend:DI (match_operand:SI 1
10527 "extend_reg_or_0_operand" ""))
10528 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10529 (const_int -4294967296))))
10530 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10535 emit_insn (gen_ashldi3_media (operands[3],
10536 simplify_gen_subreg (DImode, operands[1],
10539 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10543 (define_insn "mshflo_l_di"
10544 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10545 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10546 (const_int 4294967295))
10547 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10551 "mshflo.l %N1, %N2, %0"
10552 [(set_attr "type" "arith_media")])
10554 (define_insn "*mshflo_l_di_rev"
10555 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10556 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10558 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10559 (const_int 4294967295))))]
10562 "mshflo.l %N2, %N1, %0"
10563 [(set_attr "type" "arith_media")])
10565 ;; Combiner pattern for trampoline initialization.
10566 (define_insn_and_split "*double_shori"
10567 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10568 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10570 (match_operand:DI 2 "const_int_operand" "n")))]
10572 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10574 "rtx_equal_p (operands[0], operands[1])"
10578 HOST_WIDE_INT v = INTVAL (operands[2]);
10580 emit_insn (gen_shori_media (operands[0], operands[0],
10581 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10582 emit_insn (gen_shori_media (operands[0], operands[0],
10583 gen_int_mode (v, HImode)));
10588 (define_insn "*mshflo_l_di_x"
10589 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10590 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10592 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10596 "mshflo.l %N1, %N2, %0"
10597 [(set_attr "type" "arith_media")])
10599 (define_insn_and_split "concat_v2sf"
10600 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10601 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10602 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10603 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10607 mshflo.l %N1, %N2, %0
10610 "TARGET_SHMEDIA && reload_completed
10611 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10612 [(set (match_dup 3) (match_dup 1))
10613 (set (match_dup 4) (match_dup 2))]
10616 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10617 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10619 [(set_attr "type" "arith_media")])
10621 (define_insn "*mshflo_l_di_x_rev"
10622 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10623 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10625 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10628 "mshflo.l %N2, %N1, %0"
10629 [(set_attr "type" "arith_media")])
10631 (define_insn "ashlv2si3"
10632 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10633 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10634 (match_operand:DI 2 "arith_reg_operand" "r")))]
10636 "mshlld.l %1, %2, %0"
10637 [(set_attr "type" "arith_media")])
10639 (define_insn "ashlv4hi3"
10640 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10641 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10642 (match_operand:DI 2 "arith_reg_operand" "r")))]
10644 "mshlld.w %1, %2, %0"
10645 [(set_attr "type" "arith_media")])
10647 (define_insn "lshrv2si3"
10648 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10649 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10650 (match_operand:DI 2 "arith_reg_operand" "r")))]
10652 "mshlrd.l %1, %2, %0"
10653 [(set_attr "type" "arith_media")])
10655 (define_insn "lshrv4hi3"
10656 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10657 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10658 (match_operand:DI 2 "arith_reg_operand" "r")))]
10660 "mshlrd.w %1, %2, %0"
10661 [(set_attr "type" "arith_media")])
10663 (define_insn "subv2si3"
10664 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10665 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10666 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10668 "msub.l %N1, %2, %0"
10669 [(set_attr "type" "arith_media")])
10671 (define_insn "subv4hi3"
10672 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10673 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10674 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10676 "msub.w %N1, %2, %0"
10677 [(set_attr "type" "arith_media")])
10679 (define_insn "sssubv2si3"
10680 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10681 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10682 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10684 "msubs.l %N1, %2, %0"
10685 [(set_attr "type" "mcmp_media")])
10687 (define_insn "ussubv8qi3"
10688 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10689 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10690 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10692 "msubs.ub %1, %2, %0"
10693 [(set_attr "type" "mcmp_media")])
10695 (define_insn "sssubv4hi3"
10696 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10697 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10698 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10700 "msubs.w %N1, %2, %0"
10701 [(set_attr "type" "mcmp_media")])
10703 ;; Floating Point Intrinsics
10705 (define_insn "fcosa_s"
10706 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10707 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10711 [(set_attr "type" "atrans_media")])
10713 (define_insn "fsina_s"
10714 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10715 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10719 [(set_attr "type" "atrans_media")])
10721 (define_insn "fipr"
10722 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10723 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10724 "fp_arith_reg_operand" "f")
10725 (match_operand:V4SF 2
10726 "fp_arith_reg_operand" "f"))
10727 (parallel [(const_int 0)]))
10728 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10729 (parallel [(const_int 1)])))
10730 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10731 (parallel [(const_int 2)]))
10732 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10733 (parallel [(const_int 3)])))))]
10735 "fipr.s %1, %2, %0"
10736 [(set_attr "type" "fparith_media")])
10738 (define_insn "fsrra_s"
10739 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10740 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10744 [(set_attr "type" "atrans_media")])
10746 (define_insn "ftrv"
10747 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10751 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10752 (parallel [(const_int 0) (const_int 5)
10753 (const_int 10) (const_int 15)]))
10754 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10756 (vec_select:V4SF (match_dup 1)
10757 (parallel [(const_int 4) (const_int 9)
10758 (const_int 14) (const_int 3)]))
10759 (vec_select:V4SF (match_dup 2)
10760 (parallel [(const_int 1) (const_int 2)
10761 (const_int 3) (const_int 0)]))))
10764 (vec_select:V4SF (match_dup 1)
10765 (parallel [(const_int 8) (const_int 13)
10766 (const_int 2) (const_int 7)]))
10767 (vec_select:V4SF (match_dup 2)
10768 (parallel [(const_int 2) (const_int 3)
10769 (const_int 0) (const_int 1)])))
10771 (vec_select:V4SF (match_dup 1)
10772 (parallel [(const_int 12) (const_int 1)
10773 (const_int 6) (const_int 11)]))
10774 (vec_select:V4SF (match_dup 2)
10775 (parallel [(const_int 3) (const_int 0)
10776 (const_int 1) (const_int 2)]))))))]
10778 "ftrv.s %1, %2, %0"
10779 [(set_attr "type" "fparith_media")])
10782 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10783 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10787 [(set_attr "type" "arith_media")])
10789 (define_insn "nsbsi"
10790 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10792 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10796 [(set_attr "type" "arith_media")])
10798 (define_insn "nsbdi"
10799 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10801 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10805 [(set_attr "type" "arith_media")])
10807 (define_expand "ffsdi2"
10808 [(set (match_operand:DI 0 "arith_reg_dest" "")
10809 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10813 rtx scratch = gen_reg_rtx (DImode);
10816 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10817 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10818 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10819 emit_insn (gen_nsbdi (scratch, scratch));
10820 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10821 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10822 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10824 = gen_rtx_EXPR_LIST (REG_EQUAL,
10825 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10829 (define_expand "ffssi2"
10830 [(set (match_operand:SI 0 "arith_reg_dest" "")
10831 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10835 rtx scratch = gen_reg_rtx (SImode);
10836 rtx discratch = gen_reg_rtx (DImode);
10839 emit_insn (gen_adddi3 (discratch,
10840 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10842 emit_insn (gen_andcdi3 (discratch,
10843 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10845 emit_insn (gen_nsbsi (scratch, discratch));
10846 last = emit_insn (gen_subsi3 (operands[0],
10847 force_reg (SImode, GEN_INT (63)), scratch));
10849 = gen_rtx_EXPR_LIST (REG_EQUAL,
10850 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10854 (define_insn "byterev"
10855 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10856 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10857 (parallel [(const_int 7) (const_int 6) (const_int 5)
10858 (const_int 4) (const_int 3) (const_int 2)
10859 (const_int 1) (const_int 0)])))]
10862 [(set_attr "type" "arith_media")])
10864 (define_insn "prefetch"
10865 [(prefetch (match_operand:QI 0 "address_operand" "p")
10866 (match_operand:SI 1 "const_int_operand" "n")
10867 (match_operand:SI 2 "const_int_operand" "n"))]
10868 "TARGET_SHMEDIA || TARGET_HARD_SH4"
10871 if (TARGET_HARD_SH4)
10872 return \"pref @%0\";
10873 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10874 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10877 [(set_attr "type" "other")])