1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
138 (UNSPEC_EH_RETURN 19)
147 ;; These are used with unspec_volatile.
153 (UNSPECV_WINDOW_END 10)
154 (UNSPECV_CONST_END 11)
157 ;; -------------------------------------------------------------------------
159 ;; -------------------------------------------------------------------------
164 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165 (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
186 ;; cbranch conditional branch instructions
187 ;; jump unconditional jumps
188 ;; arith ordinary arithmetic
189 ;; arith3 a compound insn that behaves similarly to a sequence of
190 ;; three insns of type arith
191 ;; arith3b like above, but might end with a redirected branch
193 ;; load_si Likewise, SImode variant for general register.
194 ;; fload Likewise, but load to fp register.
196 ;; move general purpose register to register
197 ;; mt_group other sh4 mt instructions
198 ;; fmove register to register, floating point
199 ;; smpy word precision integer multiply
200 ;; dmpy longword or doublelongword precision integer multiply
202 ;; pload load of pr reg, which can't be put into delay slot of rts
203 ;; prset copy register to pr reg, ditto
204 ;; pstore store of pr reg, which can't be put into delay slot of jsr
205 ;; prget copy pr to register, ditto
206 ;; pcload pc relative load of constant value
207 ;; pcfload Likewise, but load to fp register.
208 ;; pcload_si Likewise, SImode variant for general register.
209 ;; rte return from exception
210 ;; sfunc special function call with known used registers
211 ;; call function call
213 ;; fdiv floating point divide (or square root)
214 ;; gp_fpul move from general purpose register to fpul
215 ;; fpul_gp move from fpul to general purpose register
216 ;; mac_gp move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s fix_truncsfsi2_i4
219 ;; dfdiv double precision floating point divide (or square root)
220 ;; cwb ic_invalidate_line_i
221 ;; movua SH4a unaligned load
222 ;; fsrra square root reciprocal approximate
223 ;; fsca sine and cosine approximate
224 ;; tls_load load TLS related address
225 ;; arith_media SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media SHmedia compare instructions
228 ;; dfdiv_media SHmedia double precision divide and square root
229 ;; dfmul_media SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media SHmedia longword multiply
233 ;; fcmp_media SHmedia floating point compare instructions
234 ;; fdiv_media SHmedia single precision divide and square root
235 ;; fload_media SHmedia floating point register load instructions
236 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media SHmedia unconditional branch instructions
243 ;; load_media SHmedia general register load instructions
244 ;; pt_media SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media SHmedia ptabs instruction
246 ;; store_media SHmedia general register store instructions
247 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media SHmedia mac-style fixed point operations
249 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
250 ;; atrans SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil no-op move, will be deleted.
255 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
256 (const_string "other"))
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
261 ;; mt_group SH4 "mt" group instructions.
263 ;; ex_group SH4 "ex" group instructions.
265 ;; ls_group SH4 "ls" group instructions.
268 (define_attr "insn_class"
269 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273 (eq_attr "type" "cbranch,jump") (const_string "br_group")
274 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275 (const_string "fe_group")
276 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
277 (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long. Something in the
296 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
301 ;; The maximum range used for SImode constant pool entries is 1018. A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table. That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
319 (define_attr "short_cbranch_p" "no,yes"
320 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
322 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
324 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
326 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
328 ] (const_string "no")))
330 (define_attr "med_branch_p" "no,yes"
331 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
334 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
339 ] (const_string "no")))
341 (define_attr "med_cbranch_p" "no,yes"
342 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
345 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
347 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
350 ] (const_string "no")))
352 (define_attr "braf_branch_p" "no,yes"
353 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
358 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
360 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
363 ] (const_string "no")))
365 (define_attr "braf_cbranch_p" "no,yes"
366 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
368 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
371 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
373 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
376 ] (const_string "no")))
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
385 ; All other instructions are two bytes long by default.
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390 (cond [(eq_attr "type" "cbranch")
391 (cond [(eq_attr "short_cbranch_p" "yes")
393 (eq_attr "med_cbranch_p" "yes")
395 (eq_attr "braf_cbranch_p" "yes")
397 ;; ??? using pc is not computed transitively.
398 (ne (match_dup 0) (match_dup 0))
400 (ne (symbol_ref ("flag_pic")) (const_int 0))
403 (eq_attr "type" "jump")
404 (cond [(eq_attr "med_branch_p" "yes")
406 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
408 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409 (symbol_ref "code_for_indirect_jump_scratch")))
410 (cond [(eq_attr "braf_branch_p" "yes")
412 (eq (symbol_ref "flag_pic") (const_int 0))
414 (ne (symbol_ref "TARGET_SH2") (const_int 0))
415 (const_int 10)] (const_int 18))
416 (eq_attr "braf_branch_p" "yes")
418 ;; ??? using pc is not computed transitively.
419 (ne (match_dup 0) (match_dup 0))
421 (ne (symbol_ref ("flag_pic")) (const_int 0))
424 (eq_attr "type" "pt_media")
425 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
426 (const_int 20) (const_int 12))
427 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
431 ;; DFA descriptions for the pipelines
434 (include "shmedia.md")
437 ;; Definitions for filling delay slots
439 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
441 ;; ??? This should be (nil) instead of (const_int 0)
442 (define_attr "hit_stack" "yes,no"
443 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
446 (const_string "yes")))
448 (define_attr "interrupt_function" "no,yes"
449 (const (symbol_ref "current_function_interrupt")))
451 (define_attr "in_delay_slot" "yes,no"
452 (cond [(eq_attr "type" "cbranch") (const_string "no")
453 (eq_attr "type" "pcload,pcload_si") (const_string "no")
454 (eq_attr "needs_delay_slot" "yes") (const_string "no")
455 (eq_attr "length" "2") (const_string "yes")
456 ] (const_string "no")))
458 (define_attr "cond_delay_slot" "yes,no"
459 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
460 ] (const_string "no")))
462 (define_attr "is_sfunc" ""
463 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
465 (define_attr "is_mac_media" ""
466 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
468 (define_attr "branch_zero" "yes,no"
469 (cond [(eq_attr "type" "!cbranch") (const_string "no")
470 (ne (symbol_ref "(next_active_insn (insn)\
471 == (prev_active_insn\
472 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
473 && get_attr_length (next_active_insn (insn)) == 2")
475 (const_string "yes")]
476 (const_string "no")))
478 ;; SH4 Double-precision computation with double-precision result -
479 ;; the two halves are ready at different times.
480 (define_attr "dfp_comp" "yes,no"
481 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
482 (const_string "no")))
484 ;; Insns for which the latency of a preceding fp insn is decreased by one.
485 (define_attr "late_fp_use" "yes,no" (const_string "no"))
486 ;; And feeding insns for which this relevant.
487 (define_attr "any_fp_comp" "yes,no"
488 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
489 (const_string "yes")]
490 (const_string "no")))
492 (define_attr "any_int_load" "yes,no"
493 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
494 (const_string "yes")]
495 (const_string "no")))
498 (eq_attr "needs_delay_slot" "yes")
499 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
501 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
502 ;; and thus we can't put a pop instruction in its delay slot.
503 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
504 ;; instruction can go in the delay slot.
506 ;; Since a normal return (rts) implicitly uses the PR register,
507 ;; we can't allow PR register loads in an rts delay slot.
510 (eq_attr "type" "return")
511 [(and (eq_attr "in_delay_slot" "yes")
512 (ior (and (eq_attr "interrupt_function" "no")
513 (eq_attr "type" "!pload,prset"))
514 (and (eq_attr "interrupt_function" "yes")
516 (ne (symbol_ref "TARGET_SH3") (const_int 0))
517 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
519 ;; Since a call implicitly uses the PR register, we can't allow
520 ;; a PR register store in a jsr delay slot.
523 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
524 [(and (eq_attr "in_delay_slot" "yes")
525 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
527 ;; Say that we have annulled true branches, since this gives smaller and
528 ;; faster code when branches are predicted as not taken.
530 ;; ??? The non-annulled condition should really be "in_delay_slot",
531 ;; but insns that can be filled in non-annulled get priority over insns
532 ;; that can only be filled in anulled.
535 (and (eq_attr "type" "cbranch")
536 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
537 ;; SH2e has a hardware bug that pretty much prohibits the use of
538 ;; annuled delay slots.
539 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
540 (not (eq_attr "cpu" "sh2e"))) (nil)])
542 ;; -------------------------------------------------------------------------
543 ;; SImode signed integer comparisons
544 ;; -------------------------------------------------------------------------
548 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
549 (match_operand:SI 1 "arith_operand" "K08,r"))
553 [(set_attr "type" "mt_group")])
555 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
556 ;; That would still allow reload to create cmpi instructions, but would
557 ;; perhaps allow forcing the constant into a register when that is better.
558 ;; Probably should use r0 for mem/imm compares, but force constant into a
559 ;; register for pseudo/imm compares.
561 (define_insn "cmpeqsi_t"
563 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
564 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
570 [(set_attr "type" "mt_group")])
572 (define_insn "cmpgtsi_t"
574 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
575 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
580 [(set_attr "type" "mt_group")])
582 (define_insn "cmpgesi_t"
584 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
585 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
590 [(set_attr "type" "mt_group")])
592 ;; -------------------------------------------------------------------------
593 ;; SImode unsigned integer comparisons
594 ;; -------------------------------------------------------------------------
596 (define_insn "cmpgeusi_t"
598 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
599 (match_operand:SI 1 "arith_reg_operand" "r")))]
602 [(set_attr "type" "mt_group")])
604 (define_insn "cmpgtusi_t"
606 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
607 (match_operand:SI 1 "arith_reg_operand" "r")))]
610 [(set_attr "type" "mt_group")])
612 ;; We save the compare operands in the cmpxx patterns and use them when
613 ;; we generate the branch.
615 (define_expand "cmpsi"
617 (compare (match_operand:SI 0 "cmpsi_operand" "")
618 (match_operand:SI 1 "arith_operand" "")))]
622 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
623 && GET_CODE (operands[1]) != CONST_INT)
624 operands[0] = copy_to_mode_reg (SImode, operands[0]);
625 sh_compare_op0 = operands[0];
626 sh_compare_op1 = operands[1];
630 ;; -------------------------------------------------------------------------
631 ;; DImode signed integer comparisons
632 ;; -------------------------------------------------------------------------
634 ;; ??? Could get better scheduling by splitting the initial test from the
635 ;; rest of the insn after reload. However, the gain would hardly justify
636 ;; the sh.md size increase necessary to do that.
640 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
641 (match_operand:DI 1 "arith_operand" "r"))
644 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
646 [(set_attr "length" "6")
647 (set_attr "type" "arith3b")])
649 (define_insn "cmpeqdi_t"
651 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
652 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
655 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
656 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
657 [(set_attr "length" "6")
658 (set_attr "type" "arith3b")])
662 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
663 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
664 ;; If we applied this split when not optimizing, it would only be
665 ;; applied during the machine-dependent reorg, when no new basic blocks
667 "TARGET_SH1 && reload_completed && optimize"
668 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
669 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
670 (label_ref (match_dup 6))
672 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
677 = gen_rtx_REG (SImode,
678 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
680 = (operands[1] == const0_rtx
682 : gen_rtx_REG (SImode,
683 true_regnum (operands[1])
684 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
685 operands[4] = gen_lowpart (SImode, operands[0]);
686 operands[5] = gen_lowpart (SImode, operands[1]);
687 operands[6] = gen_label_rtx ();
690 (define_insn "cmpgtdi_t"
692 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
693 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
696 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
697 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
698 [(set_attr "length" "8")
699 (set_attr "type" "arith3")])
701 (define_insn "cmpgedi_t"
703 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
704 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
707 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
709 [(set_attr "length" "8,2")
710 (set_attr "type" "arith3,mt_group")])
712 ;; -------------------------------------------------------------------------
713 ;; DImode unsigned integer comparisons
714 ;; -------------------------------------------------------------------------
716 (define_insn "cmpgeudi_t"
718 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
719 (match_operand:DI 1 "arith_reg_operand" "r")))]
721 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
722 [(set_attr "length" "8")
723 (set_attr "type" "arith3")])
725 (define_insn "cmpgtudi_t"
727 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
728 (match_operand:DI 1 "arith_reg_operand" "r")))]
730 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
731 [(set_attr "length" "8")
732 (set_attr "type" "arith3")])
734 (define_insn "cmpeqdi_media"
735 [(set (match_operand:DI 0 "register_operand" "=r")
736 (eq:DI (match_operand:DI 1 "register_operand" "%r")
737 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
740 [(set_attr "type" "cmp_media")])
742 (define_insn "cmpgtdi_media"
743 [(set (match_operand:DI 0 "register_operand" "=r")
744 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
745 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
748 [(set_attr "type" "cmp_media")])
750 (define_insn "cmpgtudi_media"
751 [(set (match_operand:DI 0 "register_operand" "=r")
752 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
753 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
755 "cmpgtu %N1, %N2, %0"
756 [(set_attr "type" "cmp_media")])
758 ;; We save the compare operands in the cmpxx patterns and use them when
759 ;; we generate the branch.
761 (define_expand "cmpdi"
763 (compare (match_operand:DI 0 "arith_operand" "")
764 (match_operand:DI 1 "arith_operand" "")))]
765 "TARGET_SH2 || TARGET_SHMEDIA"
768 sh_compare_op0 = operands[0];
769 sh_compare_op1 = operands[1];
772 ;; -------------------------------------------------------------------------
773 ;; Conditional move instructions
774 ;; -------------------------------------------------------------------------
776 ;; The insn names may seem reversed, but note that cmveq performs the move
777 ;; if op1 == 0, and cmvne does it if op1 != 0.
779 (define_insn "movdicc_false"
780 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
781 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
783 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
784 (match_operand:DI 3 "arith_reg_operand" "0")))]
787 [(set_attr "type" "arith_media")])
789 (define_insn "movdicc_true"
790 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
791 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
793 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
794 (match_operand:DI 3 "arith_reg_operand" "0")))]
797 [(set_attr "type" "arith_media")])
799 (define_expand "movdicc"
800 [(set (match_operand:DI 0 "register_operand" "")
801 (if_then_else:DI (match_operand 1 "comparison_operator" "")
802 (match_operand:DI 2 "register_operand" "")
803 (match_operand:DI 3 "register_operand" "")))]
807 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
808 && GET_MODE (sh_compare_op0) == DImode
809 && sh_compare_op1 == const0_rtx)
810 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
811 sh_compare_op0, sh_compare_op1);
819 tmp = gen_reg_rtx (DImode);
821 switch (GET_CODE (operands[1]))
824 emit_insn (gen_seq (tmp));
825 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
829 emit_insn (gen_seq (tmp));
830 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
834 emit_insn (gen_sgt (tmp));
835 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
839 emit_insn (gen_slt (tmp));
840 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
844 emit_insn (gen_slt (tmp));
845 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
849 emit_insn (gen_sgt (tmp));
850 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
854 emit_insn (gen_sgtu (tmp));
855 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
859 emit_insn (gen_sltu (tmp));
860 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
864 emit_insn (gen_sltu (tmp));
865 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
869 emit_insn (gen_sgtu (tmp));
870 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
874 emit_insn (gen_sunordered (tmp));
875 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
879 emit_insn (gen_sunordered (tmp));
880 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
897 ;; -------------------------------------------------------------------------
898 ;; Addition instructions
899 ;; -------------------------------------------------------------------------
901 (define_expand "adddi3"
902 [(set (match_operand:DI 0 "arith_reg_operand" "")
903 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
904 (match_operand:DI 2 "arith_operand" "")))]
910 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
912 operands[2] = force_reg (DImode, operands[2]);
913 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
918 (define_insn "*adddi3_media"
919 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
920 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
921 (match_operand:DI 2 "arith_operand" "r,I10")))]
926 [(set_attr "type" "arith_media")])
928 (define_insn "adddi3z_media"
929 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
931 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
932 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
935 [(set_attr "type" "arith_media")])
937 (define_insn "adddi3_compact"
938 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
939 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
940 (match_operand:DI 2 "arith_reg_operand" "r")))
941 (clobber (reg:SI T_REG))]
944 [(set_attr "length" "6")])
947 [(set (match_operand:DI 0 "arith_reg_operand" "")
948 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
949 (match_operand:DI 2 "arith_reg_operand" "")))
950 (clobber (reg:SI T_REG))]
951 "TARGET_SH1 && reload_completed"
955 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
956 high0 = gen_rtx_REG (SImode,
957 true_regnum (operands[0])
958 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959 high2 = gen_rtx_REG (SImode,
960 true_regnum (operands[2])
961 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
962 emit_insn (gen_clrt ());
963 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
964 emit_insn (gen_addc1 (high0, high0, high2));
969 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
970 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
971 (match_operand:SI 2 "arith_reg_operand" "r"))
974 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
977 [(set_attr "type" "arith")])
980 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
981 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
982 (match_operand:SI 2 "arith_reg_operand" "r"))
984 (clobber (reg:SI T_REG))]
987 [(set_attr "type" "arith")])
989 (define_expand "addsi3"
990 [(set (match_operand:SI 0 "arith_reg_operand" "")
991 (plus:SI (match_operand:SI 1 "arith_operand" "")
992 (match_operand:SI 2 "arith_operand" "")))]
997 operands[1] = force_reg (SImode, operands[1]);
1000 (define_insn "addsi3_media"
1001 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1002 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1003 (match_operand:SI 2 "arith_operand" "r,I10")))]
1008 [(set_attr "type" "arith_media")])
1010 (define_insn "*addsi3_compact"
1011 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1012 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1013 (match_operand:SI 2 "arith_operand" "rI08")))]
1016 [(set_attr "type" "arith")])
1018 ;; -------------------------------------------------------------------------
1019 ;; Subtraction instructions
1020 ;; -------------------------------------------------------------------------
1022 (define_expand "subdi3"
1023 [(set (match_operand:DI 0 "arith_reg_operand" "")
1024 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1025 (match_operand:DI 2 "arith_reg_operand" "")))]
1031 operands[1] = force_reg (DImode, operands[1]);
1032 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1037 (define_insn "*subdi3_media"
1038 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1039 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1040 (match_operand:DI 2 "arith_reg_operand" "r")))]
1043 [(set_attr "type" "arith_media")])
1045 (define_insn "subdi3_compact"
1046 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1047 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1048 (match_operand:DI 2 "arith_reg_operand" "r")))
1049 (clobber (reg:SI T_REG))]
1052 [(set_attr "length" "6")])
1055 [(set (match_operand:DI 0 "arith_reg_operand" "")
1056 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1057 (match_operand:DI 2 "arith_reg_operand" "")))
1058 (clobber (reg:SI T_REG))]
1059 "TARGET_SH1 && reload_completed"
1063 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1064 high0 = gen_rtx_REG (SImode,
1065 true_regnum (operands[0])
1066 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067 high2 = gen_rtx_REG (SImode,
1068 true_regnum (operands[2])
1069 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1070 emit_insn (gen_clrt ());
1071 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1072 emit_insn (gen_subc1 (high0, high0, high2));
1077 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1078 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1079 (match_operand:SI 2 "arith_reg_operand" "r"))
1082 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1087 [(set_attr "type" "arith")])
1089 (define_insn "subc1"
1090 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1091 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1092 (match_operand:SI 2 "arith_reg_operand" "r"))
1094 (clobber (reg:SI T_REG))]
1097 [(set_attr "type" "arith")])
1099 (define_insn "*subsi3_internal"
1100 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1101 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1102 (match_operand:SI 2 "arith_reg_operand" "r")))]
1105 [(set_attr "type" "arith")])
1107 (define_insn "*subsi3_media"
1108 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1109 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1110 (match_operand:SI 2 "extend_reg_operand" "r")))]
1113 [(set_attr "type" "arith_media")])
1115 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1116 ;; will sometimes save one instruction. Otherwise we might get
1117 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1120 (define_expand "subsi3"
1121 [(set (match_operand:SI 0 "arith_reg_operand" "")
1122 (minus:SI (match_operand:SI 1 "arith_operand" "")
1123 (match_operand:SI 2 "arith_reg_operand" "")))]
1127 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1129 emit_insn (gen_negsi2 (operands[0], operands[2]));
1130 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1135 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1137 if (operands[1] != const0_rtx)
1138 operands[1] = force_reg (SImode, operands[1]);
1142 ;; -------------------------------------------------------------------------
1143 ;; Division instructions
1144 ;; -------------------------------------------------------------------------
1146 ;; We take advantage of the library routines which don't clobber as many
1147 ;; registers as a normal function call would.
1149 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1150 ;; also has an effect on the register that holds the address of the sfunc.
1151 ;; To make this work, we have an extra dummy insn that shows the use
1152 ;; of this register for reorg.
1154 (define_insn "use_sfunc_addr"
1155 [(set (reg:SI PR_REG)
1156 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1157 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1159 [(set_attr "length" "0")])
1161 (define_insn "udivsi3_sh2a"
1162 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1163 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1164 (match_operand:SI 2 "arith_reg_operand" "z")))]
1167 [(set_attr "type" "arith")])
1169 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1170 ;; hard register 0. If we used hard register 0, then the next instruction
1171 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1172 ;; gets allocated to a stack slot that needs its address reloaded, then
1173 ;; there is nothing to prevent reload from using r0 to reload the address.
1174 ;; This reload would clobber the value in r0 we are trying to store.
1175 ;; If we let reload allocate r0, then this problem can never happen.
1177 (define_insn "udivsi3_i1"
1178 [(set (match_operand:SI 0 "register_operand" "=z")
1179 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1180 (clobber (reg:SI T_REG))
1181 (clobber (reg:SI PR_REG))
1182 (clobber (reg:SI R4_REG))
1183 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1184 "TARGET_SH1 && ! TARGET_SH4"
1186 [(set_attr "type" "sfunc")
1187 (set_attr "needs_delay_slot" "yes")])
1189 ; Since shmedia-nofpu code could be linked against shcompact code, and
1190 ; the udivsi3 libcall has the same name, we must consider all registers
1191 ; clobbered that are in the union of the registers clobbered by the
1192 ; shmedia and the shcompact implementation. Note, if the shcompact
1193 ; implementation actually used shcompact code, we'd need to clobber
1194 ; also r23 and fr23.
1195 (define_insn "udivsi3_i1_media"
1196 [(set (match_operand:SI 0 "register_operand" "=z")
1197 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1198 (clobber (reg:SI T_MEDIA_REG))
1199 (clobber (reg:SI PR_MEDIA_REG))
1200 (clobber (reg:SI R20_REG))
1201 (clobber (reg:SI R21_REG))
1202 (clobber (reg:SI R22_REG))
1203 (clobber (reg:DI TR0_REG))
1204 (clobber (reg:DI TR1_REG))
1205 (clobber (reg:DI TR2_REG))
1206 (use (match_operand:DI 1 "target_operand" "b"))]
1207 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1209 [(set_attr "type" "sfunc")
1210 (set_attr "needs_delay_slot" "yes")])
1212 (define_expand "udivsi3_i4_media"
1214 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1216 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1217 (set (match_dup 5) (float:DF (match_dup 3)))
1218 (set (match_dup 6) (float:DF (match_dup 4)))
1219 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1220 (set (match_dup 8) (fix:DI (match_dup 7)))
1221 (set (match_operand:SI 0 "register_operand" "")
1222 (truncate:SI (match_dup 8)))]
1223 "TARGET_SHMEDIA_FPU"
1226 operands[3] = gen_reg_rtx (DImode);
1227 operands[4] = gen_reg_rtx (DImode);
1228 operands[5] = gen_reg_rtx (DFmode);
1229 operands[6] = gen_reg_rtx (DFmode);
1230 operands[7] = gen_reg_rtx (DFmode);
1231 operands[8] = gen_reg_rtx (DImode);
1234 (define_insn "udivsi3_i4"
1235 [(set (match_operand:SI 0 "register_operand" "=y")
1236 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1237 (clobber (reg:SI T_REG))
1238 (clobber (reg:SI PR_REG))
1239 (clobber (reg:DF DR0_REG))
1240 (clobber (reg:DF DR2_REG))
1241 (clobber (reg:DF DR4_REG))
1242 (clobber (reg:SI R0_REG))
1243 (clobber (reg:SI R1_REG))
1244 (clobber (reg:SI R4_REG))
1245 (clobber (reg:SI R5_REG))
1246 (use (reg:PSI FPSCR_REG))
1247 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1248 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1250 [(set_attr "type" "sfunc")
1251 (set_attr "fp_mode" "double")
1252 (set_attr "needs_delay_slot" "yes")])
1254 (define_insn "udivsi3_i4_single"
1255 [(set (match_operand:SI 0 "register_operand" "=y")
1256 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1257 (clobber (reg:SI T_REG))
1258 (clobber (reg:SI PR_REG))
1259 (clobber (reg:DF DR0_REG))
1260 (clobber (reg:DF DR2_REG))
1261 (clobber (reg:DF DR4_REG))
1262 (clobber (reg:SI R0_REG))
1263 (clobber (reg:SI R1_REG))
1264 (clobber (reg:SI R4_REG))
1265 (clobber (reg:SI R5_REG))
1266 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1269 [(set_attr "type" "sfunc")
1270 (set_attr "needs_delay_slot" "yes")])
1272 (define_expand "udivsi3"
1273 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1274 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1275 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1276 (parallel [(set (match_operand:SI 0 "register_operand" "")
1277 (udiv:SI (reg:SI R4_REG)
1279 (clobber (reg:SI T_REG))
1280 (clobber (reg:SI PR_REG))
1281 (clobber (reg:SI R4_REG))
1282 (use (match_dup 3))])]
1288 operands[3] = gen_reg_rtx (Pmode);
1289 /* Emit the move of the address to a pseudo outside of the libcall. */
1290 if (TARGET_HARD_SH4 && TARGET_SH2E)
1292 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1293 if (TARGET_FPU_SINGLE)
1294 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1296 last = gen_udivsi3_i4 (operands[0], operands[3]);
1298 else if (TARGET_SHMEDIA_FPU)
1300 operands[1] = force_reg (SImode, operands[1]);
1301 operands[2] = force_reg (SImode, operands[2]);
1302 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1305 else if (TARGET_SH2A)
1307 operands[1] = force_reg (SImode, operands[1]);
1308 operands[2] = force_reg (SImode, operands[2]);
1309 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1312 else if (TARGET_SH5)
1314 emit_move_insn (operands[3],
1315 function_symbol (TARGET_FPU_ANY
1320 last = gen_udivsi3_i1_media (operands[0],
1323 : gen_rtx_SUBREG (DImode, operands[3],
1325 else if (TARGET_FPU_ANY)
1326 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1328 last = gen_udivsi3_i1 (operands[0], operands[3]);
1332 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1333 last = gen_udivsi3_i1 (operands[0], operands[3]);
1335 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1336 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1337 last = emit_insn (last);
1338 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1339 invariant code motion can move it. */
1340 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1341 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1345 (define_insn "divsi3_sh2a"
1346 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1347 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348 (match_operand:SI 2 "arith_reg_operand" "z")))]
1351 [(set_attr "type" "arith")])
1353 (define_insn "divsi3_i1"
1354 [(set (match_operand:SI 0 "register_operand" "=z")
1355 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1356 (clobber (reg:SI T_REG))
1357 (clobber (reg:SI PR_REG))
1358 (clobber (reg:SI R1_REG))
1359 (clobber (reg:SI R2_REG))
1360 (clobber (reg:SI R3_REG))
1361 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1362 "TARGET_SH1 && ! TARGET_SH4"
1364 [(set_attr "type" "sfunc")
1365 (set_attr "needs_delay_slot" "yes")])
1367 ; Since shmedia-nofpu code could be linked against shcompact code, and
1368 ; the sdivsi3 libcall has the same name, we must consider all registers
1369 ; clobbered that are in the union of the registers clobbered by the
1370 ; shmedia and the shcompact implementation. Note, if the shcompact
1371 ; implementation actually used shcompact code, we'd need to clobber
1372 ; also r22, r23 and fr23.
1373 (define_insn "divsi3_i1_media"
1374 [(set (match_operand:SI 0 "register_operand" "=z")
1375 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1376 (clobber (reg:SI T_MEDIA_REG))
1377 (clobber (reg:SI PR_MEDIA_REG))
1378 (clobber (reg:SI R1_REG))
1379 (clobber (reg:SI R2_REG))
1380 (clobber (reg:SI R3_REG))
1381 (clobber (reg:SI R20_REG))
1382 (clobber (reg:SI R21_REG))
1383 (clobber (reg:DI TR0_REG))
1384 (clobber (reg:DI TR1_REG))
1385 (clobber (reg:DI TR2_REG))
1386 (use (match_operand:DI 1 "target_operand" "b"))]
1387 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1389 [(set_attr "type" "sfunc")])
1391 (define_expand "divsi3_i4_media"
1392 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1393 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1394 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1395 (set (match_operand:SI 0 "register_operand" "=r")
1396 (fix:SI (match_dup 5)))]
1397 "TARGET_SHMEDIA_FPU"
1400 operands[3] = gen_reg_rtx (DFmode);
1401 operands[4] = gen_reg_rtx (DFmode);
1402 operands[5] = gen_reg_rtx (DFmode);
1405 (define_insn "divsi3_i4"
1406 [(set (match_operand:SI 0 "register_operand" "=y")
1407 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1408 (clobber (reg:SI PR_REG))
1409 (clobber (reg:DF DR0_REG))
1410 (clobber (reg:DF DR2_REG))
1411 (use (reg:PSI FPSCR_REG))
1412 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1413 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1415 [(set_attr "type" "sfunc")
1416 (set_attr "fp_mode" "double")
1417 (set_attr "needs_delay_slot" "yes")])
1419 (define_insn "divsi3_i4_single"
1420 [(set (match_operand:SI 0 "register_operand" "=y")
1421 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1422 (clobber (reg:SI PR_REG))
1423 (clobber (reg:DF DR0_REG))
1424 (clobber (reg:DF DR2_REG))
1425 (clobber (reg:SI R2_REG))
1426 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1427 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1429 [(set_attr "type" "sfunc")
1430 (set_attr "needs_delay_slot" "yes")])
1432 (define_expand "divsi3"
1433 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1434 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1435 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1436 (parallel [(set (match_operand:SI 0 "register_operand" "")
1437 (div:SI (reg:SI R4_REG)
1439 (clobber (reg:SI T_REG))
1440 (clobber (reg:SI PR_REG))
1441 (clobber (reg:SI R1_REG))
1442 (clobber (reg:SI R2_REG))
1443 (clobber (reg:SI R3_REG))
1444 (use (match_dup 3))])]
1450 operands[3] = gen_reg_rtx (Pmode);
1451 /* Emit the move of the address to a pseudo outside of the libcall. */
1452 if (TARGET_HARD_SH4 && TARGET_SH2E)
1454 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1455 if (TARGET_FPU_SINGLE)
1456 last = gen_divsi3_i4_single (operands[0], operands[3]);
1458 last = gen_divsi3_i4 (operands[0], operands[3]);
1460 else if (TARGET_SH2A)
1462 operands[1] = force_reg (SImode, operands[1]);
1463 operands[2] = force_reg (SImode, operands[2]);
1464 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1467 else if (TARGET_SHMEDIA_FPU)
1469 operands[1] = force_reg (SImode, operands[1]);
1470 operands[2] = force_reg (SImode, operands[2]);
1471 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1474 else if (TARGET_SH5)
1476 emit_move_insn (operands[3],
1477 function_symbol (TARGET_FPU_ANY
1482 last = gen_divsi3_i1_media (operands[0],
1485 : gen_rtx_SUBREG (DImode, operands[3],
1487 else if (TARGET_FPU_ANY)
1488 last = gen_divsi3_i4_single (operands[0], operands[3]);
1490 last = gen_divsi3_i1 (operands[0], operands[3]);
1494 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1495 last = gen_divsi3_i1 (operands[0], operands[3]);
1497 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1498 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1499 last = emit_insn (last);
1500 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1501 invariant code motion can move it. */
1502 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1503 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1507 ;; -------------------------------------------------------------------------
1508 ;; Multiplication instructions
1509 ;; -------------------------------------------------------------------------
1511 (define_insn "umulhisi3_i"
1512 [(set (reg:SI MACL_REG)
1513 (mult:SI (zero_extend:SI
1514 (match_operand:HI 0 "arith_reg_operand" "r"))
1516 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1519 [(set_attr "type" "smpy")])
1521 (define_insn "mulhisi3_i"
1522 [(set (reg:SI MACL_REG)
1523 (mult:SI (sign_extend:SI
1524 (match_operand:HI 0 "arith_reg_operand" "r"))
1526 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1529 [(set_attr "type" "smpy")])
1531 (define_expand "mulhisi3"
1532 [(set (reg:SI MACL_REG)
1533 (mult:SI (sign_extend:SI
1534 (match_operand:HI 1 "arith_reg_operand" ""))
1536 (match_operand:HI 2 "arith_reg_operand" ""))))
1537 (set (match_operand:SI 0 "arith_reg_operand" "")
1544 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1545 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1546 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1547 invariant code motion can move it. */
1548 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1549 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1550 /* expand_binop can't find a suitable code in umul_widen_optab to
1551 make a REG_EQUAL note from, so make one here.
1552 See also smulsi3_highpart.
1553 ??? Alternatively, we could put this at the calling site of expand_binop,
1554 i.e. expand_expr. */
1556 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1561 (define_expand "umulhisi3"
1562 [(set (reg:SI MACL_REG)
1563 (mult:SI (zero_extend:SI
1564 (match_operand:HI 1 "arith_reg_operand" ""))
1566 (match_operand:HI 2 "arith_reg_operand" ""))))
1567 (set (match_operand:SI 0 "arith_reg_operand" "")
1574 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1575 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1576 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1577 invariant code motion can move it. */
1578 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1579 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1580 /* expand_binop can't find a suitable code in umul_widen_optab to
1581 make a REG_EQUAL note from, so make one here.
1582 See also smulsi3_highpart.
1583 ??? Alternatively, we could put this at the calling site of expand_binop,
1584 i.e. expand_expr. */
1586 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1591 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1592 ;; a call to a routine which clobbers known registers.
1595 [(set (match_operand:SI 1 "register_operand" "=z")
1596 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1597 (clobber (reg:SI MACL_REG))
1598 (clobber (reg:SI T_REG))
1599 (clobber (reg:SI PR_REG))
1600 (clobber (reg:SI R3_REG))
1601 (clobber (reg:SI R2_REG))
1602 (clobber (reg:SI R1_REG))
1603 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1606 [(set_attr "type" "sfunc")
1607 (set_attr "needs_delay_slot" "yes")])
1609 (define_expand "mulsi3_call"
1610 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1611 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1612 (parallel[(set (match_operand:SI 0 "register_operand" "")
1613 (mult:SI (reg:SI R4_REG)
1615 (clobber (reg:SI MACL_REG))
1616 (clobber (reg:SI T_REG))
1617 (clobber (reg:SI PR_REG))
1618 (clobber (reg:SI R3_REG))
1619 (clobber (reg:SI R2_REG))
1620 (clobber (reg:SI R1_REG))
1621 (use (match_operand:SI 3 "register_operand" ""))])]
1625 (define_insn "mul_r"
1626 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1627 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1628 (match_operand:SI 2 "arith_reg_operand" "z")))]
1631 [(set_attr "type" "dmpy")])
1633 (define_insn "mul_l"
1634 [(set (reg:SI MACL_REG)
1635 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1636 (match_operand:SI 1 "arith_reg_operand" "r")))]
1639 [(set_attr "type" "dmpy")])
1641 (define_expand "mulsi3"
1642 [(set (reg:SI MACL_REG)
1643 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1644 (match_operand:SI 2 "arith_reg_operand" "")))
1645 (set (match_operand:SI 0 "arith_reg_operand" "")
1654 /* The address must be set outside the libcall,
1655 since it goes into a pseudo. */
1656 rtx sym = function_symbol (\"__mulsi3\");
1657 rtx addr = force_reg (SImode, sym);
1658 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1661 last = emit_insn (insns);
1665 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1667 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1668 /* consec_sets_giv can only recognize the first insn that sets a
1669 giv as the giv insn. So we must tag this also with a REG_EQUAL
1671 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1673 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1674 invariant code motion can move it. */
1675 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1676 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1680 (define_insn "mulsidi3_i"
1681 [(set (reg:SI MACH_REG)
1685 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1686 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1688 (set (reg:SI MACL_REG)
1689 (mult:SI (match_dup 0)
1693 [(set_attr "type" "dmpy")])
1695 (define_expand "mulsidi3"
1696 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1697 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1698 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1699 "TARGET_SH2 || TARGET_SHMEDIA"
1704 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1710 (define_insn "mulsidi3_media"
1711 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1712 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1713 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1716 [(set_attr "type" "dmpy_media")])
1718 (define_insn "mulsidi3_compact"
1719 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1721 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1722 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1723 (clobber (reg:SI MACH_REG))
1724 (clobber (reg:SI MACL_REG))]
1729 [(set (match_operand:DI 0 "arith_reg_operand" "")
1731 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1732 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1733 (clobber (reg:SI MACH_REG))
1734 (clobber (reg:SI MACL_REG))]
1739 rtx low_dst = gen_lowpart (SImode, operands[0]);
1740 rtx high_dst = gen_highpart (SImode, operands[0]);
1742 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1744 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1745 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1746 /* We need something to tag the possible REG_EQUAL notes on to. */
1747 emit_move_insn (operands[0], operands[0]);
1751 (define_insn "umulsidi3_i"
1752 [(set (reg:SI MACH_REG)
1756 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1757 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1759 (set (reg:SI MACL_REG)
1760 (mult:SI (match_dup 0)
1764 [(set_attr "type" "dmpy")])
1766 (define_expand "umulsidi3"
1767 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1768 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1769 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1770 "TARGET_SH2 || TARGET_SHMEDIA"
1775 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1781 (define_insn "umulsidi3_media"
1782 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1783 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1784 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1787 [(set_attr "type" "dmpy_media")])
1789 (define_insn "umulsidi3_compact"
1790 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1792 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1793 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1794 (clobber (reg:SI MACH_REG))
1795 (clobber (reg:SI MACL_REG))]
1800 [(set (match_operand:DI 0 "arith_reg_operand" "")
1801 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1802 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1803 (clobber (reg:SI MACH_REG))
1804 (clobber (reg:SI MACL_REG))]
1809 rtx low_dst = gen_lowpart (SImode, operands[0]);
1810 rtx high_dst = gen_highpart (SImode, operands[0]);
1812 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1814 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1815 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1816 /* We need something to tag the possible REG_EQUAL notes on to. */
1817 emit_move_insn (operands[0], operands[0]);
1821 (define_insn "smulsi3_highpart_i"
1822 [(set (reg:SI MACH_REG)
1826 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1827 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1829 (clobber (reg:SI MACL_REG))]
1832 [(set_attr "type" "dmpy")])
1834 (define_expand "smulsi3_highpart"
1836 [(set (reg:SI MACH_REG)
1840 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1843 (clobber (reg:SI MACL_REG))])
1844 (set (match_operand:SI 0 "arith_reg_operand" "")
1851 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1852 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1853 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1854 invariant code motion can move it. */
1855 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1856 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1857 /* expand_binop can't find a suitable code in mul_highpart_optab to
1858 make a REG_EQUAL note from, so make one here.
1859 See also {,u}mulhisi.
1860 ??? Alternatively, we could put this at the calling site of expand_binop,
1861 i.e. expand_mult_highpart. */
1863 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1868 (define_insn "umulsi3_highpart_i"
1869 [(set (reg:SI MACH_REG)
1873 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1874 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1876 (clobber (reg:SI MACL_REG))]
1879 [(set_attr "type" "dmpy")])
1881 (define_expand "umulsi3_highpart"
1883 [(set (reg:SI MACH_REG)
1887 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1888 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1890 (clobber (reg:SI MACL_REG))])
1891 (set (match_operand:SI 0 "arith_reg_operand" "")
1898 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1899 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1900 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1901 invariant code motion can move it. */
1902 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1903 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1907 ;; -------------------------------------------------------------------------
1908 ;; Logical operations
1909 ;; -------------------------------------------------------------------------
1911 (define_insn "*andsi3_compact"
1912 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1913 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1914 (match_operand:SI 2 "logical_operand" "r,K08")))]
1917 [(set_attr "type" "arith")])
1919 ;; If the constant is 255, then emit an extu.b instruction instead of an
1920 ;; and, since that will give better code.
1922 (define_expand "andsi3"
1923 [(set (match_operand:SI 0 "arith_reg_operand" "")
1924 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1925 (match_operand:SI 2 "logical_operand" "")))]
1929 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1931 emit_insn (gen_zero_extendqisi2 (operands[0],
1932 gen_lowpart (QImode, operands[1])));
1937 (define_insn_and_split "anddi3"
1938 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1939 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1940 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1947 && ! logical_operand (operands[2], DImode)"
1951 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1952 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1954 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1957 [(set_attr "type" "arith_media")])
1959 (define_insn "andcdi3"
1960 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1961 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1962 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1965 [(set_attr "type" "arith_media")])
1967 (define_insn "iorsi3"
1968 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1969 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1970 (match_operand:SI 2 "logical_operand" "r,K08")))]
1973 [(set_attr "type" "arith")])
1975 (define_insn "iordi3"
1976 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1977 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1978 (match_operand:DI 2 "logical_operand" "r,I10")))]
1983 [(set_attr "type" "arith_media")])
1985 (define_insn "xorsi3"
1986 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1987 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1988 (match_operand:SI 2 "logical_operand" "K08,r")))]
1991 [(set_attr "type" "arith")])
1993 (define_insn "xordi3"
1994 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1995 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1996 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2001 [(set_attr "type" "arith_media")])
2003 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2004 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2006 [(set (match_operand:DI 0 "arith_reg_operand" "")
2007 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2008 [(match_operand 1 "any_register_operand" "")
2009 (match_operand 2 "any_register_operand" "")])))]
2011 [(set (match_dup 5) (match_dup 4))
2012 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2015 enum machine_mode inmode = GET_MODE (operands[1]);
2018 if (GET_CODE (operands[0]) == SUBREG)
2020 offset = SUBREG_BYTE (operands[0]);
2021 operands[0] = SUBREG_REG (operands[0]);
2023 if (GET_CODE (operands[0]) != REG)
2025 if (! TARGET_LITTLE_ENDIAN)
2026 offset += 8 - GET_MODE_SIZE (inmode);
2027 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2030 ;; -------------------------------------------------------------------------
2031 ;; Shifts and rotates
2032 ;; -------------------------------------------------------------------------
2034 (define_expand "rotldi3"
2035 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2036 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2037 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2039 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2041 (define_insn "rotldi3_mextr"
2042 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2043 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2044 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2048 static char templ[16];
2050 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2051 8 - (int) (INTVAL (operands[2]) >> 3));
2054 [(set_attr "type" "arith_media")])
2056 (define_expand "rotrdi3"
2057 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2058 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2059 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2061 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2063 (define_insn "rotrdi3_mextr"
2064 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2065 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2066 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2070 static char templ[16];
2072 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2075 [(set_attr "type" "arith_media")])
2077 (define_insn "rotlsi3_1"
2078 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2079 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2082 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2085 [(set_attr "type" "arith")])
2087 (define_insn "rotlsi3_31"
2088 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2089 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2091 (clobber (reg:SI T_REG))]
2094 [(set_attr "type" "arith")])
2096 (define_insn "rotlsi3_16"
2097 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2098 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2102 [(set_attr "type" "arith")])
2104 (define_expand "rotlsi3"
2105 [(set (match_operand:SI 0 "arith_reg_operand" "")
2106 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2107 (match_operand:SI 2 "immediate_operand" "")))]
2111 static const char rot_tab[] = {
2112 000, 000, 000, 000, 000, 000, 010, 001,
2113 001, 001, 011, 013, 003, 003, 003, 003,
2114 003, 003, 003, 003, 003, 013, 012, 002,
2115 002, 002, 010, 000, 000, 000, 000, 000,
2120 if (GET_CODE (operands[2]) != CONST_INT)
2122 count = INTVAL (operands[2]);
2123 choice = rot_tab[count];
2124 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2130 emit_move_insn (operands[0], operands[1]);
2131 count -= (count & 16) * 2;
2134 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2141 parts[0] = gen_reg_rtx (SImode);
2142 parts[1] = gen_reg_rtx (SImode);
2143 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2144 emit_move_insn (parts[choice-1], operands[1]);
2145 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2146 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2147 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2148 count = (count & ~16) - 8;
2152 for (; count > 0; count--)
2153 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2154 for (; count < 0; count++)
2155 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2160 (define_insn "*rotlhi3_8"
2161 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2162 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2166 [(set_attr "type" "arith")])
2168 (define_expand "rotlhi3"
2169 [(set (match_operand:HI 0 "arith_reg_operand" "")
2170 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2171 (match_operand:HI 2 "immediate_operand" "")))]
2175 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2182 (define_insn "ashlsi3_sh2a"
2183 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2184 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2185 (match_operand:SI 2 "arith_reg_operand" "r")))]
2188 [(set_attr "type" "arith")
2189 (set_attr "length" "4")])
2191 ;; This pattern is used by init_expmed for computing the costs of shift
2194 (define_insn_and_split "ashlsi3_std"
2195 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2196 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2197 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2198 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2200 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2201 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2209 && GET_CODE (operands[2]) == CONST_INT
2210 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2211 [(set (match_dup 3) (match_dup 2))
2213 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2214 (clobber (match_dup 4))])]
2215 "operands[4] = gen_rtx_SCRATCH (SImode);"
2216 [(set_attr "length" "*,*,*,4")
2217 (set_attr "type" "dyn_shift,arith,arith,arith")])
2219 (define_insn "ashlhi3_k"
2220 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2221 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2222 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2223 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2227 [(set_attr "type" "arith")])
2229 (define_insn "ashlsi3_n"
2230 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2231 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2232 (match_operand:SI 2 "const_int_operand" "n")))
2233 (clobber (reg:SI T_REG))]
2234 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2236 [(set (attr "length")
2237 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2239 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2241 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2243 (const_string "8")))
2244 (set_attr "type" "arith")])
2247 [(set (match_operand:SI 0 "arith_reg_operand" "")
2248 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2249 (match_operand:SI 2 "const_int_operand" "")))
2250 (clobber (reg:SI T_REG))]
2251 "TARGET_SH1 && reload_completed"
2252 [(use (reg:SI R0_REG))]
2255 gen_shifty_op (ASHIFT, operands);
2259 (define_insn "ashlsi3_media"
2260 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2261 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2262 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2267 [(set_attr "type" "arith_media")])
2269 (define_expand "ashlsi3"
2270 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2271 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2272 (match_operand:SI 2 "nonmemory_operand" "")))
2273 (clobber (reg:SI T_REG))])]
2279 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2282 if (GET_CODE (operands[2]) == CONST_INT
2283 && sh_dynamicalize_shift_p (operands[2]))
2284 operands[2] = force_reg (SImode, operands[2]);
2287 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2290 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2294 (define_insn "ashlhi3"
2295 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2296 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2297 (match_operand:HI 2 "const_int_operand" "n")))
2298 (clobber (reg:SI T_REG))]
2301 [(set (attr "length")
2302 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2304 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2306 (const_string "6")))
2307 (set_attr "type" "arith")])
2310 [(set (match_operand:HI 0 "arith_reg_operand" "")
2311 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2312 (match_operand:HI 2 "const_int_operand" "")))
2313 (clobber (reg:SI T_REG))]
2314 "TARGET_SH1 && reload_completed"
2315 [(use (reg:SI R0_REG))]
2318 gen_shifty_hi_op (ASHIFT, operands);
2323 ; arithmetic shift right
2326 (define_insn "ashrsi3_sh2a"
2327 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2328 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2329 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2332 [(set_attr "type" "dyn_shift")
2333 (set_attr "length" "4")])
2335 (define_insn "ashrsi3_k"
2336 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2337 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2338 (match_operand:SI 2 "const_int_operand" "M")))
2339 (clobber (reg:SI T_REG))]
2340 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2342 [(set_attr "type" "arith")])
2344 ;; We can't do HImode right shifts correctly unless we start out with an
2345 ;; explicit zero / sign extension; doing that would result in worse overall
2346 ;; code, so just let the machine independent code widen the mode.
2347 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2350 ;; ??? This should be a define expand.
2352 (define_insn "ashrsi2_16"
2353 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2354 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2358 [(set_attr "length" "4")])
2361 [(set (match_operand:SI 0 "arith_reg_operand" "")
2362 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2365 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2366 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2367 "operands[2] = gen_lowpart (HImode, operands[0]);")
2369 ;; ??? This should be a define expand.
2371 (define_insn "ashrsi2_31"
2372 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2373 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2375 (clobber (reg:SI T_REG))]
2378 [(set_attr "length" "4")])
2381 [(set (match_operand:SI 0 "arith_reg_operand" "")
2382 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2384 (clobber (reg:SI T_REG))]
2389 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2390 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2394 (define_insn "ashlsi_c"
2395 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2396 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2398 (lt:SI (match_dup 1) (const_int 0)))]
2401 [(set_attr "type" "arith")])
2403 (define_insn "ashrsi3_d"
2404 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2405 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2406 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2409 [(set_attr "type" "dyn_shift")])
2411 (define_insn "ashrsi3_n"
2412 [(set (reg:SI R4_REG)
2413 (ashiftrt:SI (reg:SI R4_REG)
2414 (match_operand:SI 0 "const_int_operand" "i")))
2415 (clobber (reg:SI T_REG))
2416 (clobber (reg:SI PR_REG))
2417 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2420 [(set_attr "type" "sfunc")
2421 (set_attr "needs_delay_slot" "yes")])
2423 (define_insn "ashrsi3_media"
2424 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2425 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2426 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2431 [(set_attr "type" "arith_media")])
2433 (define_expand "ashrsi3"
2434 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2435 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2436 (match_operand:SI 2 "nonmemory_operand" "")))
2437 (clobber (reg:SI T_REG))])]
2443 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2446 if (expand_ashiftrt (operands))
2452 ;; logical shift right
2454 (define_insn "lshrsi3_sh2a"
2455 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2456 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2457 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2460 [(set_attr "type" "dyn_shift")
2461 (set_attr "length" "4")])
2463 (define_insn "lshrsi3_d"
2464 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2465 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2466 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2469 [(set_attr "type" "dyn_shift")])
2471 ;; Only the single bit shift clobbers the T bit.
2473 (define_insn "lshrsi3_m"
2474 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2475 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2476 (match_operand:SI 2 "const_int_operand" "M")))
2477 (clobber (reg:SI T_REG))]
2478 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2480 [(set_attr "type" "arith")])
2482 (define_insn "lshrsi3_k"
2483 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2484 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2485 (match_operand:SI 2 "const_int_operand" "P27")))]
2486 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2487 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2489 [(set_attr "type" "arith")])
2491 (define_insn "lshrsi3_n"
2492 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2493 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2494 (match_operand:SI 2 "const_int_operand" "n")))
2495 (clobber (reg:SI T_REG))]
2496 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2498 [(set (attr "length")
2499 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2501 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2503 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2505 (const_string "8")))
2506 (set_attr "type" "arith")])
2509 [(set (match_operand:SI 0 "arith_reg_operand" "")
2510 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2511 (match_operand:SI 2 "const_int_operand" "")))
2512 (clobber (reg:SI T_REG))]
2513 "TARGET_SH1 && reload_completed"
2514 [(use (reg:SI R0_REG))]
2517 gen_shifty_op (LSHIFTRT, operands);
2521 (define_insn "lshrsi3_media"
2522 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2523 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2524 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2529 [(set_attr "type" "arith_media")])
2531 (define_expand "lshrsi3"
2532 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2533 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2534 (match_operand:SI 2 "nonmemory_operand" "")))
2535 (clobber (reg:SI T_REG))])]
2541 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2544 if (GET_CODE (operands[2]) == CONST_INT
2545 && sh_dynamicalize_shift_p (operands[2]))
2546 operands[2] = force_reg (SImode, operands[2]);
2547 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2549 rtx count = copy_to_mode_reg (SImode, operands[2]);
2550 emit_insn (gen_negsi2 (count, count));
2551 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2554 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2558 ;; ??? This should be a define expand.
2560 (define_insn "ashldi3_k"
2561 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2562 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2564 (clobber (reg:SI T_REG))]
2566 "shll %R0\;rotcl %S0"
2567 [(set_attr "length" "4")
2568 (set_attr "type" "arith")])
2570 (define_insn "ashldi3_media"
2571 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2572 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2573 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2578 [(set_attr "type" "arith_media")])
2580 (define_expand "ashldi3"
2581 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2582 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2583 (match_operand:DI 2 "immediate_operand" "")))
2584 (clobber (reg:SI T_REG))])]
2590 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2593 if (GET_CODE (operands[2]) != CONST_INT
2594 || INTVAL (operands[2]) != 1)
2598 ;; ??? This should be a define expand.
2600 (define_insn "lshrdi3_k"
2601 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2602 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2604 (clobber (reg:SI T_REG))]
2606 "shlr %S0\;rotcr %R0"
2607 [(set_attr "length" "4")
2608 (set_attr "type" "arith")])
2610 (define_insn "lshrdi3_media"
2611 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2612 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2613 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2618 [(set_attr "type" "arith_media")])
2620 (define_expand "lshrdi3"
2621 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2622 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2623 (match_operand:DI 2 "immediate_operand" "")))
2624 (clobber (reg:SI T_REG))])]
2630 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2633 if (GET_CODE (operands[2]) != CONST_INT
2634 || INTVAL (operands[2]) != 1)
2638 ;; ??? This should be a define expand.
2640 (define_insn "ashrdi3_k"
2641 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2642 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2644 (clobber (reg:SI T_REG))]
2646 "shar %S0\;rotcr %R0"
2647 [(set_attr "length" "4")
2648 (set_attr "type" "arith")])
2650 (define_insn "ashrdi3_media"
2651 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2652 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2653 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2658 [(set_attr "type" "arith_media")])
2660 (define_expand "ashrdi3"
2661 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2662 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2663 (match_operand:DI 2 "immediate_operand" "")))
2664 (clobber (reg:SI T_REG))])]
2670 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2673 if (GET_CODE (operands[2]) != CONST_INT
2674 || INTVAL (operands[2]) != 1)
2678 ;; combined left/right shift
2681 [(set (match_operand:SI 0 "register_operand" "")
2682 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2683 (match_operand:SI 2 "const_int_operand" ""))
2684 (match_operand:SI 3 "const_int_operand" "")))]
2685 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2686 [(use (reg:SI R0_REG))]
2687 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2691 [(set (match_operand:SI 0 "register_operand" "")
2692 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2693 (match_operand:SI 2 "const_int_operand" ""))
2694 (match_operand:SI 3 "const_int_operand" "")))
2695 (clobber (reg:SI T_REG))]
2696 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2697 [(use (reg:SI R0_REG))]
2698 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2702 [(set (match_operand:SI 0 "register_operand" "=r")
2703 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2704 (match_operand:SI 2 "const_int_operand" "n"))
2705 (match_operand:SI 3 "const_int_operand" "n")))
2706 (clobber (reg:SI T_REG))]
2707 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2709 [(set (attr "length")
2710 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2712 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2714 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2716 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2718 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2720 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2722 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2723 (const_string "16")]
2724 (const_string "18")))
2725 (set_attr "type" "arith")])
2728 [(set (match_operand:SI 0 "register_operand" "=z")
2729 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730 (match_operand:SI 2 "const_int_operand" "n"))
2731 (match_operand:SI 3 "const_int_operand" "n")))
2732 (clobber (reg:SI T_REG))]
2733 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2735 [(set (attr "length")
2736 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2738 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2740 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2742 (const_string "10")))
2743 (set_attr "type" "arith")])
2745 ;; shift left / and combination with a scratch register: The combine pass
2746 ;; does not accept the individual instructions, even though they are
2747 ;; cheap. But it needs a precise description so that it is usable after
2749 (define_insn "and_shl_scratch"
2750 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2754 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2755 (match_operand:SI 2 "const_int_operand" "N,n"))
2756 (match_operand:SI 3 "" "0,r"))
2757 (match_operand:SI 4 "const_int_operand" "n,n"))
2758 (match_operand:SI 5 "const_int_operand" "n,n")))
2759 (clobber (reg:SI T_REG))]
2762 [(set (attr "length")
2763 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2765 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2767 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2769 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2770 (const_string "10")]
2771 (const_string "12")))
2772 (set_attr "type" "arith")])
2775 [(set (match_operand:SI 0 "register_operand" "")
2779 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2780 (match_operand:SI 2 "const_int_operand" ""))
2781 (match_operand:SI 3 "register_operand" ""))
2782 (match_operand:SI 4 "const_int_operand" ""))
2783 (match_operand:SI 5 "const_int_operand" "")))
2784 (clobber (reg:SI T_REG))]
2786 [(use (reg:SI R0_REG))]
2789 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2791 if (INTVAL (operands[2]))
2793 gen_shifty_op (LSHIFTRT, operands);
2795 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2796 operands[2] = operands[4];
2797 gen_shifty_op (ASHIFT, operands);
2798 if (INTVAL (operands[5]))
2800 operands[2] = operands[5];
2801 gen_shifty_op (LSHIFTRT, operands);
2806 ;; signed left/right shift combination.
2808 [(set (match_operand:SI 0 "register_operand" "")
2810 (ashift:SI (match_operand:SI 1 "register_operand" "")
2811 (match_operand:SI 2 "const_int_operand" ""))
2812 (match_operand:SI 3 "const_int_operand" "")
2814 (clobber (reg:SI T_REG))]
2816 [(use (reg:SI R0_REG))]
2817 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2820 (define_insn "shl_sext_ext"
2821 [(set (match_operand:SI 0 "register_operand" "=r")
2823 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2824 (match_operand:SI 2 "const_int_operand" "n"))
2825 (match_operand:SI 3 "const_int_operand" "n")
2827 (clobber (reg:SI T_REG))]
2828 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2830 [(set (attr "length")
2831 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2833 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2835 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2837 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2839 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2841 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2843 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2845 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2846 (const_string "16")]
2847 (const_string "18")))
2848 (set_attr "type" "arith")])
2850 (define_insn "shl_sext_sub"
2851 [(set (match_operand:SI 0 "register_operand" "=z")
2853 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2854 (match_operand:SI 2 "const_int_operand" "n"))
2855 (match_operand:SI 3 "const_int_operand" "n")
2857 (clobber (reg:SI T_REG))]
2858 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2860 [(set (attr "length")
2861 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2863 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2865 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2867 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2868 (const_string "12")]
2869 (const_string "14")))
2870 (set_attr "type" "arith")])
2872 ;; These patterns are found in expansions of DImode shifts by 16, and
2873 ;; allow the xtrct instruction to be generated from C source.
2875 (define_insn "xtrct_left"
2876 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2877 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2879 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2883 [(set_attr "type" "arith")])
2885 (define_insn "xtrct_right"
2886 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2887 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2889 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2893 [(set_attr "type" "arith")])
2895 ;; -------------------------------------------------------------------------
2897 ;; -------------------------------------------------------------------------
2900 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2901 (neg:SI (plus:SI (reg:SI T_REG)
2902 (match_operand:SI 1 "arith_reg_operand" "r"))))
2904 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2908 [(set_attr "type" "arith")])
2910 (define_insn "*negdi_media"
2911 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2912 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2915 [(set_attr "type" "arith_media")])
2917 (define_expand "negdi2"
2918 [(set (match_operand:DI 0 "arith_reg_operand" "")
2919 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2925 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2926 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2928 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2929 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2931 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2932 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2934 emit_insn (gen_clrt ());
2935 emit_insn (gen_negc (low_dst, low_src));
2936 emit_insn (gen_negc (high_dst, high_src));
2941 (define_insn "negsi2"
2942 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2943 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2946 [(set_attr "type" "arith")])
2948 (define_insn "one_cmplsi2"
2949 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2950 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2953 [(set_attr "type" "arith")])
2955 (define_expand "one_cmpldi2"
2956 [(set (match_operand:DI 0 "arith_reg_operand" "")
2957 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2959 "TARGET_SHMEDIA" "")
2961 ;; -------------------------------------------------------------------------
2962 ;; Zero extension instructions
2963 ;; -------------------------------------------------------------------------
2965 (define_insn "zero_extendsidi2"
2966 [(set (match_operand:DI 0 "register_operand" "=r")
2967 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2969 "addz.l %1, r63, %0"
2970 [(set_attr "type" "arith_media")])
2972 (define_insn "zero_extendhidi2"
2973 [(set (match_operand:DI 0 "register_operand" "=r,r")
2974 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2979 [(set_attr "type" "*,load_media")])
2982 [(set (match_operand:DI 0 "register_operand" "")
2983 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2984 "TARGET_SHMEDIA && reload_completed"
2985 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2986 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2989 if (GET_CODE (operands[1]) == TRUNCATE)
2990 operands[1] = XEXP (operands[1], 0);
2993 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2994 ;; reload the entire truncate expression.
2995 (define_insn_and_split "*loaddi_trunc"
2996 [(set (match_operand 0 "int_gpr_dest" "=r")
2997 (truncate (match_operand:DI 1 "memory_operand" "m")))]
2998 "TARGET_SHMEDIA && reload_completed"
3000 "TARGET_SHMEDIA && reload_completed"
3001 [(set (match_dup 0) (match_dup 1))]
3002 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3004 (define_insn "zero_extendqidi2"
3005 [(set (match_operand:DI 0 "register_operand" "=r,r")
3006 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3011 [(set_attr "type" "arith_media,load_media")])
3013 (define_expand "zero_extendhisi2"
3014 [(set (match_operand:SI 0 "arith_reg_operand" "")
3015 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3019 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3020 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3023 (define_insn "*zero_extendhisi2_compact"
3024 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3025 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3028 [(set_attr "type" "arith")])
3030 (define_insn "*zero_extendhisi2_media"
3031 [(set (match_operand:SI 0 "register_operand" "=r,r")
3032 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3037 [(set_attr "type" "arith_media,load_media")])
3040 [(set (match_operand:SI 0 "register_operand" "")
3041 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3042 "TARGET_SHMEDIA && reload_completed"
3043 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3044 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3047 if (GET_CODE (operands[1]) == TRUNCATE)
3048 operands[1] = XEXP (operands[1], 0);
3051 (define_expand "zero_extendqisi2"
3052 [(set (match_operand:SI 0 "arith_reg_operand" "")
3053 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3057 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3058 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3061 (define_insn "*zero_extendqisi2_compact"
3062 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3063 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3066 [(set_attr "type" "arith")])
3068 (define_insn "*zero_extendqisi2_media"
3069 [(set (match_operand:SI 0 "register_operand" "=r,r")
3070 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3075 [(set_attr "type" "arith_media,load_media")])
3077 (define_insn "zero_extendqihi2"
3078 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3079 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3082 [(set_attr "type" "arith")])
3084 ;; -------------------------------------------------------------------------
3085 ;; Sign extension instructions
3086 ;; -------------------------------------------------------------------------
3088 ;; ??? This should be a define expand.
3089 ;; ??? Or perhaps it should be dropped?
3091 ;; convert_move generates good code for SH[1-4].
3092 (define_insn "extendsidi2"
3093 [(set (match_operand:DI 0 "register_operand" "=r,r")
3094 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3099 [(set_attr "type" "arith_media,load_media")])
3101 (define_insn "extendhidi2"
3102 [(set (match_operand:DI 0 "register_operand" "=r,r")
3103 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3108 [(set_attr "type" "*,load_media")])
3111 [(set (match_operand:DI 0 "register_operand" "")
3112 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3113 "TARGET_SHMEDIA && reload_completed"
3114 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3115 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3118 if (GET_CODE (operands[1]) == TRUNCATE)
3119 operands[1] = XEXP (operands[1], 0);
3122 (define_insn "extendqidi2"
3123 [(set (match_operand:DI 0 "register_operand" "=r,r")
3124 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3129 [(set_attr "type" "*,load_media")])
3132 [(set (match_operand:DI 0 "register_operand" "")
3133 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3134 "TARGET_SHMEDIA && reload_completed"
3135 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3136 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3139 if (GET_CODE (operands[1]) == TRUNCATE)
3140 operands[1] = XEXP (operands[1], 0);
3143 (define_expand "extendhisi2"
3144 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3145 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3149 (define_insn "*extendhisi2_compact"
3150 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3151 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3156 [(set_attr "type" "arith,load")])
3158 (define_insn "*extendhisi2_media"
3159 [(set (match_operand:SI 0 "register_operand" "=r,r")
3160 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3165 [(set_attr "type" "arith_media,load_media")])
3168 [(set (match_operand:SI 0 "register_operand" "")
3169 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3170 "TARGET_SHMEDIA && reload_completed"
3171 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3172 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3175 if (GET_CODE (operands[1]) == TRUNCATE)
3176 operands[1] = XEXP (operands[1], 0);
3179 (define_expand "extendqisi2"
3180 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3181 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3185 (define_insn "*extendqisi2_compact"
3186 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3187 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3192 [(set_attr "type" "arith,load")])
3194 (define_insn "*extendqisi2_media"
3195 [(set (match_operand:SI 0 "register_operand" "=r,r")
3196 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3201 [(set_attr "type" "arith_media,load_media")])
3204 [(set (match_operand:SI 0 "register_operand" "")
3205 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3206 "TARGET_SHMEDIA && reload_completed"
3207 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3208 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3211 if (GET_CODE (operands[1]) == TRUNCATE)
3212 operands[1] = XEXP (operands[1], 0);
3215 (define_insn "extendqihi2"
3216 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3217 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3222 [(set_attr "type" "arith,load")])
3224 /* It would seem useful to combine the truncXi patterns into the movXi
3225 patterns, but unary operators are ignored when matching constraints,
3226 so we need separate patterns. */
3227 (define_insn "truncdisi2"
3228 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3229 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3238 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3241 (define_insn "truncdihi2"
3242 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3243 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3246 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3248 [(set_attr "type" "arith_media,store_media")
3249 (set_attr "length" "8,4")])
3251 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3252 ; Because we use zero extension, we can't provide signed QImode compares
3253 ; using a simple compare or conditional banch insn.
3254 (define_insn "truncdiqi2"
3255 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3256 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3261 [(set_attr "type" "arith_media,store")])
3263 ;; -------------------------------------------------------------------------
3264 ;; Move instructions
3265 ;; -------------------------------------------------------------------------
3267 ;; define push and pop so it is easy for sh.c
3268 ;; We can't use push and pop on SHcompact because the stack must always
3269 ;; be 8-byte aligned.
3271 (define_expand "push"
3272 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3273 (match_operand:SI 0 "register_operand" "r,l,x"))]
3274 "TARGET_SH1 && ! TARGET_SH5"
3277 (define_expand "pop"
3278 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3279 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3280 "TARGET_SH1 && ! TARGET_SH5"
3283 (define_expand "push_e"
3284 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3285 (match_operand:SF 0 "" ""))
3286 (use (reg:PSI FPSCR_REG))
3287 (clobber (scratch:SI))])]
3288 "TARGET_SH1 && ! TARGET_SH5"
3291 (define_insn "push_fpul"
3292 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3293 "TARGET_SH2E && ! TARGET_SH5"
3295 [(set_attr "type" "store")
3296 (set_attr "late_fp_use" "yes")
3297 (set_attr "hit_stack" "yes")])
3299 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3301 (define_expand "push_4"
3302 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3303 (match_operand:DF 0 "" ""))
3304 (use (reg:PSI FPSCR_REG))
3305 (clobber (scratch:SI))])]
3306 "TARGET_SH1 && ! TARGET_SH5"
3309 (define_expand "pop_e"
3310 [(parallel [(set (match_operand:SF 0 "" "")
3311 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3312 (use (reg:PSI FPSCR_REG))
3313 (clobber (scratch:SI))])]
3314 "TARGET_SH1 && ! TARGET_SH5"
3317 (define_insn "pop_fpul"
3318 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3319 "TARGET_SH2E && ! TARGET_SH5"
3321 [(set_attr "type" "load")
3322 (set_attr "hit_stack" "yes")])
3324 (define_expand "pop_4"
3325 [(parallel [(set (match_operand:DF 0 "" "")
3326 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3327 (use (reg:PSI FPSCR_REG))
3328 (clobber (scratch:SI))])]
3329 "TARGET_SH1 && ! TARGET_SH5"
3332 (define_expand "push_fpscr"
3337 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3338 gen_rtx_PRE_DEC (Pmode,
3339 stack_pointer_rtx)),
3341 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3345 (define_expand "pop_fpscr"
3350 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3351 gen_rtx_MEM (PSImode,
3352 gen_rtx_POST_INC (Pmode,
3353 stack_pointer_rtx))));
3354 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3358 ;; These two patterns can happen as the result of optimization, when
3359 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3360 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3363 [(set (reg:SI T_REG) (const_int 0))]
3368 [(set (reg:SI T_REG) (const_int 1))]
3372 ;; t/r must come after r/r, lest reload will try to reload stuff like
3373 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3374 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3375 (define_insn "movsi_i"
3376 [(set (match_operand:SI 0 "general_movdst_operand"
3377 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3378 (match_operand:SI 1 "general_movsrc_operand"
3379 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3383 && (register_operand (operands[0], SImode)
3384 || register_operand (operands[1], SImode))"
3401 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3402 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3404 ;; t/r must come after r/r, lest reload will try to reload stuff like
3405 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3406 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3407 ;; will require a reload.
3408 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3409 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3410 (define_insn "movsi_ie"
3411 [(set (match_operand:SI 0 "general_movdst_operand"
3412 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3413 (match_operand:SI 1 "general_movsrc_operand"
3414 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3415 "(TARGET_SH2E || TARGET_SH2A)
3416 && (register_operand (operands[0], SImode)
3417 || register_operand (operands[1], SImode))"
3442 ! move optimized away"
3443 [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3444 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3445 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3447 (define_insn "movsi_i_lowpart"
3448 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3449 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3451 && (register_operand (operands[0], SImode)
3452 || register_operand (operands[1], SImode))"
3462 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3464 (define_insn_and_split "load_ra"
3465 [(set (match_operand:SI 0 "general_movdst_operand" "")
3466 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3469 "&& ! currently_expanding_to_rtl"
3470 [(set (match_dup 0) (match_dup 1))]
3473 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3474 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3477 (define_insn "*movsi_media"
3478 [(set (match_operand:SI 0 "general_movdst_operand"
3479 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3480 (match_operand:SI 1 "general_movsrc_operand"
3481 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3483 && (register_operand (operands[0], SImode)
3484 || sh_register_operand (operands[1], SImode))"
3499 [(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")
3500 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3502 (define_insn "*movsi_media_nofpu"
3503 [(set (match_operand:SI 0 "general_movdst_operand"
3504 "=r,r,r,r,m,*b,r,b")
3505 (match_operand:SI 1 "general_movsrc_operand"
3506 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3508 && (register_operand (operands[0], SImode)
3509 || sh_register_operand (operands[1], SImode))"
3519 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3520 (set_attr "length" "4,4,8,4,4,4,4,12")])
3523 [(set (match_operand:SI 0 "arith_reg_operand" "")
3524 (match_operand:SI 1 "immediate_operand" ""))]
3525 "TARGET_SHMEDIA && reload_completed
3526 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3527 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3530 operands[2] = shallow_copy_rtx (operands[1]);
3531 PUT_MODE (operands[2], DImode);
3535 [(set (match_operand:SI 0 "register_operand" "")
3536 (match_operand:SI 1 "immediate_operand" ""))]
3537 "TARGET_SHMEDIA && reload_completed
3538 && ((GET_CODE (operands[1]) == CONST_INT
3539 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3540 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3541 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3543 (define_expand "movsi"
3544 [(set (match_operand:SI 0 "general_movdst_operand" "")
3545 (match_operand:SI 1 "general_movsrc_operand" ""))]
3547 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3549 (define_expand "ic_invalidate_line"
3550 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3551 (match_dup 1)] UNSPEC_ICACHE)
3552 (clobber (scratch:SI))])]
3553 "TARGET_HARD_SH4 || TARGET_SH5"
3558 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3561 else if (TARGET_SHCOMPACT)
3563 operands[1] = function_symbol (\"__ic_invalidate\");
3564 operands[1] = force_reg (Pmode, operands[1]);
3565 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3568 else if (TARGET_SH4A_ARCH)
3570 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3573 operands[0] = force_reg (Pmode, operands[0]);
3574 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3578 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3579 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3580 ;; the requirement *1*00 for associative address writes. The alignment of
3581 ;; %0 implies that its least significant bit is cleared,
3582 ;; thus we clear the V bit of a matching entry if there is one.
3583 (define_insn "ic_invalidate_line_i"
3584 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3585 (match_operand:SI 1 "register_operand" "r")]
3587 (clobber (match_scratch:SI 2 "=&r"))]
3589 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3590 [(set_attr "length" "8")
3591 (set_attr "type" "cwb")])
3593 (define_insn "ic_invalidate_line_sh4a"
3594 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3597 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3598 [(set_attr "length" "16")
3599 (set_attr "type" "cwb")])
3601 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3602 ;; an add in the code that calculates the address.
3603 (define_insn "ic_invalidate_line_media"
3604 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3607 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3608 [(set_attr "length" "16")
3609 (set_attr "type" "invalidate_line_media")])
3611 (define_insn "ic_invalidate_line_compact"
3612 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3613 (match_operand:SI 1 "register_operand" "r")]
3615 (clobber (reg:SI PR_REG))]
3618 [(set_attr "type" "sfunc")
3619 (set_attr "needs_delay_slot" "yes")])
3621 (define_expand "initialize_trampoline"
3622 [(match_operand:SI 0 "" "")
3623 (match_operand:SI 1 "" "")
3624 (match_operand:SI 2 "" "")]
3630 tramp = force_reg (Pmode, operands[0]);
3631 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3632 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3633 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3635 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3639 (define_insn "initialize_trampoline_compact"
3640 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3641 (match_operand:SI 1 "register_operand" "r")
3642 (reg:SI R2_REG) (reg:SI R3_REG)]
3645 (clobber (reg:SI PR_REG))]
3648 [(set_attr "type" "sfunc")
3649 (set_attr "needs_delay_slot" "yes")])
3651 (define_insn "movqi_i"
3652 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3653 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3655 && (arith_reg_operand (operands[0], QImode)
3656 || arith_reg_operand (operands[1], QImode))"
3664 [(set_attr "type" "move,load,store,move,move,move")])
3666 (define_insn "*movqi_media"
3667 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3668 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3670 && (arith_reg_operand (operands[0], QImode)
3671 || arith_reg_or_0_operand (operands[1], QImode))"
3677 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3679 (define_expand "movqi"
3680 [(set (match_operand:QI 0 "general_operand" "")
3681 (match_operand:QI 1 "general_operand" ""))]
3683 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3685 (define_expand "reload_inqi"
3686 [(set (match_operand:SI 2 "" "=&r")
3687 (match_operand:QI 1 "inqhi_operand" ""))
3688 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3689 (truncate:QI (match_dup 3)))]
3693 rtx inner = XEXP (operands[1], 0);
3694 int regno = REGNO (inner);
3696 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3697 operands[1] = gen_rtx_REG (SImode, regno);
3698 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3701 /* When storing r0, we have to avoid reg+reg addressing. */
3702 (define_insn "movhi_i"
3703 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3704 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3706 && (arith_reg_operand (operands[0], HImode)
3707 || arith_reg_operand (operands[1], HImode))
3708 && (GET_CODE (operands[0]) != MEM
3709 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3710 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3711 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3721 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3723 (define_insn "*movhi_media"
3724 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3725 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3727 && (arith_reg_operand (operands[0], HImode)
3728 || arith_reg_or_0_operand (operands[1], HImode))"
3735 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3738 [(set (match_operand:HI 0 "register_operand" "")
3739 (match_operand:HI 1 "immediate_operand" ""))]
3740 "TARGET_SHMEDIA && reload_completed
3741 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3742 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3744 (define_expand "movhi"
3745 [(set (match_operand:HI 0 "general_movdst_operand" "")
3746 (match_operand:HI 1 "general_movsrc_operand" ""))]
3748 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3750 (define_expand "reload_inhi"
3751 [(set (match_operand:SI 2 "" "=&r")
3752 (match_operand:HI 1 "inqhi_operand" ""))
3753 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3754 (truncate:HI (match_dup 3)))]
3758 rtx inner = XEXP (operands[1], 0);
3759 int regno = REGNO (inner);
3761 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3762 operands[1] = gen_rtx_REG (SImode, regno);
3763 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3766 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3767 ;; compiled with -m2 -ml -O3 -funroll-loops
3768 (define_insn "*movdi_i"
3769 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3770 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3772 && (arith_reg_operand (operands[0], DImode)
3773 || arith_reg_operand (operands[1], DImode))"
3774 "* return output_movedouble (insn, operands, DImode);"
3775 [(set_attr "length" "4")
3776 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3778 ;; If the output is a register and the input is memory or a register, we have
3779 ;; to be careful and see which word needs to be loaded first.
3782 [(set (match_operand:DI 0 "general_movdst_operand" "")
3783 (match_operand:DI 1 "general_movsrc_operand" ""))]
3784 "TARGET_SH1 && reload_completed"
3785 [(set (match_dup 2) (match_dup 3))
3786 (set (match_dup 4) (match_dup 5))]
3791 if ((GET_CODE (operands[0]) == MEM
3792 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3793 || (GET_CODE (operands[1]) == MEM
3794 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3797 if (GET_CODE (operands[0]) == REG)
3798 regno = REGNO (operands[0]);
3799 else if (GET_CODE (operands[0]) == SUBREG)
3800 regno = subreg_regno (operands[0]);
3801 else if (GET_CODE (operands[0]) == MEM)
3807 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3809 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3810 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3811 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3812 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3816 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3817 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3818 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3819 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3822 if (operands[2] == 0 || operands[3] == 0
3823 || operands[4] == 0 || operands[5] == 0)
3827 (define_insn "*movdi_media"
3828 [(set (match_operand:DI 0 "general_movdst_operand"
3829 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3830 (match_operand:DI 1 "general_movsrc_operand"
3831 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3833 && (register_operand (operands[0], DImode)
3834 || sh_register_operand (operands[1], DImode))"
3849 [(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")
3850 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3852 (define_insn "*movdi_media_nofpu"
3853 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3854 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3856 && (register_operand (operands[0], DImode)
3857 || sh_register_operand (operands[1], DImode))"
3867 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3868 (set_attr "length" "4,4,16,4,4,4,4,*")])
3871 [(set (match_operand:DI 0 "arith_reg_operand" "")
3872 (match_operand:DI 1 "immediate_operand" ""))]
3873 "TARGET_SHMEDIA && reload_completed
3874 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3875 [(set (match_dup 0) (match_dup 1))]
3880 if (TARGET_SHMEDIA64)
3881 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3883 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3885 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3891 (define_expand "movdi_const"
3892 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3893 (const:DI (sign_extend:DI
3896 (match_operand:DI 1 "immediate_operand" "s")
3899 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3907 (const_int 32)))))))))
3909 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3917 (const_int 16)))))))))
3919 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3925 (match_dup 1))))))))]
3926 "TARGET_SHMEDIA64 && reload_completed
3927 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3930 sh_mark_label (operands[1], 4);
3933 (define_expand "movdi_const_32bit"
3934 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3935 (const:DI (sign_extend:DI
3938 (match_operand:DI 1 "immediate_operand" "s")
3941 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3947 (match_dup 1))))))))]
3948 "TARGET_SHMEDIA32 && reload_completed
3949 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3952 sh_mark_label (operands[1], 2);
3955 (define_expand "movdi_const_16bit"
3956 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3957 (const:DI (sign_extend:DI
3959 (match_operand:DI 1 "immediate_operand" "s")))))]
3960 "TARGET_SHMEDIA && flag_pic && reload_completed
3961 && GET_CODE (operands[1]) == SYMBOL_REF"
3965 [(set (match_operand:DI 0 "arith_reg_operand" "")
3966 (match_operand:DI 1 "immediate_operand" ""))]
3967 "TARGET_SHMEDIA && reload_completed
3968 && GET_CODE (operands[1]) == CONST_INT
3969 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3970 [(set (match_dup 0) (match_dup 2))
3974 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3975 unsigned HOST_WIDE_INT low = val;
3976 unsigned HOST_WIDE_INT high = val;
3977 unsigned HOST_WIDE_INT sign;
3978 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3980 /* Sign-extend the 16 least-significant bits. */
3985 /* Arithmetic shift right the word by 16 bits. */
3988 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3993 /* If we can't generate the constant with a two-insn movi / shori
3994 sequence, try some other strategies. */
3995 if (! CONST_OK_FOR_I16 (high))
3997 /* Try constant load / left shift. We know VAL != 0. */
3998 val2 = val ^ (val-1);
4001 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4003 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4004 || (! CONST_OK_FOR_I16 (high >> 16)
4005 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4007 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4008 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4009 GEN_INT (trailing_zeroes));
4013 /* Try constant load / right shift. */
4014 val2 = (val >> 15) + 1;
4015 if (val2 == (val2 & -val2))
4017 int shift = 49 - exact_log2 (val2);
4019 val2 = trunc_int_for_mode (val << shift, DImode);
4020 if (CONST_OK_FOR_I16 (val2))
4022 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4028 val2 = val & 0xffff;
4029 if ((val >> 16 & 0xffff) == val2
4030 && (val >> 32 & 0xffff) == val2
4031 && (val >> 48 & 0xffff) == val2)
4033 val2 = (HOST_WIDE_INT) val >> 48;
4034 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4035 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4038 /* Try movi / mshflo.l */
4039 val2 = (HOST_WIDE_INT) val >> 32;
4040 if (val2 == ((unsigned HOST_WIDE_INT)
4041 trunc_int_for_mode (val, SImode)))
4043 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4047 /* Try movi / mshflo.l w/ r63. */
4048 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4049 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4051 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4057 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4060 operands[2] = GEN_INT (val2);
4064 [(set (match_operand:DI 0 "arith_reg_operand" "")
4065 (match_operand:DI 1 "immediate_operand" ""))]
4066 "TARGET_SHMEDIA && reload_completed
4067 && GET_CODE (operands[1]) == CONST_DOUBLE"
4068 [(set (match_dup 0) (match_dup 2))
4070 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4071 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4074 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4075 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4076 unsigned HOST_WIDE_INT val = low;
4077 unsigned HOST_WIDE_INT sign;
4079 /* Sign-extend the 16 least-significant bits. */
4083 operands[1] = GEN_INT (val);
4085 /* Arithmetic shift right the double-word by 16 bits. */
4087 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4090 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4094 /* This will only be true if high is a sign-extension of low, i.e.,
4095 it must be either 0 or (unsigned)-1, and be zero iff the
4096 most-significant bit of low is set. */
4097 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4098 operands[2] = GEN_INT (low);
4100 operands[2] = immed_double_const (low, high, DImode);
4103 (define_insn "shori_media"
4104 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4105 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4109 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4114 [(set_attr "type" "arith_media,*")])
4116 (define_expand "movdi"
4117 [(set (match_operand:DI 0 "general_movdst_operand" "")
4118 (match_operand:DI 1 "general_movsrc_operand" ""))]
4120 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4122 (define_insn "movdf_media"
4123 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4124 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4126 && (register_operand (operands[0], DFmode)
4127 || sh_register_operand (operands[1], DFmode))"
4138 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4140 (define_insn "movdf_media_nofpu"
4141 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4142 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4144 && (register_operand (operands[0], DFmode)
4145 || sh_register_operand (operands[1], DFmode))"
4151 [(set_attr "type" "arith_media,*,load_media,store_media")])
4154 [(set (match_operand:DF 0 "arith_reg_operand" "")
4155 (match_operand:DF 1 "immediate_operand" ""))]
4156 "TARGET_SHMEDIA && reload_completed"
4157 [(set (match_dup 3) (match_dup 2))]
4160 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4162 REAL_VALUE_TYPE value;
4164 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4165 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4167 if (HOST_BITS_PER_WIDE_INT >= 64)
4168 operands[2] = immed_double_const ((unsigned long) values[endian]
4169 | ((HOST_WIDE_INT) values[1 - endian]
4171 else if (HOST_BITS_PER_WIDE_INT == 32)
4172 operands[2] = immed_double_const (values[endian], values[1 - endian],
4177 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4180 ;; ??? This should be a define expand.
4182 (define_insn "movdf_k"
4183 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4184 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4186 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4187 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4188 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4189 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4190 && (arith_reg_operand (operands[0], DFmode)
4191 || arith_reg_operand (operands[1], DFmode))"
4192 "* return output_movedouble (insn, operands, DFmode);"
4193 [(set_attr "length" "4")
4194 (set_attr "type" "move,pcload,load,store")])
4196 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4197 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4198 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4199 ;; the d/m/c/X alternative, which is split later into single-precision
4200 ;; instructions. And when not optimizing, no splits are done before fixing
4201 ;; up pcloads, so we need usable length information for that.
4202 (define_insn "movdf_i4"
4203 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4204 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4205 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4206 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4207 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4208 && (arith_reg_operand (operands[0], DFmode)
4209 || arith_reg_operand (operands[1], DFmode))"
4221 [(set_attr_alternative "length"
4222 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4224 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4225 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4226 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4228 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4229 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4230 ;; increment or decrement r15 explicitly.
4232 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233 (const_int 10) (const_int 8))
4235 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4236 (const_int 10) (const_int 8))])
4237 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4238 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4239 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4240 (const_string "double")
4241 (const_string "none")))])
4243 ;; Moving DFmode between fp/general registers through memory
4244 ;; (the top of the stack) is faster than moving through fpul even for
4245 ;; little endian. Because the type of an instruction is important for its
4246 ;; scheduling, it is beneficial to split these operations, rather than
4247 ;; emitting them in one single chunk, even if this will expose a stack
4248 ;; use that will prevent scheduling of other stack accesses beyond this
4251 [(set (match_operand:DF 0 "register_operand" "")
4252 (match_operand:DF 1 "register_operand" ""))
4253 (use (match_operand:PSI 2 "fpscr_operand" ""))
4254 (clobber (match_scratch:SI 3 "=X"))]
4255 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4256 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4262 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4264 emit_move_insn (stack_pointer_rtx,
4265 plus_constant (stack_pointer_rtx, -8));
4266 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4269 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4270 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4271 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4272 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4273 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4274 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4276 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4277 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4278 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4279 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4281 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4285 ;; local-alloc sometimes allocates scratch registers even when not required,
4286 ;; so we must be prepared to handle these.
4288 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4290 [(set (match_operand:DF 0 "general_movdst_operand" "")
4291 (match_operand:DF 1 "general_movsrc_operand" ""))
4292 (use (match_operand:PSI 2 "fpscr_operand" ""))
4293 (clobber (match_scratch:SI 3 ""))]
4294 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4296 && true_regnum (operands[0]) < 16
4297 && true_regnum (operands[1]) < 16"
4298 [(set (match_dup 0) (match_dup 1))]
4301 /* If this was a reg <-> mem operation with base + index reg addressing,
4302 we have to handle this in a special way. */
4303 rtx mem = operands[0];
4305 if (! memory_operand (mem, DFmode))
4310 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4311 mem = SUBREG_REG (mem);
4312 if (GET_CODE (mem) == MEM)
4314 rtx addr = XEXP (mem, 0);
4315 if (GET_CODE (addr) == PLUS
4316 && GET_CODE (XEXP (addr, 0)) == REG
4317 && GET_CODE (XEXP (addr, 1)) == REG)
4320 rtx reg0 = gen_rtx_REG (Pmode, 0);
4321 rtx regop = operands[store_p], word0 ,word1;
4323 if (GET_CODE (regop) == SUBREG)
4324 alter_subreg (®op);
4325 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4329 mem = copy_rtx (mem);
4330 PUT_MODE (mem, SImode);
4331 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4332 alter_subreg (&word0);
4333 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4334 alter_subreg (&word1);
4335 if (store_p || ! refers_to_regno_p (REGNO (word0),
4336 REGNO (word0) + 1, addr, 0))
4339 ? gen_movsi_ie (mem, word0)
4340 : gen_movsi_ie (word0, mem));
4341 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4342 mem = copy_rtx (mem);
4344 ? gen_movsi_ie (mem, word1)
4345 : gen_movsi_ie (word1, mem));
4346 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4350 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4351 emit_insn (gen_movsi_ie (word1, mem));
4352 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4353 mem = copy_rtx (mem);
4354 emit_insn (gen_movsi_ie (word0, mem));
4361 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4363 [(set (match_operand:DF 0 "register_operand" "")
4364 (match_operand:DF 1 "memory_operand" ""))
4365 (use (match_operand:PSI 2 "fpscr_operand" ""))
4366 (clobber (reg:SI R0_REG))]
4367 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4368 [(parallel [(set (match_dup 0) (match_dup 1))
4370 (clobber (scratch:SI))])]
4373 (define_expand "reload_indf"
4374 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4375 (match_operand:DF 1 "immediate_operand" "FQ"))
4376 (use (reg:PSI FPSCR_REG))
4377 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4381 (define_expand "reload_outdf"
4382 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4383 (match_operand:DF 1 "register_operand" "af,r"))
4384 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4388 ;; Simplify no-op moves.
4390 [(set (match_operand:SF 0 "register_operand" "")
4391 (match_operand:SF 1 "register_operand" ""))
4392 (use (match_operand:PSI 2 "fpscr_operand" ""))
4393 (clobber (match_scratch:SI 3 ""))]
4394 "TARGET_SH2E && reload_completed
4395 && true_regnum (operands[0]) == true_regnum (operands[1])"
4396 [(set (match_dup 0) (match_dup 0))]
4399 ;; fmovd substitute post-reload splits
4401 [(set (match_operand:DF 0 "register_operand" "")
4402 (match_operand:DF 1 "register_operand" ""))
4403 (use (match_operand:PSI 2 "fpscr_operand" ""))
4404 (clobber (match_scratch:SI 3 ""))]
4405 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4406 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4407 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4411 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4412 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4413 gen_rtx_REG (SFmode, src), operands[2]));
4414 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4415 gen_rtx_REG (SFmode, src + 1), operands[2]));
4420 [(set (match_operand:DF 0 "register_operand" "")
4421 (mem:DF (match_operand:SI 1 "register_operand" "")))
4422 (use (match_operand:PSI 2 "fpscr_operand" ""))
4423 (clobber (match_scratch:SI 3 ""))]
4424 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4425 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4426 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4430 int regno = true_regnum (operands[0]);
4432 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4434 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4435 regno + !! TARGET_LITTLE_ENDIAN),
4436 mem2, operands[2]));
4437 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4438 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4439 regno + ! TARGET_LITTLE_ENDIAN),
4440 gen_rtx_MEM (SFmode, operands[1]),
4446 [(set (match_operand:DF 0 "register_operand" "")
4447 (match_operand:DF 1 "memory_operand" ""))
4448 (use (match_operand:PSI 2 "fpscr_operand" ""))
4449 (clobber (match_scratch:SI 3 ""))]
4450 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4451 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4455 int regno = true_regnum (operands[0]);
4456 rtx addr, insn, adjust = NULL_RTX;
4457 rtx mem2 = copy_rtx (operands[1]);
4458 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4459 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4461 PUT_MODE (mem2, SFmode);
4462 operands[1] = copy_rtx (mem2);
4463 addr = XEXP (mem2, 0);
4464 if (GET_CODE (addr) != POST_INC)
4466 /* If we have to modify the stack pointer, the value that we have
4467 read with post-increment might be modified by an interrupt,
4468 so write it back. */
4469 if (REGNO (addr) == STACK_POINTER_REGNUM)
4470 adjust = gen_push_e (reg0);
4472 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4473 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4475 addr = XEXP (addr, 0);
4476 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4477 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4478 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4482 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4487 [(set (match_operand:DF 0 "memory_operand" "")
4488 (match_operand:DF 1 "register_operand" ""))
4489 (use (match_operand:PSI 2 "fpscr_operand" ""))
4490 (clobber (match_scratch:SI 3 ""))]
4491 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4492 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4496 int regno = true_regnum (operands[1]);
4497 rtx insn, addr, adjust = NULL_RTX;
4499 operands[0] = copy_rtx (operands[0]);
4500 PUT_MODE (operands[0], SFmode);
4501 insn = emit_insn (gen_movsf_ie (operands[0],
4502 gen_rtx_REG (SFmode,
4503 regno + ! TARGET_LITTLE_ENDIAN),
4505 operands[0] = copy_rtx (operands[0]);
4506 addr = XEXP (operands[0], 0);
4507 if (GET_CODE (addr) != PRE_DEC)
4509 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4510 emit_insn_before (adjust, insn);
4511 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4513 addr = XEXP (addr, 0);
4515 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4516 insn = emit_insn (gen_movsf_ie (operands[0],
4517 gen_rtx_REG (SFmode,
4518 regno + !! TARGET_LITTLE_ENDIAN),
4520 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4524 ;; If the output is a register and the input is memory or a register, we have
4525 ;; to be careful and see which word needs to be loaded first.
4528 [(set (match_operand:DF 0 "general_movdst_operand" "")
4529 (match_operand:DF 1 "general_movsrc_operand" ""))]
4530 "TARGET_SH1 && reload_completed"
4531 [(set (match_dup 2) (match_dup 3))
4532 (set (match_dup 4) (match_dup 5))]
4537 if ((GET_CODE (operands[0]) == MEM
4538 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4539 || (GET_CODE (operands[1]) == MEM
4540 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4543 if (GET_CODE (operands[0]) == REG)
4544 regno = REGNO (operands[0]);
4545 else if (GET_CODE (operands[0]) == SUBREG)
4546 regno = subreg_regno (operands[0]);
4547 else if (GET_CODE (operands[0]) == MEM)
4553 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4555 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4556 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4557 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4558 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4562 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4563 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4564 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4565 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4568 if (operands[2] == 0 || operands[3] == 0
4569 || operands[4] == 0 || operands[5] == 0)
4573 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4574 ;; used only once, let combine add in the index again.
4577 [(set (match_operand:SI 0 "register_operand" "")
4578 (match_operand:SI 1 "" ""))
4579 (clobber (match_operand 2 "register_operand" ""))]
4580 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4581 [(use (reg:SI R0_REG))]
4584 rtx addr, reg, const_int;
4586 if (GET_CODE (operands[1]) != MEM)
4588 addr = XEXP (operands[1], 0);
4589 if (GET_CODE (addr) != PLUS)
4591 reg = XEXP (addr, 0);
4592 const_int = XEXP (addr, 1);
4593 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4594 && GET_CODE (const_int) == CONST_INT))
4596 emit_move_insn (operands[2], const_int);
4597 emit_move_insn (operands[0],
4598 change_address (operands[1], VOIDmode,
4599 gen_rtx_PLUS (SImode, reg, operands[2])));
4604 [(set (match_operand:SI 1 "" "")
4605 (match_operand:SI 0 "register_operand" ""))
4606 (clobber (match_operand 2 "register_operand" ""))]
4607 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4608 [(use (reg:SI R0_REG))]
4611 rtx addr, reg, const_int;
4613 if (GET_CODE (operands[1]) != MEM)
4615 addr = XEXP (operands[1], 0);
4616 if (GET_CODE (addr) != PLUS)
4618 reg = XEXP (addr, 0);
4619 const_int = XEXP (addr, 1);
4620 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4621 && GET_CODE (const_int) == CONST_INT))
4623 emit_move_insn (operands[2], const_int);
4624 emit_move_insn (change_address (operands[1], VOIDmode,
4625 gen_rtx_PLUS (SImode, reg, operands[2])),
4630 (define_expand "movdf"
4631 [(set (match_operand:DF 0 "general_movdst_operand" "")
4632 (match_operand:DF 1 "general_movsrc_operand" ""))]
4636 if (prepare_move_operands (operands, DFmode)) DONE;
4639 if (TARGET_SHMEDIA_FPU)
4640 emit_insn (gen_movdf_media (operands[0], operands[1]));
4642 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4645 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4647 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4652 ;;This is incompatible with the way gcc uses subregs.
4653 ;;(define_insn "movv2sf_i"
4654 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4655 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4656 ;; "TARGET_SHMEDIA_FPU
4657 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4658 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4662 ;; fst%M0.p %m0, %1"
4663 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4665 (define_insn_and_split "movv2sf_i"
4666 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4667 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4668 "TARGET_SHMEDIA_FPU"
4670 "TARGET_SHMEDIA_FPU && reload_completed"
4671 [(set (match_dup 0) (match_dup 1))]
4674 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4675 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4678 (define_expand "movv2sf"
4679 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4680 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4681 "TARGET_SHMEDIA_FPU"
4684 if (prepare_move_operands (operands, V2SFmode))
4688 (define_expand "addv2sf3"
4689 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4690 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4691 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4692 "TARGET_SHMEDIA_FPU"
4695 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4699 (define_expand "subv2sf3"
4700 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4701 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4702 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4703 "TARGET_SHMEDIA_FPU"
4706 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4710 (define_expand "mulv2sf3"
4711 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4712 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4713 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4714 "TARGET_SHMEDIA_FPU"
4717 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4721 (define_expand "divv2sf3"
4722 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4723 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4724 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4725 "TARGET_SHMEDIA_FPU"
4728 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4732 (define_insn_and_split "*movv4sf_i"
4733 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4734 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4735 "TARGET_SHMEDIA_FPU"
4737 "&& reload_completed"
4743 for (i = 0; i < 4/2; i++)
4747 if (GET_CODE (operands[0]) == MEM)
4748 x = gen_rtx_MEM (V2SFmode,
4749 plus_constant (XEXP (operands[0], 0),
4750 i * GET_MODE_SIZE (V2SFmode)));
4752 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4754 if (GET_CODE (operands[1]) == MEM)
4755 y = gen_rtx_MEM (V2SFmode,
4756 plus_constant (XEXP (operands[1], 0),
4757 i * GET_MODE_SIZE (V2SFmode)));
4759 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4761 emit_insn (gen_movv2sf_i (x, y));
4766 [(set_attr "length" "8")])
4768 (define_expand "movv4sf"
4769 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4770 (match_operand:V4SF 1 "general_operand" ""))]
4771 "TARGET_SHMEDIA_FPU"
4774 if (prepare_move_operands (operands, V4SFmode))
4778 (define_insn_and_split "*movv16sf_i"
4779 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4780 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4781 "TARGET_SHMEDIA_FPU"
4783 "&& reload_completed"
4789 for (i = 0; i < 16/2; i++)
4793 if (GET_CODE (operands[0]) == MEM)
4794 x = gen_rtx_MEM (V2SFmode,
4795 plus_constant (XEXP (operands[0], 0),
4796 i * GET_MODE_SIZE (V2SFmode)));
4799 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4803 if (GET_CODE (operands[1]) == MEM)
4804 y = gen_rtx_MEM (V2SFmode,
4805 plus_constant (XEXP (operands[1], 0),
4806 i * GET_MODE_SIZE (V2SFmode)));
4809 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4813 emit_insn (gen_movv2sf_i (x, y));
4818 [(set_attr "length" "32")])
4820 (define_expand "movv16sf"
4821 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4822 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4823 "TARGET_SHMEDIA_FPU"
4826 if (prepare_move_operands (operands, V16SFmode))
4830 (define_insn "movsf_media"
4831 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4832 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4834 && (register_operand (operands[0], SFmode)
4835 || sh_register_operand (operands[1], SFmode))"
4846 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4848 (define_insn "movsf_media_nofpu"
4849 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4850 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4852 && (register_operand (operands[0], SFmode)
4853 || sh_register_operand (operands[1], SFmode))"
4859 [(set_attr "type" "arith_media,*,load_media,store_media")])
4862 [(set (match_operand:SF 0 "arith_reg_operand" "")
4863 (match_operand:SF 1 "immediate_operand" ""))]
4864 "TARGET_SHMEDIA && reload_completed
4865 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4866 [(set (match_dup 3) (match_dup 2))]
4870 REAL_VALUE_TYPE value;
4872 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4873 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4874 operands[2] = GEN_INT (values);
4876 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4879 (define_insn "movsf_i"
4880 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4881 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4884 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4885 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4886 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4887 && (arith_reg_operand (operands[0], SFmode)
4888 || arith_reg_operand (operands[1], SFmode))"
4897 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4899 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4900 ;; update_flow_info would not know where to put REG_EQUAL notes
4901 ;; when the destination changes mode.
4902 (define_insn "movsf_ie"
4903 [(set (match_operand:SF 0 "general_movdst_operand"
4904 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4905 (match_operand:SF 1 "general_movsrc_operand"
4906 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4907 (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"))
4908 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4911 && (arith_reg_operand (operands[0], SFmode)
4912 || arith_reg_operand (operands[1], SFmode)
4913 || arith_reg_operand (operands[3], SImode)
4914 || (fpul_operand (operands[0], SFmode)
4915 && memory_operand (operands[1], SFmode)
4916 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4917 || (fpul_operand (operands[1], SFmode)
4918 && memory_operand (operands[0], SFmode)
4919 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4939 ! move optimized away"
4940 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4941 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4942 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4943 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4944 (const_string "single")
4945 (const_string "none")))])
4948 [(set (match_operand:SF 0 "register_operand" "")
4949 (match_operand:SF 1 "register_operand" ""))
4950 (use (match_operand:PSI 2 "fpscr_operand" ""))
4951 (clobber (reg:SI FPUL_REG))]
4953 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4955 (clobber (scratch:SI))])
4956 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4958 (clobber (scratch:SI))])]
4961 (define_expand "movsf"
4962 [(set (match_operand:SF 0 "general_movdst_operand" "")
4963 (match_operand:SF 1 "general_movsrc_operand" ""))]
4967 if (prepare_move_operands (operands, SFmode))
4971 if (TARGET_SHMEDIA_FPU)
4972 emit_insn (gen_movsf_media (operands[0], operands[1]));
4974 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4979 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4984 (define_insn "mov_nop"
4985 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4988 [(set_attr "length" "0")
4989 (set_attr "type" "nil")])
4991 (define_expand "reload_insf"
4992 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4993 (match_operand:SF 1 "immediate_operand" "FQ"))
4994 (use (reg:PSI FPSCR_REG))
4995 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4999 (define_expand "reload_insi"
5000 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5001 (match_operand:SF 1 "immediate_operand" "FQ"))
5002 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5006 (define_insn "*movsi_y"
5007 [(set (match_operand:SI 0 "register_operand" "=y,y")
5008 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5009 (clobber (match_scratch:SI 2 "=&z,r"))]
5011 && (reload_in_progress || reload_completed)"
5013 [(set_attr "length" "4")
5014 (set_attr "type" "pcload,move")])
5017 [(set (match_operand:SI 0 "register_operand" "")
5018 (match_operand:SI 1 "immediate_operand" ""))
5019 (clobber (match_operand:SI 2 "register_operand" ""))]
5021 [(set (match_dup 2) (match_dup 1))
5022 (set (match_dup 0) (match_dup 2))]
5026 [(set (match_operand:SI 0 "register_operand" "")
5027 (match_operand:SI 1 "memory_operand" ""))
5028 (clobber (reg:SI R0_REG))]
5030 [(set (match_dup 0) (match_dup 1))]
5033 ;; ------------------------------------------------------------------------
5034 ;; Define the real conditional branch instructions.
5035 ;; ------------------------------------------------------------------------
5037 (define_insn "branch_true"
5038 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5039 (label_ref (match_operand 0 "" ""))
5042 "* return output_branch (1, insn, operands);"
5043 [(set_attr "type" "cbranch")])
5045 (define_insn "branch_false"
5046 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5047 (label_ref (match_operand 0 "" ""))
5050 "* return output_branch (0, insn, operands);"
5051 [(set_attr "type" "cbranch")])
5053 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5054 ;; which destination is too far away.
5055 ;; The const_int_operand is distinct for each branch target; it avoids
5056 ;; unwanted matches with redundant_insn.
5057 (define_insn "block_branch_redirect"
5058 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5061 [(set_attr "length" "0")])
5063 ;; This one has the additional purpose to record a possible scratch register
5064 ;; for the following branch.
5065 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5066 ;; because the insn then might be deemed dead and deleted. And we can't
5067 ;; make the use in the jump insn explicit because that would disable
5068 ;; delay slot scheduling from the target.
5069 (define_insn "indirect_jump_scratch"
5070 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5072 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5075 [(set_attr "length" "0")])
5077 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5078 ;; being pulled into the delay slot of a condbranch that has been made to
5079 ;; jump around the unconditional jump because it was out of range.
5080 (define_insn "stuff_delay_slot"
5082 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5083 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5086 [(set_attr "length" "0")
5087 (set_attr "cond_delay_slot" "yes")])
5089 ;; Conditional branch insns
5091 (define_expand "beq_media"
5093 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5094 (match_operand:DI 2 "arith_operand" "r,I06"))
5095 (label_ref:DI (match_operand 0 "" ""))
5100 (define_insn "*beq_media_i"
5102 (if_then_else (match_operator 3 "equality_comparison_operator"
5103 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5104 (match_operand:DI 2 "arith_operand" "r,I06")])
5105 (match_operand:DI 0 "target_operand" "b,b")
5111 [(set_attr "type" "cbranch_media")])
5113 (define_expand "bne_media"
5115 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5116 (match_operand:DI 2 "arith_operand" "r,I06"))
5117 (label_ref:DI (match_operand 0 "" ""))
5122 (define_expand "bgt_media"
5124 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5125 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5126 (label_ref:DI (match_operand 0 "" ""))
5131 (define_expand "bge_media"
5133 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5134 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5135 (label_ref:DI (match_operand 0 "" ""))
5140 (define_expand "bgtu_media"
5142 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5143 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5144 (label_ref:DI (match_operand 0 "" ""))
5149 (define_expand "bgeu_media"
5151 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5152 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5153 (label_ref:DI (match_operand 0 "" ""))
5158 (define_insn "*bgt_media_i"
5160 (if_then_else (match_operator 3 "greater_comparison_operator"
5161 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5162 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5163 (match_operand:DI 0 "target_operand" "b")
5166 "b%o3%' %N1, %N2, %0"
5167 [(set_attr "type" "cbranch_media")])
5169 ;; These are only needed to make invert_jump() happy.
5170 (define_insn "*blt_media_i"
5172 (if_then_else (match_operator 3 "less_comparison_operator"
5173 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5174 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5175 (match_operand:DI 0 "target_operand" "b")
5178 "b%o3%' %N2, %N1, %0"
5179 [(set_attr "type" "cbranch_media")])
5181 (define_expand "beq"
5183 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5184 (label_ref (match_operand 0 "" ""))
5191 if (GET_MODE (sh_compare_op0) != DImode)
5193 rtx tmp = gen_reg_rtx (DImode);
5195 emit_insn (gen_seq (tmp));
5196 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5200 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5201 emit_jump_insn (gen_beq_media (operands[0],
5202 sh_compare_op0, sh_compare_op1));
5206 from_compare (operands, EQ);
5209 (define_expand "bne"
5211 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5212 (label_ref (match_operand 0 "" ""))
5219 if (GET_MODE (sh_compare_op0) != DImode)
5221 rtx tmp = gen_reg_rtx (DImode);
5223 emit_insn (gen_seq (tmp));
5224 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5228 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5229 emit_jump_insn (gen_bne_media (operands[0],
5230 sh_compare_op0, sh_compare_op1));
5234 from_compare (operands, EQ);
5237 (define_expand "bgt"
5239 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5240 (label_ref (match_operand 0 "" ""))
5247 if (GET_MODE (sh_compare_op0) != DImode)
5249 rtx tmp = gen_reg_rtx (DImode);
5251 emit_insn (gen_sgt (tmp));
5252 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5256 if (sh_compare_op0 != const0_rtx)
5257 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5258 if (sh_compare_op1 != const0_rtx)
5259 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5260 emit_jump_insn (gen_bgt_media (operands[0],
5261 sh_compare_op0, sh_compare_op1));
5265 from_compare (operands, GT);
5268 (define_expand "blt"
5270 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5271 (label_ref (match_operand 0 "" ""))
5278 if (GET_MODE (sh_compare_op0) != DImode)
5280 rtx tmp = gen_reg_rtx (DImode);
5282 emit_insn (gen_slt (tmp));
5283 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5287 if (sh_compare_op0 != const0_rtx)
5288 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5289 if (sh_compare_op1 != const0_rtx)
5290 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5291 emit_jump_insn (gen_bgt_media (operands[0],
5292 sh_compare_op1, sh_compare_op0));
5296 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5298 rtx tmp = sh_compare_op0;
5299 sh_compare_op0 = sh_compare_op1;
5300 sh_compare_op1 = tmp;
5301 emit_insn (gen_bgt (operands[0]));
5304 from_compare (operands, GE);
5307 (define_expand "ble"
5309 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5310 (label_ref (match_operand 0 "" ""))
5317 if (GET_MODE (sh_compare_op0) != DImode)
5319 rtx tmp = gen_reg_rtx (DImode);
5321 emit_insn (gen_sle (tmp));
5322 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5326 if (sh_compare_op0 != const0_rtx)
5327 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5328 if (sh_compare_op1 != const0_rtx)
5329 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5330 emit_jump_insn (gen_bge_media (operands[0],
5331 sh_compare_op1, sh_compare_op0));
5337 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5339 rtx tmp = sh_compare_op0;
5340 sh_compare_op0 = sh_compare_op1;
5341 sh_compare_op1 = tmp;
5342 emit_insn (gen_bge (operands[0]));
5345 from_compare (operands, GT);
5348 (define_expand "bge"
5350 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5351 (label_ref (match_operand 0 "" ""))
5358 if (GET_MODE (sh_compare_op0) != DImode)
5360 rtx tmp = gen_reg_rtx (DImode);
5362 emit_insn (gen_sge (tmp));
5363 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5367 if (sh_compare_op0 != const0_rtx)
5368 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5369 if (sh_compare_op1 != const0_rtx)
5370 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5371 emit_jump_insn (gen_bge_media (operands[0],
5372 sh_compare_op0, sh_compare_op1));
5378 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5380 rtx tmp = sh_compare_op0;
5381 sh_compare_op0 = sh_compare_op1;
5382 sh_compare_op1 = tmp;
5383 emit_insn (gen_ble (operands[0]));
5386 from_compare (operands, GE);
5389 (define_expand "bgtu"
5391 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5392 (label_ref (match_operand 0 "" ""))
5399 if (sh_compare_op0 != const0_rtx)
5400 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5401 if (sh_compare_op1 != const0_rtx)
5402 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5403 emit_jump_insn (gen_bgtu_media (operands[0],
5404 sh_compare_op0, sh_compare_op1));
5408 from_compare (operands, GTU);
5411 (define_expand "bltu"
5413 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5414 (label_ref (match_operand 0 "" ""))
5421 if (sh_compare_op0 != const0_rtx)
5422 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5423 if (sh_compare_op1 != const0_rtx)
5424 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5425 emit_jump_insn (gen_bgtu_media (operands[0],
5426 sh_compare_op1, sh_compare_op0));
5430 from_compare (operands, GEU);
5433 (define_expand "bgeu"
5435 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5436 (label_ref (match_operand 0 "" ""))
5443 if (sh_compare_op0 != const0_rtx)
5444 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5445 if (sh_compare_op1 != const0_rtx)
5446 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5447 emit_jump_insn (gen_bgeu_media (operands[0],
5448 sh_compare_op0, sh_compare_op1));
5452 from_compare (operands, GEU);
5455 (define_expand "bleu"
5457 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5458 (label_ref (match_operand 0 "" ""))
5465 if (sh_compare_op0 != const0_rtx)
5466 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5467 if (sh_compare_op1 != const0_rtx)
5468 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5469 emit_jump_insn (gen_bgeu_media (operands[0],
5470 sh_compare_op1, sh_compare_op0));
5474 from_compare (operands, GTU);
5477 (define_expand "bunordered"
5478 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5480 (if_then_else (ne (match_dup 1) (const_int 0))
5481 (label_ref:DI (match_operand 0 "" ""))
5486 operands[1] = gen_reg_rtx (DImode);
5487 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5488 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5491 ;; ------------------------------------------------------------------------
5492 ;; Jump and linkage insns
5493 ;; ------------------------------------------------------------------------
5495 (define_insn "jump_compact"
5497 (label_ref (match_operand 0 "" "")))]
5501 /* The length is 16 if the delay slot is unfilled. */
5502 if (get_attr_length(insn) > 4)
5503 return output_far_jump(insn, operands[0]);
5505 return \"bra %l0%#\";
5507 [(set_attr "type" "jump")
5508 (set_attr "needs_delay_slot" "yes")])
5510 ;; ??? It would be much saner to explicitly use the scratch register
5511 ;; in the jump insn, and have indirect_jump_scratch only set it,
5512 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5513 ;; from the target then, as it uses simplejump_p.
5514 ;;(define_insn "jump_compact_far"
5516 ;; (label_ref (match_operand 0 "" "")))
5517 ;; (use (match_operand 1 "register_operand" "r")]
5519 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5520 ;; [(set_attr "type" "jump")
5521 ;; (set_attr "needs_delay_slot" "yes")])
5523 (define_insn "jump_media"
5525 (match_operand:DI 0 "target_operand" "b"))]
5528 [(set_attr "type" "jump_media")])
5530 (define_expand "jump"
5532 (label_ref (match_operand 0 "" "")))]
5537 emit_jump_insn (gen_jump_compact (operands[0]));
5538 else if (TARGET_SHMEDIA)
5540 if (reload_in_progress || reload_completed)
5542 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5548 (define_insn "force_mode_for_call"
5549 [(use (reg:PSI FPSCR_REG))]
5552 [(set_attr "length" "0")
5553 (set (attr "fp_mode")
5554 (if_then_else (eq_attr "fpu_single" "yes")
5555 (const_string "single") (const_string "double")))])
5557 (define_insn "calli"
5558 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5559 (match_operand 1 "" ""))
5560 (use (reg:PSI FPSCR_REG))
5561 (clobber (reg:SI PR_REG))]
5564 [(set_attr "type" "call")
5565 (set (attr "fp_mode")
5566 (if_then_else (eq_attr "fpu_single" "yes")
5567 (const_string "single") (const_string "double")))
5568 (set_attr "needs_delay_slot" "yes")
5569 (set_attr "fp_set" "unknown")])
5571 ;; This is a pc-rel call, using bsrf, for use with PIC.
5573 (define_insn "calli_pcrel"
5574 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5575 (match_operand 1 "" ""))
5576 (use (reg:PSI FPSCR_REG))
5577 (use (reg:SI PIC_REG))
5578 (use (match_operand 2 "" ""))
5579 (clobber (reg:SI PR_REG))]
5582 [(set_attr "type" "call")
5583 (set (attr "fp_mode")
5584 (if_then_else (eq_attr "fpu_single" "yes")
5585 (const_string "single") (const_string "double")))
5586 (set_attr "needs_delay_slot" "yes")
5587 (set_attr "fp_set" "unknown")])
5589 (define_insn_and_split "call_pcrel"
5590 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5591 (match_operand 1 "" ""))
5592 (use (reg:PSI FPSCR_REG))
5593 (use (reg:SI PIC_REG))
5594 (clobber (reg:SI PR_REG))
5595 (clobber (match_scratch:SI 2 "=r"))]
5602 rtx lab = PATTERN (gen_call_site ());
5604 if (SYMBOL_REF_LOCAL_P (operands[0]))
5605 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5607 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5608 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5611 [(set_attr "type" "call")
5612 (set (attr "fp_mode")
5613 (if_then_else (eq_attr "fpu_single" "yes")
5614 (const_string "single") (const_string "double")))
5615 (set_attr "needs_delay_slot" "yes")
5616 (set_attr "fp_set" "unknown")])
5618 (define_insn "call_compact"
5619 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5620 (match_operand 1 "" ""))
5621 (match_operand 2 "immediate_operand" "n")
5622 (use (reg:SI R0_REG))
5623 (use (reg:SI R1_REG))
5624 (use (reg:PSI FPSCR_REG))
5625 (clobber (reg:SI PR_REG))]
5626 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5628 [(set_attr "type" "call")
5629 (set (attr "fp_mode")
5630 (if_then_else (eq_attr "fpu_single" "yes")
5631 (const_string "single") (const_string "double")))
5632 (set_attr "needs_delay_slot" "yes")])
5634 (define_insn "call_compact_rettramp"
5635 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5636 (match_operand 1 "" ""))
5637 (match_operand 2 "immediate_operand" "n")
5638 (use (reg:SI R0_REG))
5639 (use (reg:SI R1_REG))
5640 (use (reg:PSI FPSCR_REG))
5641 (clobber (reg:SI R10_REG))
5642 (clobber (reg:SI PR_REG))]
5643 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5645 [(set_attr "type" "call")
5646 (set (attr "fp_mode")
5647 (if_then_else (eq_attr "fpu_single" "yes")
5648 (const_string "single") (const_string "double")))
5649 (set_attr "needs_delay_slot" "yes")])
5651 (define_insn "call_media"
5652 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5653 (match_operand 1 "" ""))
5654 (clobber (reg:DI PR_MEDIA_REG))]
5657 [(set_attr "type" "jump_media")])
5659 (define_insn "call_valuei"
5660 [(set (match_operand 0 "" "=rf")
5661 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5662 (match_operand 2 "" "")))
5663 (use (reg:PSI FPSCR_REG))
5664 (clobber (reg:SI PR_REG))]
5667 [(set_attr "type" "call")
5668 (set (attr "fp_mode")
5669 (if_then_else (eq_attr "fpu_single" "yes")
5670 (const_string "single") (const_string "double")))
5671 (set_attr "needs_delay_slot" "yes")
5672 (set_attr "fp_set" "unknown")])
5674 (define_insn "call_valuei_pcrel"
5675 [(set (match_operand 0 "" "=rf")
5676 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5677 (match_operand 2 "" "")))
5678 (use (reg:PSI FPSCR_REG))
5679 (use (reg:SI PIC_REG))
5680 (use (match_operand 3 "" ""))
5681 (clobber (reg:SI PR_REG))]
5684 [(set_attr "type" "call")
5685 (set (attr "fp_mode")
5686 (if_then_else (eq_attr "fpu_single" "yes")
5687 (const_string "single") (const_string "double")))
5688 (set_attr "needs_delay_slot" "yes")
5689 (set_attr "fp_set" "unknown")])
5691 (define_insn_and_split "call_value_pcrel"
5692 [(set (match_operand 0 "" "=rf")
5693 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5694 (match_operand 2 "" "")))
5695 (use (reg:PSI FPSCR_REG))
5696 (use (reg:SI PIC_REG))
5697 (clobber (reg:SI PR_REG))
5698 (clobber (match_scratch:SI 3 "=r"))]
5705 rtx lab = PATTERN (gen_call_site ());
5707 if (SYMBOL_REF_LOCAL_P (operands[1]))
5708 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5710 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5711 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5715 [(set_attr "type" "call")
5716 (set (attr "fp_mode")
5717 (if_then_else (eq_attr "fpu_single" "yes")
5718 (const_string "single") (const_string "double")))
5719 (set_attr "needs_delay_slot" "yes")
5720 (set_attr "fp_set" "unknown")])
5722 (define_insn "call_value_compact"
5723 [(set (match_operand 0 "" "=rf")
5724 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5725 (match_operand 2 "" "")))
5726 (match_operand 3 "immediate_operand" "n")
5727 (use (reg:SI R0_REG))
5728 (use (reg:SI R1_REG))
5729 (use (reg:PSI FPSCR_REG))
5730 (clobber (reg:SI PR_REG))]
5731 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5733 [(set_attr "type" "call")
5734 (set (attr "fp_mode")
5735 (if_then_else (eq_attr "fpu_single" "yes")
5736 (const_string "single") (const_string "double")))
5737 (set_attr "needs_delay_slot" "yes")])
5739 (define_insn "call_value_compact_rettramp"
5740 [(set (match_operand 0 "" "=rf")
5741 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5742 (match_operand 2 "" "")))
5743 (match_operand 3 "immediate_operand" "n")
5744 (use (reg:SI R0_REG))
5745 (use (reg:SI R1_REG))
5746 (use (reg:PSI FPSCR_REG))
5747 (clobber (reg:SI R10_REG))
5748 (clobber (reg:SI PR_REG))]
5749 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5751 [(set_attr "type" "call")
5752 (set (attr "fp_mode")
5753 (if_then_else (eq_attr "fpu_single" "yes")
5754 (const_string "single") (const_string "double")))
5755 (set_attr "needs_delay_slot" "yes")])
5757 (define_insn "call_value_media"
5758 [(set (match_operand 0 "" "=rf")
5759 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5760 (match_operand 2 "" "")))
5761 (clobber (reg:DI PR_MEDIA_REG))]
5764 [(set_attr "type" "jump_media")])
5766 (define_expand "call"
5767 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5768 (match_operand 1 "" ""))
5769 (match_operand 2 "" "")
5770 (use (reg:PSI FPSCR_REG))
5771 (clobber (reg:SI PR_REG))])]
5777 operands[0] = XEXP (operands[0], 0);
5778 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5780 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5782 rtx reg = gen_reg_rtx (Pmode);
5784 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5789 operands[0] = gen_sym2PIC (operands[0]);
5790 PUT_MODE (operands[0], Pmode);
5793 if (GET_MODE (operands[0]) == SImode)
5795 if (GET_CODE (operands[0]) == REG)
5796 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5797 else if (GET_CODE (operands[0]) == SUBREG)
5799 operands[0] = SUBREG_REG (operands[0]);
5800 if (GET_MODE (operands[0]) != DImode)
5801 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5805 operands[0] = shallow_copy_rtx (operands[0]);
5806 PUT_MODE (operands[0], DImode);
5809 if (! target_reg_operand (operands[0], DImode))
5810 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5811 emit_call_insn (gen_call_media (operands[0], operands[1]));
5814 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5816 rtx cookie_rtx = operands[2];
5817 long cookie = INTVAL (cookie_rtx);
5818 rtx func = XEXP (operands[0], 0);
5823 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5825 rtx reg = gen_reg_rtx (Pmode);
5827 emit_insn (gen_symGOTPLT2reg (reg, func));
5831 func = legitimize_pic_address (func, Pmode, 0);
5834 r0 = gen_rtx_REG (SImode, R0_REG);
5835 r1 = gen_rtx_REG (SImode, R1_REG);
5837 /* Since such a call function may use all call-clobbered
5838 registers, we force a mode switch earlier, so that we don't
5839 run out of registers when adjusting fpscr for the call. */
5840 emit_insn (gen_force_mode_for_call ());
5842 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5845 rtx reg = gen_reg_rtx (Pmode);
5847 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5850 operands[0] = force_reg (SImode, operands[0]);
5852 emit_move_insn (r0, func);
5853 emit_move_insn (r1, cookie_rtx);
5855 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5856 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5859 emit_call_insn (gen_call_compact (operands[0], operands[1],
5864 else if (TARGET_SHCOMPACT && flag_pic
5865 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5866 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5868 rtx reg = gen_reg_rtx (Pmode);
5870 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5871 XEXP (operands[0], 0) = reg;
5873 if (flag_pic && TARGET_SH2
5874 && GET_CODE (operands[0]) == MEM
5875 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5877 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5882 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5883 operands[1] = operands[2];
5886 emit_call_insn (gen_calli (operands[0], operands[1]));
5890 (define_insn "call_pop_compact"
5891 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5892 (match_operand 1 "" ""))
5893 (match_operand 2 "immediate_operand" "n")
5894 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5895 (match_operand 3 "immediate_operand" "n")))
5896 (use (reg:SI R0_REG))
5897 (use (reg:SI R1_REG))
5898 (use (reg:PSI FPSCR_REG))
5899 (clobber (reg:SI PR_REG))]
5900 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5902 [(set_attr "type" "call")
5903 (set (attr "fp_mode")
5904 (if_then_else (eq_attr "fpu_single" "yes")
5905 (const_string "single") (const_string "double")))
5906 (set_attr "needs_delay_slot" "yes")])
5908 (define_insn "call_pop_compact_rettramp"
5909 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5910 (match_operand 1 "" ""))
5911 (match_operand 2 "immediate_operand" "n")
5912 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5913 (match_operand 3 "immediate_operand" "n")))
5914 (use (reg:SI R0_REG))
5915 (use (reg:SI R1_REG))
5916 (use (reg:PSI FPSCR_REG))
5917 (clobber (reg:SI R10_REG))
5918 (clobber (reg:SI PR_REG))]
5919 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5921 [(set_attr "type" "call")
5922 (set (attr "fp_mode")
5923 (if_then_else (eq_attr "fpu_single" "yes")
5924 (const_string "single") (const_string "double")))
5925 (set_attr "needs_delay_slot" "yes")])
5927 (define_expand "call_pop"
5928 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5929 (match_operand 1 "" ""))
5930 (match_operand 2 "" "")
5931 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5932 (match_operand 3 "" "")))])]
5936 if (operands[2] && INTVAL (operands[2]))
5938 rtx cookie_rtx = operands[2];
5939 long cookie = INTVAL (cookie_rtx);
5940 rtx func = XEXP (operands[0], 0);
5945 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5947 rtx reg = gen_reg_rtx (Pmode);
5949 emit_insn (gen_symGOTPLT2reg (reg, func));
5953 func = legitimize_pic_address (func, Pmode, 0);
5956 r0 = gen_rtx_REG (SImode, R0_REG);
5957 r1 = gen_rtx_REG (SImode, R1_REG);
5959 /* Since such a call function may use all call-clobbered
5960 registers, we force a mode switch earlier, so that we don't
5961 run out of registers when adjusting fpscr for the call. */
5962 emit_insn (gen_force_mode_for_call ());
5964 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5967 rtx reg = gen_reg_rtx (Pmode);
5969 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5972 operands[0] = force_reg (SImode, operands[0]);
5974 emit_move_insn (r0, func);
5975 emit_move_insn (r1, cookie_rtx);
5977 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5978 emit_call_insn (gen_call_pop_compact_rettramp
5979 (operands[0], operands[1], operands[2], operands[3]));
5981 emit_call_insn (gen_call_pop_compact
5982 (operands[0], operands[1], operands[2], operands[3]));
5990 (define_expand "call_value"
5991 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5992 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5993 (match_operand 2 "" "")))
5994 (match_operand 3 "" "")
5995 (use (reg:PSI FPSCR_REG))
5996 (clobber (reg:SI PR_REG))])]
6002 operands[1] = XEXP (operands[1], 0);
6003 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6005 if (! SYMBOL_REF_LOCAL_P (operands[1]))
6007 rtx reg = gen_reg_rtx (Pmode);
6009 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6014 operands[1] = gen_sym2PIC (operands[1]);
6015 PUT_MODE (operands[1], Pmode);
6018 if (GET_MODE (operands[1]) == SImode)
6020 if (GET_CODE (operands[1]) == REG)
6021 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6022 else if (GET_CODE (operands[1]) == SUBREG)
6024 operands[1] = SUBREG_REG (operands[1]);
6025 if (GET_MODE (operands[1]) != DImode)
6026 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6030 operands[1] = shallow_copy_rtx (operands[1]);
6031 PUT_MODE (operands[1], DImode);
6034 if (! target_reg_operand (operands[1], DImode))
6035 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6036 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6040 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6042 rtx cookie_rtx = operands[3];
6043 long cookie = INTVAL (cookie_rtx);
6044 rtx func = XEXP (operands[1], 0);
6049 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6051 rtx reg = gen_reg_rtx (Pmode);
6053 emit_insn (gen_symGOTPLT2reg (reg, func));
6057 func = legitimize_pic_address (func, Pmode, 0);
6060 r0 = gen_rtx_REG (SImode, R0_REG);
6061 r1 = gen_rtx_REG (SImode, R1_REG);
6063 /* Since such a call function may use all call-clobbered
6064 registers, we force a mode switch earlier, so that we don't
6065 run out of registers when adjusting fpscr for the call. */
6066 emit_insn (gen_force_mode_for_call ());
6068 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6071 rtx reg = gen_reg_rtx (Pmode);
6073 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6076 operands[1] = force_reg (SImode, operands[1]);
6078 emit_move_insn (r0, func);
6079 emit_move_insn (r1, cookie_rtx);
6081 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6082 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6087 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6088 operands[2], operands[3]));
6092 else if (TARGET_SHCOMPACT && flag_pic
6093 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6094 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6096 rtx reg = gen_reg_rtx (Pmode);
6098 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6099 XEXP (operands[1], 0) = reg;
6101 if (flag_pic && TARGET_SH2
6102 && GET_CODE (operands[1]) == MEM
6103 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6105 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6110 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6112 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6116 (define_insn "sibcalli"
6117 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6118 (match_operand 1 "" ""))
6119 (use (reg:PSI FPSCR_REG))
6123 [(set_attr "needs_delay_slot" "yes")
6124 (set (attr "fp_mode")
6125 (if_then_else (eq_attr "fpu_single" "yes")
6126 (const_string "single") (const_string "double")))
6127 (set_attr "type" "jump_ind")])
6129 (define_insn "sibcalli_pcrel"
6130 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6131 (match_operand 1 "" ""))
6132 (use (match_operand 2 "" ""))
6133 (use (reg:PSI FPSCR_REG))
6137 [(set_attr "needs_delay_slot" "yes")
6138 (set (attr "fp_mode")
6139 (if_then_else (eq_attr "fpu_single" "yes")
6140 (const_string "single") (const_string "double")))
6141 (set_attr "type" "jump_ind")])
6143 (define_insn_and_split "sibcall_pcrel"
6144 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6145 (match_operand 1 "" ""))
6146 (use (reg:PSI FPSCR_REG))
6147 (clobber (match_scratch:SI 2 "=k"))
6155 rtx lab = PATTERN (gen_call_site ());
6158 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6159 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6161 SIBLING_CALL_P (call_insn) = 1;
6164 [(set_attr "needs_delay_slot" "yes")
6165 (set (attr "fp_mode")
6166 (if_then_else (eq_attr "fpu_single" "yes")
6167 (const_string "single") (const_string "double")))
6168 (set_attr "type" "jump_ind")])
6170 (define_insn "sibcall_compact"
6171 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6172 (match_operand 1 "" ""))
6174 (use (match_operand:SI 2 "register_operand" "z,x"))
6175 (use (reg:SI R1_REG))
6176 (use (reg:PSI FPSCR_REG))
6177 ;; We want to make sure the `x' above will only match MACH_REG
6178 ;; because sibcall_epilogue may clobber MACL_REG.
6179 (clobber (reg:SI MACL_REG))]
6183 jmp @%0\\n sts %2, r0"
6184 [(set_attr "needs_delay_slot" "yes,no")
6185 (set_attr "length" "2,4")
6186 (set (attr "fp_mode") (const_string "single"))
6187 (set_attr "type" "jump_ind")])
6189 (define_insn "sibcall_media"
6190 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6191 (match_operand 1 "" ""))
6192 (use (reg:SI PR_MEDIA_REG))
6196 [(set_attr "type" "jump_media")])
6198 (define_expand "sibcall"
6200 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6201 (match_operand 1 "" ""))
6202 (match_operand 2 "" "")
6203 (use (reg:PSI FPSCR_REG))
6210 operands[0] = XEXP (operands[0], 0);
6211 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6213 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6215 rtx reg = gen_reg_rtx (Pmode);
6217 /* We must not use GOTPLT for sibcalls, because PIC_REG
6218 must be restored before the PLT code gets to run. */
6219 emit_insn (gen_symGOT2reg (reg, operands[0]));
6224 operands[0] = gen_sym2PIC (operands[0]);
6225 PUT_MODE (operands[0], Pmode);
6228 if (GET_MODE (operands[0]) == SImode)
6230 if (GET_CODE (operands[0]) == REG)
6231 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6232 else if (GET_CODE (operands[0]) == SUBREG)
6234 operands[0] = SUBREG_REG (operands[0]);
6235 if (GET_MODE (operands[0]) != DImode)
6236 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6240 operands[0] = shallow_copy_rtx (operands[0]);
6241 PUT_MODE (operands[0], DImode);
6244 if (! target_reg_operand (operands[0], DImode))
6245 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6246 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6249 else if (TARGET_SHCOMPACT && operands[2]
6250 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6252 rtx cookie_rtx = operands[2];
6253 long cookie = INTVAL (cookie_rtx);
6254 rtx func = XEXP (operands[0], 0);
6259 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6261 rtx reg = gen_reg_rtx (Pmode);
6263 emit_insn (gen_symGOT2reg (reg, func));
6267 func = legitimize_pic_address (func, Pmode, 0);
6270 /* FIXME: if we could tell whether all argument registers are
6271 already taken, we could decide whether to force the use of
6272 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6273 simple way to tell. We could use the CALL_COOKIE, but we
6274 can't currently tell a register used for regular argument
6275 passing from one that is unused. If we leave it up to reload
6276 to decide which register to use, it seems to always choose
6277 R0_REG, which leaves no available registers in SIBCALL_REGS
6278 to hold the address of the trampoline. */
6279 mach = gen_rtx_REG (SImode, MACH_REG);
6280 r1 = gen_rtx_REG (SImode, R1_REG);
6282 /* Since such a call function may use all call-clobbered
6283 registers, we force a mode switch earlier, so that we don't
6284 run out of registers when adjusting fpscr for the call. */
6285 emit_insn (gen_force_mode_for_call ());
6287 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6290 rtx reg = gen_reg_rtx (Pmode);
6292 emit_insn (gen_symGOT2reg (reg, operands[0]));
6295 operands[0] = force_reg (SImode, operands[0]);
6297 /* We don't need a return trampoline, since the callee will
6298 return directly to the upper caller. */
6299 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6301 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6302 cookie_rtx = GEN_INT (cookie);
6305 emit_move_insn (mach, func);
6306 emit_move_insn (r1, cookie_rtx);
6308 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6311 else if (TARGET_SHCOMPACT && flag_pic
6312 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6313 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6315 rtx reg = gen_reg_rtx (Pmode);
6317 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6318 XEXP (operands[0], 0) = reg;
6320 if (flag_pic && TARGET_SH2
6321 && GET_CODE (operands[0]) == MEM
6322 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6323 /* The PLT needs the PIC register, but the epilogue would have
6324 to restore it, so we can only use PC-relative PIC calls for
6325 static functions. */
6326 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6328 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6332 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6334 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6338 (define_expand "sibcall_value"
6339 [(set (match_operand 0 "" "")
6340 (call (match_operand 1 "" "")
6341 (match_operand 2 "" "")))
6342 (match_operand 3 "" "")]
6346 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6350 (define_insn "call_value_pop_compact"
6351 [(set (match_operand 0 "" "=rf")
6352 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6353 (match_operand 2 "" "")))
6354 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6355 (match_operand 4 "immediate_operand" "n")))
6356 (match_operand 3 "immediate_operand" "n")
6357 (use (reg:SI R0_REG))
6358 (use (reg:SI R1_REG))
6359 (use (reg:PSI FPSCR_REG))
6360 (clobber (reg:SI PR_REG))]
6361 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6363 [(set_attr "type" "call")
6364 (set (attr "fp_mode")
6365 (if_then_else (eq_attr "fpu_single" "yes")
6366 (const_string "single") (const_string "double")))
6367 (set_attr "needs_delay_slot" "yes")])
6369 (define_insn "call_value_pop_compact_rettramp"
6370 [(set (match_operand 0 "" "=rf")
6371 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6372 (match_operand 2 "" "")))
6373 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6374 (match_operand 4 "immediate_operand" "n")))
6375 (match_operand 3 "immediate_operand" "n")
6376 (use (reg:SI R0_REG))
6377 (use (reg:SI R1_REG))
6378 (use (reg:PSI FPSCR_REG))
6379 (clobber (reg:SI R10_REG))
6380 (clobber (reg:SI PR_REG))]
6381 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6383 [(set_attr "type" "call")
6384 (set (attr "fp_mode")
6385 (if_then_else (eq_attr "fpu_single" "yes")
6386 (const_string "single") (const_string "double")))
6387 (set_attr "needs_delay_slot" "yes")])
6389 (define_expand "call_value_pop"
6390 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6391 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6392 (match_operand 2 "" "")))
6393 (match_operand 3 "" "")
6394 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6395 (match_operand 4 "" "")))])]
6399 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6401 rtx cookie_rtx = operands[3];
6402 long cookie = INTVAL (cookie_rtx);
6403 rtx func = XEXP (operands[1], 0);
6408 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6410 rtx reg = gen_reg_rtx (Pmode);
6412 emit_insn (gen_symGOTPLT2reg (reg, func));
6416 func = legitimize_pic_address (func, Pmode, 0);
6419 r0 = gen_rtx_REG (SImode, R0_REG);
6420 r1 = gen_rtx_REG (SImode, R1_REG);
6422 /* Since such a call function may use all call-clobbered
6423 registers, we force a mode switch earlier, so that we don't
6424 run out of registers when adjusting fpscr for the call. */
6425 emit_insn (gen_force_mode_for_call ());
6427 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6430 rtx reg = gen_reg_rtx (Pmode);
6432 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6435 operands[1] = force_reg (SImode, operands[1]);
6437 emit_move_insn (r0, func);
6438 emit_move_insn (r1, cookie_rtx);
6440 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6441 emit_call_insn (gen_call_value_pop_compact_rettramp
6442 (operands[0], operands[1], operands[2],
6443 operands[3], operands[4]));
6445 emit_call_insn (gen_call_value_pop_compact
6446 (operands[0], operands[1], operands[2],
6447 operands[3], operands[4]));
6455 (define_expand "sibcall_epilogue"
6460 sh_expand_epilogue (1);
6461 if (TARGET_SHCOMPACT)
6465 /* If epilogue clobbers r0, preserve it in macl. */
6466 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6467 if ((set = single_set (insn))
6468 && GET_CODE (SET_DEST (set)) == REG
6469 && REGNO (SET_DEST (set)) == R0_REG)
6471 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6472 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6475 /* We can't tell at this point whether the sibcall is a
6476 sibcall_compact and, if it is, whether it uses r0 or
6477 mach as operand 2, so let the instructions that
6478 preserve r0 be optimized away if r0 turns out to be
6480 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6481 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6483 i = emit_move_insn (r0, tmp);
6484 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6492 (define_insn "indirect_jump_compact"
6494 (match_operand:SI 0 "arith_reg_operand" "r"))]
6497 [(set_attr "needs_delay_slot" "yes")
6498 (set_attr "type" "jump_ind")])
6500 (define_expand "indirect_jump"
6502 (match_operand 0 "register_operand" ""))]
6506 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6507 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6510 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6511 ;; which can be present in structured code from indirect jumps which can not
6512 ;; be present in structured code. This allows -fprofile-arcs to work.
6514 ;; For SH1 processors.
6515 (define_insn "casesi_jump_1"
6517 (match_operand:SI 0 "register_operand" "r"))
6518 (use (label_ref (match_operand 1 "" "")))]
6521 [(set_attr "needs_delay_slot" "yes")
6522 (set_attr "type" "jump_ind")])
6524 ;; For all later processors.
6525 (define_insn "casesi_jump_2"
6526 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6527 (label_ref (match_operand 1 "" ""))))
6528 (use (label_ref (match_operand 2 "" "")))]
6530 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6532 [(set_attr "needs_delay_slot" "yes")
6533 (set_attr "type" "jump_ind")])
6535 (define_insn "casesi_jump_media"
6536 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6537 (use (label_ref (match_operand 1 "" "")))]
6540 [(set_attr "type" "jump_media")])
6542 ;; Call subroutine returning any type.
6543 ;; ??? This probably doesn't work.
6545 (define_expand "untyped_call"
6546 [(parallel [(call (match_operand 0 "" "")
6548 (match_operand 1 "" "")
6549 (match_operand 2 "" "")])]
6550 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6555 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6557 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6559 rtx set = XVECEXP (operands[2], 0, i);
6560 emit_move_insn (SET_DEST (set), SET_SRC (set));
6563 /* The optimizer does not know that the call sets the function value
6564 registers we stored in the result block. We avoid problems by
6565 claiming that all hard registers are used and clobbered at this
6567 emit_insn (gen_blockage ());
6572 ;; ------------------------------------------------------------------------
6574 ;; ------------------------------------------------------------------------
6577 [(set (reg:SI T_REG)
6578 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6579 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6582 [(set_attr "type" "arith")])
6589 ;; Load address of a label. This is only generated by the casesi expand,
6590 ;; and by machine_dependent_reorg (fixing up fp moves).
6591 ;; This must use unspec, because this only works for labels that are
6595 [(set (reg:SI R0_REG)
6596 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6599 [(set_attr "in_delay_slot" "no")
6600 (set_attr "type" "arith")])
6602 ;; machine_dependent_reorg will make this a `mova'.
6603 (define_insn "mova_const"
6604 [(set (reg:SI R0_REG)
6605 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6608 [(set_attr "in_delay_slot" "no")
6609 (set_attr "type" "arith")])
6611 (define_expand "GOTaddr2picreg"
6612 [(set (reg:SI R0_REG)
6613 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6615 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6616 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6619 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6620 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6623 operands[1] = gen_datalabel_ref (operands[1]);
6627 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6628 rtx dipic = operands[0];
6629 rtx lab = PATTERN (gen_call_site ());
6632 equiv = operands[1];
6633 operands[1] = gen_rtx_MINUS (DImode,
6637 gen_rtx_MINUS (DImode,
6638 gen_rtx_CONST (DImode,
6641 operands[1] = gen_sym2PIC (operands[1]);
6642 PUT_MODE (operands[1], DImode);
6644 if (GET_MODE (dipic) != DImode)
6645 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6647 if (TARGET_SHMEDIA64)
6648 emit_insn (gen_movdi_const (dipic, operands[1]));
6650 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6652 emit_insn (gen_ptrel (tr, dipic, lab));
6654 if (GET_MODE (operands[0]) != GET_MODE (tr))
6655 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6657 insn = emit_move_insn (operands[0], tr);
6659 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6668 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6669 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6670 UNSPEC_DATALABEL)))]
6671 "TARGET_SHMEDIA && flag_pic
6672 && EXTRA_CONSTRAINT_Csy (operands[1])"
6673 "ptb/u datalabel %1, %0"
6674 [(set_attr "type" "pt_media")
6675 (set_attr "length" "*")])
6677 (define_insn "ptrel"
6678 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6679 (plus:DI (match_operand:DI 1 "register_operand" "r")
6681 (match_operand:DI 2 "" "")]
6683 "%O2: ptrel/u %1, %0"
6684 [(set_attr "type" "ptabs_media")])
6686 (define_expand "builtin_setjmp_receiver"
6687 [(match_operand 0 "" "")]
6691 emit_insn (gen_GOTaddr2picreg ());
6695 (define_expand "call_site"
6696 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6700 static HOST_WIDE_INT i = 0;
6701 operands[0] = GEN_INT (i);
6705 (define_expand "sym_label2reg"
6706 [(set (match_operand:SI 0 "" "")
6709 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6712 (match_operand:SI 2 "" "")
6716 (define_expand "symGOT_load"
6717 [(set (match_dup 2) (match_operand 1 "" ""))
6718 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6719 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6725 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6726 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6730 rtx reg = operands[2];
6732 if (GET_MODE (reg) != DImode)
6733 reg = gen_rtx_SUBREG (DImode, reg, 0);
6736 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6738 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6741 emit_move_insn (operands[2], operands[1]);
6743 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6745 gen_rtx_REG (Pmode, PIC_REG)));
6747 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6749 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6756 (define_expand "sym2GOT"
6757 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6761 (define_expand "symGOT2reg"
6762 [(match_operand 0 "" "") (match_operand 1 "" "")]
6768 gotsym = gen_sym2GOT (operands[1]);
6769 PUT_MODE (gotsym, Pmode);
6770 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6772 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6777 (define_expand "sym2GOTPLT"
6778 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6782 (define_expand "symGOTPLT2reg"
6783 [(match_operand 0 "" "") (match_operand 1 "" "")]
6787 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6791 (define_expand "sym2GOTOFF"
6792 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6796 (define_expand "symGOTOFF2reg"
6797 [(match_operand 0 "" "") (match_operand 1 "" "")]
6801 rtx gotoffsym, insn;
6802 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6804 gotoffsym = gen_sym2GOTOFF (operands[1]);
6805 PUT_MODE (gotoffsym, Pmode);
6806 emit_move_insn (t, gotoffsym);
6807 insn = emit_move_insn (operands[0],
6808 gen_rtx_PLUS (Pmode, t,
6809 gen_rtx_REG (Pmode, PIC_REG)));
6811 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6817 (define_expand "symPLT_label2reg"
6818 [(set (match_operand:SI 0 "" "")
6821 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6825 (match_operand:SI 2 "" "")
6827 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6828 ;; Even though the PIC register is not really used by the call
6829 ;; sequence in which this is expanded, the PLT code assumes the PIC
6830 ;; register is set, so we must not skip its initialization. Since
6831 ;; we only use this expand as part of calling sequences, and never
6832 ;; to take the address of a function, this is the best point to
6833 ;; insert the (use). Using the PLT to take the address of a
6834 ;; function would be wrong, not only because the PLT entry could
6835 ;; then be called from a function that doesn't initialize the PIC
6836 ;; register to the proper GOT, but also because pointers to the
6837 ;; same function might not compare equal, should they be set by
6838 ;; different shared libraries.
6839 (use (reg:SI PIC_REG))]
6843 (define_expand "sym2PIC"
6844 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6848 ;; TLS code generation.
6849 ;; ??? this should be a define_insn_and_split
6850 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6851 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6854 (define_insn "tls_global_dynamic"
6855 [(set (match_operand:SI 0 "register_operand" "=&z")
6856 (call (unspec:SI [(match_operand:SI 1 "" "")]
6859 (use (reg:PSI FPSCR_REG))
6860 (use (reg:SI PIC_REG))
6861 (clobber (reg:SI PR_REG))
6862 (clobber (scratch:SI))]
6868 \\tmova\\t2f,r0\\n\\
6869 \\tmov.l\\t2f,r1\\n\\
6872 \\tadd\\tr12,r4\\n\\
6876 1:\\t.long\\t%a1@TLSGD\\n\\
6877 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6880 [(set_attr "type" "tls_load")
6881 (set_attr "length" "26")])
6883 (define_insn "tls_local_dynamic"
6884 [(set (match_operand:SI 0 "register_operand" "=&z")
6885 (call (unspec:SI [(match_operand:SI 1 "" "")]
6888 (use (reg:PSI FPSCR_REG))
6889 (use (reg:SI PIC_REG))
6890 (clobber (reg:SI PR_REG))
6891 (clobber (scratch:SI))]
6897 \\tmova\\t2f,r0\\n\\
6898 \\tmov.l\\t2f,r1\\n\\
6901 \\tadd\\tr12,r4\\n\\
6905 1:\\t.long\\t%a1@TLSLDM\\n\\
6906 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6909 [(set_attr "type" "tls_load")
6910 (set_attr "length" "26")])
6912 (define_expand "sym2DTPOFF"
6913 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6917 (define_expand "symDTPOFF2reg"
6918 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6922 rtx dtpoffsym, insn;
6923 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6925 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6926 PUT_MODE (dtpoffsym, Pmode);
6927 emit_move_insn (t, dtpoffsym);
6928 insn = emit_move_insn (operands[0],
6929 gen_rtx_PLUS (Pmode, t, operands[2]));
6933 (define_expand "sym2GOTTPOFF"
6934 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6938 (define_insn "tls_initial_exec"
6939 [(set (match_operand:SI 0 "register_operand" "=&r")
6940 (unspec:SI [(match_operand:SI 1 "" "")]
6942 (use (reg:SI GBR_REG))
6943 (use (reg:SI PIC_REG))
6944 (clobber (reg:SI R0_REG))]
6950 \\tstc\\tgbr,%0\\n\\
6951 \\tmov.l\\t@(r0,r12),r0\\n\\
6955 1:\\t.long\\t%a1\\n\\
6958 [(set_attr "type" "tls_load")
6959 (set_attr "length" "16")])
6961 (define_expand "sym2TPOFF"
6962 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6966 (define_expand "symTPOFF2reg"
6967 [(match_operand 0 "" "") (match_operand 1 "" "")]
6973 tpoffsym = gen_sym2TPOFF (operands[1]);
6974 PUT_MODE (tpoffsym, Pmode);
6975 insn = emit_move_insn (operands[0], tpoffsym);
6979 (define_insn "load_gbr"
6980 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6981 (use (reg:SI GBR_REG))]
6984 [(set_attr "type" "tls_load")])
6986 ;; case instruction for switch statements.
6988 ;; Operand 0 is index
6989 ;; operand 1 is the minimum bound
6990 ;; operand 2 is the maximum bound - minimum bound + 1
6991 ;; operand 3 is CODE_LABEL for the table;
6992 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6994 (define_expand "casesi"
6995 [(match_operand:SI 0 "arith_reg_operand" "")
6996 (match_operand:SI 1 "arith_reg_operand" "")
6997 (match_operand:SI 2 "arith_reg_operand" "")
6998 (match_operand 3 "" "") (match_operand 4 "" "")]
7002 rtx reg = gen_reg_rtx (SImode);
7003 rtx reg2 = gen_reg_rtx (SImode);
7006 rtx reg = gen_reg_rtx (DImode);
7007 rtx reg2 = gen_reg_rtx (DImode);
7008 rtx reg3 = gen_reg_rtx (DImode);
7009 rtx reg4 = gen_reg_rtx (DImode);
7010 rtx reg5 = gen_reg_rtx (DImode);
7012 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7013 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7014 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7016 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7017 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7018 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7019 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7020 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7021 (DImode, operands[3])));
7022 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7023 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7024 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7028 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7029 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7030 /* If optimizing, casesi_worker depends on the mode of the instruction
7031 before label it 'uses' - operands[3]. */
7032 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7034 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7036 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7038 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7039 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7040 operands[3], but to lab. We will fix this up in
7041 machine_dependent_reorg. */
7046 (define_expand "casesi_0"
7047 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7048 (set (match_dup 4) (minus:SI (match_dup 4)
7049 (match_operand:SI 1 "arith_operand" "")))
7051 (gtu:SI (match_dup 4)
7052 (match_operand:SI 2 "arith_reg_operand" "")))
7054 (if_then_else (ne (reg:SI T_REG)
7056 (label_ref (match_operand 3 "" ""))
7061 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7062 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7063 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7065 (define_insn "casesi_worker_0"
7066 [(set (match_operand:SI 0 "register_operand" "=r,r")
7067 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7068 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7069 (clobber (match_scratch:SI 3 "=X,1"))
7070 (clobber (match_scratch:SI 4 "=&z,z"))]
7075 [(set (match_operand:SI 0 "register_operand" "")
7076 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7077 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7078 (clobber (match_scratch:SI 3 ""))
7079 (clobber (match_scratch:SI 4 ""))]
7080 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7081 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7082 (parallel [(set (match_dup 0)
7083 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7084 (label_ref (match_dup 2))] UNSPEC_CASESI))
7085 (clobber (match_dup 3))])
7086 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7087 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7090 [(set (match_operand:SI 0 "register_operand" "")
7091 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7092 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7093 (clobber (match_scratch:SI 3 ""))
7094 (clobber (match_scratch:SI 4 ""))]
7095 "TARGET_SH2 && reload_completed"
7096 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7097 (parallel [(set (match_dup 0)
7098 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7099 (label_ref (match_dup 2))] UNSPEC_CASESI))
7100 (clobber (match_dup 3))])]
7101 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7103 (define_insn "casesi_worker_1"
7104 [(set (match_operand:SI 0 "register_operand" "=r,r")
7105 (unspec:SI [(reg:SI R0_REG)
7106 (match_operand:SI 1 "register_operand" "0,r")
7107 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7108 (clobber (match_scratch:SI 3 "=X,1"))]
7112 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7114 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7117 switch (GET_MODE (diff_vec))
7120 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7122 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7124 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7125 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7126 return \"mov.b @(r0,%1),%0\";
7131 [(set_attr "length" "4")])
7133 (define_insn "casesi_worker_2"
7134 [(set (match_operand:SI 0 "register_operand" "=r,r")
7135 (unspec:SI [(reg:SI R0_REG)
7136 (match_operand:SI 1 "register_operand" "0,r")
7137 (label_ref (match_operand 2 "" ""))
7138 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7139 (clobber (match_operand:SI 4 "" "=X,1"))]
7140 "TARGET_SH2 && reload_completed && flag_pic"
7143 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7146 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7149 switch (GET_MODE (diff_vec))
7152 output_asm_insn (\"shll2 %1\", operands);
7153 load = \"mov.l @(r0,%1),%0\"; break;
7155 output_asm_insn (\"add %1,%1\", operands);
7156 load = \"mov.w @(r0,%1),%0\"; break;
7158 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7159 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7161 load = \"mov.b @(r0,%1),%0\";
7166 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7169 [(set_attr "length" "8")])
7171 (define_insn "casesi_shift_media"
7172 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7173 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7174 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7179 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7181 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7184 switch (GET_MODE (diff_vec))
7187 return \"shlli %1, 2, %0\";
7189 return \"shlli %1, 1, %0\";
7191 if (rtx_equal_p (operands[0], operands[1]))
7193 return \"add %1, r63, %0\";
7198 [(set_attr "type" "arith_media")])
7200 (define_insn "casesi_load_media"
7201 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7202 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7203 (match_operand 2 "arith_reg_operand" "r")
7204 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7208 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7210 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7213 switch (GET_MODE (diff_vec))
7216 return \"ldx.l %1, %2, %0\";
7219 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7220 return \"ldx.uw %1, %2, %0\";
7222 return \"ldx.w %1, %2, %0\";
7224 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7225 return \"ldx.ub %1, %2, %0\";
7226 return \"ldx.b %1, %2, %0\";
7231 [(set_attr "type" "load_media")])
7233 (define_expand "return"
7235 "reload_completed && ! sh_need_epilogue ()"
7240 emit_jump_insn (gen_return_media ());
7244 if (TARGET_SHCOMPACT
7245 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7247 emit_jump_insn (gen_shcompact_return_tramp ());
7252 (define_insn "*return_i"
7254 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7255 && (current_function_args_info.call_cookie
7256 & CALL_COOKIE_RET_TRAMP (1)))
7257 && reload_completed"
7259 [(set_attr "type" "return")
7260 (set_attr "needs_delay_slot" "yes")])
7262 (define_expand "shcompact_return_tramp"
7265 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7268 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7269 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7272 emit_insn (gen_symGOTPLT2reg (reg, sym));
7274 emit_move_insn (reg, sym);
7276 emit_jump_insn (gen_shcompact_return_tramp_i ());
7280 (define_insn "shcompact_return_tramp_i"
7281 [(parallel [(return) (use (reg:SI R0_REG))])]
7283 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7285 [(set_attr "type" "jump_ind")
7286 (set_attr "needs_delay_slot" "yes")])
7288 (define_insn "return_media_i"
7289 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7290 "TARGET_SHMEDIA && reload_completed"
7292 [(set_attr "type" "jump_media")])
7294 (define_insn "return_media_rte"
7296 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7298 [(set_attr "type" "jump_media")])
7300 (define_expand "return_media"
7302 "TARGET_SHMEDIA && reload_completed"
7305 int tr_regno = sh_media_register_for_return ();
7308 if (current_function_interrupt)
7310 emit_jump_insn (gen_return_media_rte ());
7315 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7317 if (! call_really_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7320 tr = gen_rtx_REG (DImode, tr_regno);
7321 emit_move_insn (tr, r18);
7324 tr = gen_rtx_REG (DImode, tr_regno);
7326 emit_jump_insn (gen_return_media_i (tr));
7330 (define_insn "shcompact_preserve_incoming_args"
7331 [(set (match_operand:SI 0 "register_operand" "+r")
7332 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7335 [(set_attr "length" "0")])
7337 (define_insn "shcompact_incoming_args"
7338 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7339 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7340 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7341 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7342 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7343 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7344 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7345 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7346 (set (mem:BLK (reg:SI MACL_REG))
7347 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7348 (use (reg:SI R0_REG))
7349 (clobber (reg:SI R0_REG))
7350 (clobber (reg:SI MACL_REG))
7351 (clobber (reg:SI MACH_REG))
7352 (clobber (reg:SI PR_REG))]
7355 [(set_attr "needs_delay_slot" "yes")])
7357 (define_insn "shmedia_save_restore_regs_compact"
7358 [(set (reg:SI SP_REG)
7359 (plus:SI (reg:SI SP_REG)
7360 (match_operand:SI 0 "immediate_operand" "i")))
7361 (use (reg:SI R0_REG))
7362 (clobber (reg:SI PR_REG))]
7364 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7365 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7367 [(set_attr "needs_delay_slot" "yes")])
7369 (define_expand "prologue"
7372 "sh_expand_prologue (); DONE;")
7374 (define_expand "epilogue"
7379 sh_expand_epilogue (0);
7380 emit_jump_insn (gen_return ());
7384 (define_expand "eh_return"
7385 [(use (match_operand 0 "register_operand" ""))]
7388 rtx ra = operands[0];
7390 if (TARGET_SHMEDIA64)
7391 emit_insn (gen_eh_set_ra_di (ra));
7393 emit_insn (gen_eh_set_ra_si (ra));
7398 ;; Clobber the return address on the stack. We can't expand this
7399 ;; until we know where it will be put in the stack frame.
7401 (define_insn "eh_set_ra_si"
7402 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7403 (clobber (match_scratch:SI 1 "=&r"))]
7404 "! TARGET_SHMEDIA64"
7407 (define_insn "eh_set_ra_di"
7408 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7409 (clobber (match_scratch:DI 1 "=&r"))]
7414 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7415 (clobber (match_scratch 1 ""))]
7420 sh_set_return_address (operands[0], operands[1]);
7424 (define_insn "blockage"
7425 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7428 [(set_attr "length" "0")])
7430 ;; ------------------------------------------------------------------------
7432 ;; ------------------------------------------------------------------------
7435 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7436 (eq:SI (reg:SI T_REG) (const_int 1)))]
7439 [(set_attr "type" "arith")])
7441 (define_expand "seq"
7442 [(set (match_operand:SI 0 "arith_reg_operand" "")
7449 if (GET_MODE (operands[0]) != DImode)
7450 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7451 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7452 if (sh_compare_op1 != const0_rtx)
7453 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7454 ? GET_MODE (sh_compare_op0)
7455 : GET_MODE (sh_compare_op1),
7458 switch (GET_MODE (sh_compare_op0))
7461 emit_insn (gen_cmpeqdi_media (operands[0],
7462 sh_compare_op0, sh_compare_op1));
7466 if (! TARGET_SHMEDIA_FPU)
7468 emit_insn (gen_cmpeqsf_media (operands[0],
7469 sh_compare_op0, sh_compare_op1));
7473 if (! TARGET_SHMEDIA_FPU)
7475 emit_insn (gen_cmpeqdf_media (operands[0],
7476 sh_compare_op0, sh_compare_op1));
7484 if (sh_expand_t_scc (EQ, operands[0]))
7486 if (! currently_expanding_to_rtl)
7488 operands[1] = prepare_scc_operands (EQ);
7491 (define_expand "slt"
7492 [(set (match_operand:SI 0 "arith_reg_operand" "")
7499 if (GET_MODE (operands[0]) != DImode)
7500 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7501 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7502 if (sh_compare_op1 != const0_rtx)
7503 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7504 ? GET_MODE (sh_compare_op0)
7505 : GET_MODE (sh_compare_op1),
7508 switch (GET_MODE (sh_compare_op0))
7511 emit_insn (gen_cmpgtdi_media (operands[0],
7512 sh_compare_op1, sh_compare_op0));
7516 if (! TARGET_SHMEDIA_FPU)
7518 emit_insn (gen_cmpgtsf_media (operands[0],
7519 sh_compare_op1, sh_compare_op0));
7523 if (! TARGET_SHMEDIA_FPU)
7525 emit_insn (gen_cmpgtdf_media (operands[0],
7526 sh_compare_op1, sh_compare_op0));
7534 if (! currently_expanding_to_rtl)
7536 operands[1] = prepare_scc_operands (LT);
7539 (define_expand "sle"
7540 [(match_operand:SI 0 "arith_reg_operand" "")]
7544 rtx tmp = sh_compare_op0;
7548 if (GET_MODE (operands[0]) != DImode)
7549 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7550 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7551 if (sh_compare_op1 != const0_rtx)
7552 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7553 ? GET_MODE (sh_compare_op0)
7554 : GET_MODE (sh_compare_op1),
7557 switch (GET_MODE (sh_compare_op0))
7561 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7563 emit_insn (gen_cmpgtdi_media (tmp,
7564 sh_compare_op0, sh_compare_op1));
7565 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7570 if (! TARGET_SHMEDIA_FPU)
7572 emit_insn (gen_cmpgesf_media (operands[0],
7573 sh_compare_op1, sh_compare_op0));
7577 if (! TARGET_SHMEDIA_FPU)
7579 emit_insn (gen_cmpgedf_media (operands[0],
7580 sh_compare_op1, sh_compare_op0));
7589 sh_compare_op0 = sh_compare_op1;
7590 sh_compare_op1 = tmp;
7591 emit_insn (gen_sge (operands[0]));
7595 (define_expand "sgt"
7596 [(set (match_operand:SI 0 "arith_reg_operand" "")
7603 if (GET_MODE (operands[0]) != DImode)
7604 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7605 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7606 if (sh_compare_op1 != const0_rtx)
7607 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7608 ? GET_MODE (sh_compare_op0)
7609 : GET_MODE (sh_compare_op1),
7612 switch (GET_MODE (sh_compare_op0))
7615 emit_insn (gen_cmpgtdi_media (operands[0],
7616 sh_compare_op0, sh_compare_op1));
7620 if (! TARGET_SHMEDIA_FPU)
7622 emit_insn (gen_cmpgtsf_media (operands[0],
7623 sh_compare_op0, sh_compare_op1));
7627 if (! TARGET_SHMEDIA_FPU)
7629 emit_insn (gen_cmpgtdf_media (operands[0],
7630 sh_compare_op0, sh_compare_op1));
7638 if (! currently_expanding_to_rtl)
7640 operands[1] = prepare_scc_operands (GT);
7643 (define_expand "sge"
7644 [(set (match_operand:SI 0 "arith_reg_operand" "")
7651 if (GET_MODE (operands[0]) != DImode)
7652 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7653 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7654 if (sh_compare_op1 != const0_rtx)
7655 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7656 ? GET_MODE (sh_compare_op0)
7657 : GET_MODE (sh_compare_op1),
7660 switch (GET_MODE (sh_compare_op0))
7664 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7666 emit_insn (gen_cmpgtdi_media (tmp,
7667 sh_compare_op1, sh_compare_op0));
7668 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7673 if (! TARGET_SHMEDIA_FPU)
7675 emit_insn (gen_cmpgesf_media (operands[0],
7676 sh_compare_op0, sh_compare_op1));
7680 if (! TARGET_SHMEDIA_FPU)
7682 emit_insn (gen_cmpgedf_media (operands[0],
7683 sh_compare_op0, sh_compare_op1));
7692 if (! currently_expanding_to_rtl)
7694 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7698 rtx lab = gen_label_rtx ();
7699 prepare_scc_operands (EQ);
7700 emit_jump_insn (gen_branch_true (lab));
7701 prepare_scc_operands (GT);
7703 emit_insn (gen_movt (operands[0]));
7706 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7709 operands[1] = prepare_scc_operands (GE);
7712 (define_expand "sgtu"
7713 [(set (match_operand:SI 0 "arith_reg_operand" "")
7720 if (GET_MODE (operands[0]) != DImode)
7721 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7722 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7723 if (sh_compare_op1 != const0_rtx)
7724 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7725 ? GET_MODE (sh_compare_op0)
7726 : GET_MODE (sh_compare_op1),
7729 emit_insn (gen_cmpgtudi_media (operands[0],
7730 sh_compare_op0, sh_compare_op1));
7733 if (! currently_expanding_to_rtl)
7735 operands[1] = prepare_scc_operands (GTU);
7738 (define_expand "sltu"
7739 [(set (match_operand:SI 0 "arith_reg_operand" "")
7746 if (GET_MODE (operands[0]) != DImode)
7747 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7748 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7749 if (sh_compare_op1 != const0_rtx)
7750 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7751 ? GET_MODE (sh_compare_op0)
7752 : GET_MODE (sh_compare_op1),
7755 emit_insn (gen_cmpgtudi_media (operands[0],
7756 sh_compare_op1, sh_compare_op0));
7759 if (! currently_expanding_to_rtl)
7761 operands[1] = prepare_scc_operands (LTU);
7764 (define_expand "sleu"
7765 [(set (match_operand:SI 0 "arith_reg_operand" "")
7774 if (GET_MODE (operands[0]) != DImode)
7775 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7776 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7777 if (sh_compare_op1 != const0_rtx)
7778 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7779 ? GET_MODE (sh_compare_op0)
7780 : GET_MODE (sh_compare_op1),
7783 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7785 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7786 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7790 if (! currently_expanding_to_rtl)
7792 operands[1] = prepare_scc_operands (LEU);
7795 (define_expand "sgeu"
7796 [(set (match_operand:SI 0 "arith_reg_operand" "")
7805 if (GET_MODE (operands[0]) != DImode)
7806 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7807 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7808 if (sh_compare_op1 != const0_rtx)
7809 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7810 ? GET_MODE (sh_compare_op0)
7811 : GET_MODE (sh_compare_op1),
7814 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7816 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7817 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7822 if (! currently_expanding_to_rtl)
7824 operands[1] = prepare_scc_operands (GEU);
7827 ;; sne moves the complement of the T reg to DEST like this:
7831 ;; This is better than xoring compare result with 1 because it does
7832 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7835 (define_expand "sne"
7836 [(set (match_dup 2) (const_int -1))
7837 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7838 (neg:SI (plus:SI (match_dup 1)
7841 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7850 if (GET_MODE (operands[0]) != DImode)
7851 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7853 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7856 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7857 if (sh_compare_op1 != const0_rtx)
7858 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7859 ? GET_MODE (sh_compare_op0)
7860 : GET_MODE (sh_compare_op1),
7863 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7865 emit_insn (gen_seq (tmp));
7866 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7871 if (sh_expand_t_scc (NE, operands[0]))
7873 if (! currently_expanding_to_rtl)
7875 operands[1] = prepare_scc_operands (EQ);
7876 operands[2] = gen_reg_rtx (SImode);
7879 (define_expand "sunordered"
7880 [(set (match_operand:DI 0 "arith_reg_operand" "")
7881 (unordered:DI (match_dup 1) (match_dup 2)))]
7882 "TARGET_SHMEDIA_FPU"
7885 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7886 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7889 ;; Use the same trick for FP sle / sge
7890 (define_expand "movnegt"
7891 [(set (match_dup 2) (const_int -1))
7892 (parallel [(set (match_operand 0 "" "")
7893 (neg:SI (plus:SI (match_dup 1)
7896 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7899 "operands[2] = gen_reg_rtx (SImode);")
7901 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7902 ;; This prevents a regression that occurred when we switched from xor to
7906 [(set (match_operand:SI 0 "arith_reg_operand" "")
7907 (plus:SI (reg:SI T_REG)
7910 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7911 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7914 ;; -------------------------------------------------------------------------
7915 ;; Instructions to cope with inline literal tables
7916 ;; -------------------------------------------------------------------------
7918 ; 2 byte integer in line
7920 (define_insn "consttable_2"
7921 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7922 (match_operand 1 "" "")]
7927 if (operands[1] != const0_rtx)
7928 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7931 [(set_attr "length" "2")
7932 (set_attr "in_delay_slot" "no")])
7934 ; 4 byte integer in line
7936 (define_insn "consttable_4"
7937 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7938 (match_operand 1 "" "")]
7943 if (operands[1] != const0_rtx)
7944 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7947 [(set_attr "length" "4")
7948 (set_attr "in_delay_slot" "no")])
7950 ; 8 byte integer in line
7952 (define_insn "consttable_8"
7953 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7954 (match_operand 1 "" "")]
7959 if (operands[1] != const0_rtx)
7960 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7963 [(set_attr "length" "8")
7964 (set_attr "in_delay_slot" "no")])
7966 ; 4 byte floating point
7968 (define_insn "consttable_sf"
7969 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7970 (match_operand 1 "" "")]
7975 if (operands[1] != const0_rtx)
7978 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7979 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7983 [(set_attr "length" "4")
7984 (set_attr "in_delay_slot" "no")])
7986 ; 8 byte floating point
7988 (define_insn "consttable_df"
7989 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7990 (match_operand 1 "" "")]
7995 if (operands[1] != const0_rtx)
7998 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7999 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8003 [(set_attr "length" "8")
8004 (set_attr "in_delay_slot" "no")])
8006 ;; Alignment is needed for some constant tables; it may also be added for
8007 ;; Instructions at the start of loops, or after unconditional branches.
8008 ;; ??? We would get more accurate lengths if we did instruction
8009 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8010 ;; here is too conservative.
8012 ; align to a two byte boundary
8014 (define_expand "align_2"
8015 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8019 ; align to a four byte boundary
8020 ;; align_4 and align_log are instructions for the starts of loops, or
8021 ;; after unconditional branches, which may take up extra room.
8023 (define_expand "align_4"
8024 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8028 ; align to a cache line boundary
8030 (define_insn "align_log"
8031 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8034 [(set_attr "length" "0")
8035 (set_attr "in_delay_slot" "no")])
8037 ; emitted at the end of the literal table, used to emit the
8038 ; 32bit branch labels if needed.
8040 (define_insn "consttable_end"
8041 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8043 "* return output_jump_label_table ();"
8044 [(set_attr "in_delay_slot" "no")])
8046 ; emitted at the end of the window in the literal table.
8048 (define_insn "consttable_window_end"
8049 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8052 [(set_attr "length" "0")
8053 (set_attr "in_delay_slot" "no")])
8055 ;; -------------------------------------------------------------------------
8057 ;; -------------------------------------------------------------------------
8059 ;; String/block move insn.
8061 (define_expand "movmemsi"
8062 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8063 (mem:BLK (match_operand:BLK 1 "" "")))
8064 (use (match_operand:SI 2 "nonmemory_operand" ""))
8065 (use (match_operand:SI 3 "immediate_operand" ""))
8066 (clobber (reg:SI PR_REG))
8067 (clobber (reg:SI R4_REG))
8068 (clobber (reg:SI R5_REG))
8069 (clobber (reg:SI R0_REG))])]
8070 "TARGET_SH1 && ! TARGET_SH5"
8073 if(expand_block_move (operands))
8078 (define_insn "block_move_real"
8079 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8080 (mem:BLK (reg:SI R5_REG)))
8081 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8082 (clobber (reg:SI PR_REG))
8083 (clobber (reg:SI R0_REG))])]
8084 "TARGET_SH1 && ! TARGET_HARD_SH4"
8086 [(set_attr "type" "sfunc")
8087 (set_attr "needs_delay_slot" "yes")])
8089 (define_insn "block_lump_real"
8090 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8091 (mem:BLK (reg:SI R5_REG)))
8092 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8093 (use (reg:SI R6_REG))
8094 (clobber (reg:SI PR_REG))
8095 (clobber (reg:SI T_REG))
8096 (clobber (reg:SI R4_REG))
8097 (clobber (reg:SI R5_REG))
8098 (clobber (reg:SI R6_REG))
8099 (clobber (reg:SI R0_REG))])]
8100 "TARGET_SH1 && ! TARGET_HARD_SH4"
8102 [(set_attr "type" "sfunc")
8103 (set_attr "needs_delay_slot" "yes")])
8105 (define_insn "block_move_real_i4"
8106 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8107 (mem:BLK (reg:SI R5_REG)))
8108 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8109 (clobber (reg:SI PR_REG))
8110 (clobber (reg:SI R0_REG))
8111 (clobber (reg:SI R1_REG))
8112 (clobber (reg:SI R2_REG))])]
8115 [(set_attr "type" "sfunc")
8116 (set_attr "needs_delay_slot" "yes")])
8118 (define_insn "block_lump_real_i4"
8119 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8120 (mem:BLK (reg:SI R5_REG)))
8121 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8122 (use (reg:SI R6_REG))
8123 (clobber (reg:SI PR_REG))
8124 (clobber (reg:SI T_REG))
8125 (clobber (reg:SI R4_REG))
8126 (clobber (reg:SI R5_REG))
8127 (clobber (reg:SI R6_REG))
8128 (clobber (reg:SI R0_REG))
8129 (clobber (reg:SI R1_REG))
8130 (clobber (reg:SI R2_REG))
8131 (clobber (reg:SI R3_REG))])]
8134 [(set_attr "type" "sfunc")
8135 (set_attr "needs_delay_slot" "yes")])
8137 ;; -------------------------------------------------------------------------
8138 ;; Floating point instructions.
8139 ;; -------------------------------------------------------------------------
8141 ;; ??? All patterns should have a type attribute.
8143 (define_expand "fpu_switch0"
8144 [(set (match_operand:SI 0 "" "") (match_dup 2))
8145 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8146 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8149 operands[1] = get_fpscr_rtx ();
8150 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8152 operands[2] = legitimize_pic_address (operands[2], SImode,
8153 no_new_pseudos ? operands[0] : 0);
8156 (define_expand "fpu_switch1"
8157 [(set (match_operand:SI 0 "" "") (match_dup 2))
8158 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8159 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8160 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8163 operands[1] = get_fpscr_rtx ();
8164 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8166 operands[2] = legitimize_pic_address (operands[2], SImode,
8167 no_new_pseudos ? operands[0] : 0);
8168 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8171 (define_expand "movpsi"
8172 [(set (match_operand:PSI 0 "register_operand" "")
8173 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8174 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8177 ;; The c / m alternative is a fake to guide reload to load directly into
8178 ;; fpscr, since reload doesn't know how to use post-increment.
8179 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8180 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8181 ;; predicate after reload.
8182 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8183 ;; like a mac -> gpr move.
8184 (define_insn "fpu_switch"
8185 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8186 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8188 && (! reload_completed
8189 || true_regnum (operands[0]) != FPSCR_REG
8190 || GET_CODE (operands[1]) != MEM
8191 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8193 ! precision stays the same
8202 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8203 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8206 [(set (reg:PSI FPSCR_REG)
8207 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8208 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8209 [(set (match_dup 0) (match_dup 0))]
8212 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8213 gen_rtx_MEM (PSImode,
8214 gen_rtx_POST_INC (Pmode,
8216 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8220 [(set (reg:PSI FPSCR_REG)
8221 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8222 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8223 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8226 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8227 gen_rtx_MEM (PSImode,
8228 gen_rtx_POST_INC (Pmode,
8230 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8233 ;; ??? This uses the fp unit, but has no type indicating that.
8234 ;; If we did that, this would either give a bogus latency or introduce
8235 ;; a bogus FIFO constraint.
8236 ;; Since this insn is currently only used for prologues/epilogues,
8237 ;; it is probably best to claim no function unit, which matches the
8239 (define_insn "toggle_sz"
8240 [(set (reg:PSI FPSCR_REG)
8241 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8242 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8244 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8246 ;; There's no way we can use it today, since optimize mode switching
8247 ;; doesn't enable us to know from which mode we're switching to the
8248 ;; mode it requests, to tell whether we can use a relative mode switch
8249 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8251 (define_insn "toggle_pr"
8252 [(set (reg:PSI FPSCR_REG)
8253 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8254 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8256 [(set_attr "type" "fp")])
8258 (define_expand "addsf3"
8259 [(set (match_operand:SF 0 "arith_reg_operand" "")
8260 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8261 (match_operand:SF 2 "arith_reg_operand" "")))]
8262 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8267 expand_sf_binop (&gen_addsf3_i, operands);
8272 (define_insn "*addsf3_media"
8273 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8274 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8275 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8276 "TARGET_SHMEDIA_FPU"
8278 [(set_attr "type" "fparith_media")])
8280 (define_insn_and_split "unary_sf_op"
8281 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8286 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8287 (match_operator:SF 2 "unary_float_operator"
8288 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8289 (parallel [(match_operand 4
8290 "const_int_operand" "n")]))]))
8291 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8292 "TARGET_SHMEDIA_FPU"
8294 "TARGET_SHMEDIA_FPU && reload_completed"
8295 [(set (match_dup 5) (match_dup 6))]
8298 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8299 rtx op1 = gen_rtx_REG (SFmode,
8300 (true_regnum (operands[1])
8301 + (INTVAL (operands[4]) ^ endian)));
8303 operands[7] = gen_rtx_REG (SFmode,
8304 (true_regnum (operands[0])
8305 + (INTVAL (operands[3]) ^ endian)));
8306 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8308 [(set_attr "type" "fparith_media")])
8310 (define_insn_and_split "binary_sf_op"
8311 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8316 (parallel [(match_operand 7 "const_int_operand" "n")]))
8317 (match_operator:SF 3 "binary_float_operator"
8318 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8319 (parallel [(match_operand 5
8320 "const_int_operand" "n")]))
8321 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8322 (parallel [(match_operand 6
8323 "const_int_operand" "n")]))]))
8324 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8325 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8327 "&& reload_completed"
8328 [(set (match_dup 8) (match_dup 9))]
8331 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8332 rtx op1 = gen_rtx_REG (SFmode,
8333 (true_regnum (operands[1])
8334 + (INTVAL (operands[5]) ^ endian)));
8335 rtx op2 = gen_rtx_REG (SFmode,
8336 (true_regnum (operands[2])
8337 + (INTVAL (operands[6]) ^ endian)));
8339 operands[8] = gen_rtx_REG (SFmode,
8340 (true_regnum (operands[0])
8341 + (INTVAL (operands[4]) ^ endian)));
8342 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8344 [(set_attr "type" "fparith_media")])
8346 (define_insn "addsf3_i"
8347 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8348 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8349 (match_operand:SF 2 "arith_reg_operand" "f")))
8350 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8353 [(set_attr "type" "fp")
8354 (set_attr "fp_mode" "single")])
8356 (define_expand "subsf3"
8357 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8358 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8359 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8360 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8365 expand_sf_binop (&gen_subsf3_i, operands);
8370 (define_insn "*subsf3_media"
8371 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8372 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8373 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8374 "TARGET_SHMEDIA_FPU"
8376 [(set_attr "type" "fparith_media")])
8378 (define_insn "subsf3_i"
8379 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8380 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8381 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8382 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8385 [(set_attr "type" "fp")
8386 (set_attr "fp_mode" "single")])
8388 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8389 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8390 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8391 ;; SH3E, we use a separate insn for SH3E mulsf3.
8393 (define_expand "mulsf3"
8394 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8395 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8396 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8397 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8400 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8401 expand_sf_binop (&gen_mulsf3_i4, operands);
8402 else if (TARGET_SH2E)
8403 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8404 if (! TARGET_SHMEDIA)
8408 (define_insn "*mulsf3_media"
8409 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8410 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8411 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8412 "TARGET_SHMEDIA_FPU"
8414 [(set_attr "type" "fparith_media")])
8416 (define_insn "mulsf3_i4"
8417 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8418 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8419 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8420 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8423 [(set_attr "type" "fp")
8424 (set_attr "fp_mode" "single")])
8426 (define_insn "mulsf3_ie"
8427 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8429 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8430 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8432 [(set_attr "type" "fp")])
8434 (define_insn "*mac_media"
8435 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8436 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8437 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8438 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8439 "TARGET_SHMEDIA_FPU"
8441 [(set_attr "type" "fparith_media")])
8443 (define_insn "*macsf3"
8444 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8445 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8446 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8447 (match_operand:SF 3 "arith_reg_operand" "0")))
8448 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8449 "TARGET_SH2E && ! TARGET_SH4"
8451 [(set_attr "type" "fp")
8452 (set_attr "fp_mode" "single")])
8454 (define_expand "divsf3"
8455 [(set (match_operand:SF 0 "arith_reg_operand" "")
8456 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8457 (match_operand:SF 2 "arith_reg_operand" "")))]
8458 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8463 expand_sf_binop (&gen_divsf3_i, operands);
8468 (define_insn "*divsf3_media"
8469 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8470 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8471 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8472 "TARGET_SHMEDIA_FPU"
8474 [(set_attr "type" "fdiv_media")])
8476 (define_insn "divsf3_i"
8477 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8478 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8479 (match_operand:SF 2 "arith_reg_operand" "f")))
8480 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8483 [(set_attr "type" "fdiv")
8484 (set_attr "fp_mode" "single")])
8486 (define_insn "floatdisf2"
8487 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8488 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8489 "TARGET_SHMEDIA_FPU"
8491 [(set_attr "type" "fpconv_media")])
8493 (define_expand "floatsisf2"
8494 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8495 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8496 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8499 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8501 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8506 (define_insn "*floatsisf2_media"
8507 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8508 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8509 "TARGET_SHMEDIA_FPU"
8511 [(set_attr "type" "fpconv_media")])
8513 (define_insn "floatsisf2_i4"
8514 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8515 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8516 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8517 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8519 [(set_attr "type" "fp")
8520 (set_attr "fp_mode" "single")])
8522 (define_insn "*floatsisf2_ie"
8523 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8524 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8525 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8527 [(set_attr "type" "fp")])
8529 (define_insn "fix_truncsfdi2"
8530 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8531 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8532 "TARGET_SHMEDIA_FPU"
8534 [(set_attr "type" "fpconv_media")])
8536 (define_expand "fix_truncsfsi2"
8537 [(set (match_operand:SI 0 "fpul_operand" "=y")
8538 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8539 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8542 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8544 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8549 (define_insn "*fix_truncsfsi2_media"
8550 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8551 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8552 "TARGET_SHMEDIA_FPU"
8554 [(set_attr "type" "fpconv_media")])
8556 (define_insn "fix_truncsfsi2_i4"
8557 [(set (match_operand:SI 0 "fpul_operand" "=y")
8558 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8559 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8560 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8562 [(set_attr "type" "ftrc_s")
8563 (set_attr "fp_mode" "single")])
8565 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8566 ;; fix_truncsfsi2_i4.
8567 ;; (define_insn "fix_truncsfsi2_i4_2"
8568 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8569 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8570 ;; (use (reg:PSI FPSCR_REG))
8571 ;; (clobber (reg:SI FPUL_REG))]
8574 ;; [(set_attr "length" "4")
8575 ;; (set_attr "fp_mode" "single")])
8578 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8579 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8580 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8581 ;; (clobber (reg:SI FPUL_REG))]
8583 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8584 ;; (use (match_dup 2))])
8585 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8587 (define_insn "*fixsfsi"
8588 [(set (match_operand:SI 0 "fpul_operand" "=y")
8589 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8590 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8592 [(set_attr "type" "fp")])
8594 (define_insn "cmpgtsf_t"
8595 [(set (reg:SI T_REG)
8596 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8597 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8598 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8600 [(set_attr "type" "fp")
8601 (set_attr "fp_mode" "single")])
8603 (define_insn "cmpeqsf_t"
8604 [(set (reg:SI T_REG)
8605 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8606 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8607 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8609 [(set_attr "type" "fp")
8610 (set_attr "fp_mode" "single")])
8612 (define_insn "ieee_ccmpeqsf_t"
8613 [(set (reg:SI T_REG)
8614 (ior:SI (reg:SI T_REG)
8615 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8616 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8617 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8618 "* return output_ieee_ccmpeq (insn, operands);"
8619 [(set_attr "length" "4")])
8622 (define_insn "cmpgtsf_t_i4"
8623 [(set (reg:SI T_REG)
8624 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8625 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8626 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8627 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8629 [(set_attr "type" "fp")
8630 (set_attr "fp_mode" "single")])
8632 (define_insn "cmpeqsf_t_i4"
8633 [(set (reg:SI T_REG)
8634 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8635 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8636 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8637 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8639 [(set_attr "type" "fp")
8640 (set_attr "fp_mode" "single")])
8642 (define_insn "*ieee_ccmpeqsf_t_4"
8643 [(set (reg:SI T_REG)
8644 (ior:SI (reg:SI T_REG)
8645 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8646 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8647 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8648 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8649 "* return output_ieee_ccmpeq (insn, operands);"
8650 [(set_attr "length" "4")
8651 (set_attr "fp_mode" "single")])
8653 (define_insn "cmpeqsf_media"
8654 [(set (match_operand:DI 0 "register_operand" "=r")
8655 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8656 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8657 "TARGET_SHMEDIA_FPU"
8658 "fcmpeq.s %1, %2, %0"
8659 [(set_attr "type" "fcmp_media")])
8661 (define_insn "cmpgtsf_media"
8662 [(set (match_operand:DI 0 "register_operand" "=r")
8663 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8664 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8665 "TARGET_SHMEDIA_FPU"
8666 "fcmpgt.s %1, %2, %0"
8667 [(set_attr "type" "fcmp_media")])
8669 (define_insn "cmpgesf_media"
8670 [(set (match_operand:DI 0 "register_operand" "=r")
8671 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8672 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8673 "TARGET_SHMEDIA_FPU"
8674 "fcmpge.s %1, %2, %0"
8675 [(set_attr "type" "fcmp_media")])
8677 (define_insn "cmpunsf_media"
8678 [(set (match_operand:DI 0 "register_operand" "=r")
8679 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8680 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8681 "TARGET_SHMEDIA_FPU"
8682 "fcmpun.s %1, %2, %0"
8683 [(set_attr "type" "fcmp_media")])
8685 (define_expand "cmpsf"
8686 [(set (reg:SI T_REG)
8687 (compare (match_operand:SF 0 "arith_operand" "")
8688 (match_operand:SF 1 "arith_operand" "")))]
8689 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8692 sh_compare_op0 = operands[0];
8693 sh_compare_op1 = operands[1];
8697 (define_expand "negsf2"
8698 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8699 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8700 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8705 expand_sf_unop (&gen_negsf2_i, operands);
8710 (define_insn "*negsf2_media"
8711 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8712 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8713 "TARGET_SHMEDIA_FPU"
8715 [(set_attr "type" "fmove_media")])
8717 (define_insn "negsf2_i"
8718 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8719 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8720 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8723 [(set_attr "type" "fmove")
8724 (set_attr "fp_mode" "single")])
8726 (define_expand "sqrtsf2"
8727 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8728 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8729 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8734 expand_sf_unop (&gen_sqrtsf2_i, operands);
8739 (define_insn "*sqrtsf2_media"
8740 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8741 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8742 "TARGET_SHMEDIA_FPU"
8744 [(set_attr "type" "fdiv_media")])
8746 (define_insn "sqrtsf2_i"
8747 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8748 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8749 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8752 [(set_attr "type" "fdiv")
8753 (set_attr "fp_mode" "single")])
8755 (define_insn "rsqrtsf2"
8756 [(set (match_operand:SF 0 "register_operand" "=f")
8757 (div:SF (match_operand:SF 1 "immediate_operand" "i")
8758 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8759 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8760 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8761 && operands[1] == CONST1_RTX (SFmode)"
8763 [(set_attr "type" "fsrra")
8764 (set_attr "fp_mode" "single")])
8767 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8769 (unspec:SF [(mult:SF
8770 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8771 (match_operand:SF 2 "immediate_operand" "i"))
8773 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8775 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8776 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8777 && operands[2] == sh_fsca_int2sf ()"
8779 [(set_attr "type" "fsca")
8780 (set_attr "fp_mode" "single")])
8782 (define_expand "sinsf2"
8783 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8784 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8786 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8789 rtx scaled = gen_reg_rtx (SFmode);
8790 rtx truncated = gen_reg_rtx (SImode);
8791 rtx fsca = gen_reg_rtx (V2SFmode);
8792 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8794 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8795 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8796 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8798 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8802 (define_expand "cossf2"
8803 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8804 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8806 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8809 rtx scaled = gen_reg_rtx (SFmode);
8810 rtx truncated = gen_reg_rtx (SImode);
8811 rtx fsca = gen_reg_rtx (V2SFmode);
8812 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8814 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8815 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8816 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8818 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8822 (define_expand "sindf2"
8823 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8824 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8826 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8829 rtx scaled = gen_reg_rtx (DFmode);
8830 rtx truncated = gen_reg_rtx (SImode);
8831 rtx fsca = gen_reg_rtx (V2SFmode);
8832 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8833 rtx sfresult = gen_reg_rtx (SFmode);
8835 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8836 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8837 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8839 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8840 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8844 (define_expand "cosdf2"
8845 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8846 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8848 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8851 rtx scaled = gen_reg_rtx (DFmode);
8852 rtx truncated = gen_reg_rtx (SImode);
8853 rtx fsca = gen_reg_rtx (V2SFmode);
8854 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8855 rtx sfresult = gen_reg_rtx (SFmode);
8857 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8858 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8859 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8861 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8862 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8866 (define_expand "abssf2"
8867 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8868 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8869 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8874 expand_sf_unop (&gen_abssf2_i, operands);
8879 (define_insn "*abssf2_media"
8880 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8881 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8882 "TARGET_SHMEDIA_FPU"
8884 [(set_attr "type" "fmove_media")])
8886 (define_insn "abssf2_i"
8887 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8888 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8889 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8892 [(set_attr "type" "fmove")
8893 (set_attr "fp_mode" "single")])
8895 (define_expand "adddf3"
8896 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8897 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8898 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8899 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8902 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8904 expand_df_binop (&gen_adddf3_i, operands);
8909 (define_insn "*adddf3_media"
8910 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8911 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8912 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8913 "TARGET_SHMEDIA_FPU"
8915 [(set_attr "type" "dfparith_media")])
8917 (define_insn "adddf3_i"
8918 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8919 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8920 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8921 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8922 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8924 [(set_attr "type" "dfp_arith")
8925 (set_attr "fp_mode" "double")])
8927 (define_expand "subdf3"
8928 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8929 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8930 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8931 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8934 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8936 expand_df_binop (&gen_subdf3_i, operands);
8941 (define_insn "*subdf3_media"
8942 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8943 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8944 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8945 "TARGET_SHMEDIA_FPU"
8947 [(set_attr "type" "dfparith_media")])
8949 (define_insn "subdf3_i"
8950 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8951 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8952 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8953 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8954 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8956 [(set_attr "type" "dfp_arith")
8957 (set_attr "fp_mode" "double")])
8959 (define_expand "muldf3"
8960 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8961 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8962 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8963 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8966 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8968 expand_df_binop (&gen_muldf3_i, operands);
8973 (define_insn "*muldf3_media"
8974 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8975 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8976 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8977 "TARGET_SHMEDIA_FPU"
8979 [(set_attr "type" "dfmul_media")])
8981 (define_insn "muldf3_i"
8982 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8983 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8984 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8985 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8986 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8988 [(set_attr "type" "dfp_arith")
8989 (set_attr "fp_mode" "double")])
8991 (define_expand "divdf3"
8992 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8993 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8994 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8995 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8998 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9000 expand_df_binop (&gen_divdf3_i, operands);
9005 (define_insn "*divdf3_media"
9006 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9007 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9008 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9009 "TARGET_SHMEDIA_FPU"
9011 [(set_attr "type" "dfdiv_media")])
9013 (define_insn "divdf3_i"
9014 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9015 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9016 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9017 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9018 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9020 [(set_attr "type" "dfdiv")
9021 (set_attr "fp_mode" "double")])
9023 (define_insn "floatdidf2"
9024 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9025 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9026 "TARGET_SHMEDIA_FPU"
9028 [(set_attr "type" "dfpconv_media")])
9030 (define_expand "floatsidf2"
9031 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9032 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9033 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9036 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9038 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9044 (define_insn "*floatsidf2_media"
9045 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9046 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9047 "TARGET_SHMEDIA_FPU"
9049 [(set_attr "type" "dfpconv_media")])
9051 (define_insn "floatsidf2_i"
9052 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9053 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9054 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9055 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9057 [(set_attr "type" "dfp_conv")
9058 (set_attr "fp_mode" "double")])
9060 (define_insn "fix_truncdfdi2"
9061 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9062 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9063 "TARGET_SHMEDIA_FPU"
9065 [(set_attr "type" "dfpconv_media")])
9067 (define_expand "fix_truncdfsi2"
9068 [(set (match_operand:SI 0 "fpul_operand" "")
9069 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9070 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9073 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9075 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9081 (define_insn "*fix_truncdfsi2_media"
9082 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9083 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9084 "TARGET_SHMEDIA_FPU"
9086 [(set_attr "type" "dfpconv_media")])
9088 (define_insn "fix_truncdfsi2_i"
9089 [(set (match_operand:SI 0 "fpul_operand" "=y")
9090 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9091 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9092 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9094 [(set_attr "type" "dfp_conv")
9095 (set_attr "dfp_comp" "no")
9096 (set_attr "fp_mode" "double")])
9098 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
9099 ;; fix_truncdfsi2_i.
9100 ;; (define_insn "fix_truncdfsi2_i4"
9101 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9102 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9103 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9104 ;; (clobber (reg:SI FPUL_REG))]
9107 ;; [(set_attr "length" "4")
9108 ;; (set_attr "fp_mode" "double")])
9111 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9112 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9113 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9114 ;; (clobber (reg:SI FPUL_REG))]
9116 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9117 ;; (use (match_dup 2))])
9118 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
9120 (define_insn "cmpgtdf_t"
9121 [(set (reg:SI T_REG)
9122 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9123 (match_operand:DF 1 "arith_reg_operand" "f")))
9124 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9125 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9127 [(set_attr "type" "dfp_cmp")
9128 (set_attr "fp_mode" "double")])
9130 (define_insn "cmpeqdf_t"
9131 [(set (reg:SI T_REG)
9132 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9133 (match_operand:DF 1 "arith_reg_operand" "f")))
9134 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9135 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9137 [(set_attr "type" "dfp_cmp")
9138 (set_attr "fp_mode" "double")])
9140 (define_insn "*ieee_ccmpeqdf_t"
9141 [(set (reg:SI T_REG)
9142 (ior:SI (reg:SI T_REG)
9143 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9144 (match_operand:DF 1 "arith_reg_operand" "f"))))
9145 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9146 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9147 "* return output_ieee_ccmpeq (insn, operands);"
9148 [(set_attr "length" "4")
9149 (set_attr "fp_mode" "double")])
9151 (define_insn "cmpeqdf_media"
9152 [(set (match_operand:DI 0 "register_operand" "=r")
9153 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9154 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9155 "TARGET_SHMEDIA_FPU"
9157 [(set_attr "type" "fcmp_media")])
9159 (define_insn "cmpgtdf_media"
9160 [(set (match_operand:DI 0 "register_operand" "=r")
9161 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9162 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9163 "TARGET_SHMEDIA_FPU"
9165 [(set_attr "type" "fcmp_media")])
9167 (define_insn "cmpgedf_media"
9168 [(set (match_operand:DI 0 "register_operand" "=r")
9169 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9170 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9171 "TARGET_SHMEDIA_FPU"
9173 [(set_attr "type" "fcmp_media")])
9175 (define_insn "cmpundf_media"
9176 [(set (match_operand:DI 0 "register_operand" "=r")
9177 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9178 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9179 "TARGET_SHMEDIA_FPU"
9181 [(set_attr "type" "fcmp_media")])
9183 (define_expand "cmpdf"
9184 [(set (reg:SI T_REG)
9185 (compare (match_operand:DF 0 "arith_operand" "")
9186 (match_operand:DF 1 "arith_operand" "")))]
9187 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9190 sh_compare_op0 = operands[0];
9191 sh_compare_op1 = operands[1];
9195 (define_expand "negdf2"
9196 [(set (match_operand:DF 0 "arith_reg_operand" "")
9197 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9198 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9201 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9203 expand_df_unop (&gen_negdf2_i, operands);
9208 (define_insn "*negdf2_media"
9209 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9210 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9211 "TARGET_SHMEDIA_FPU"
9213 [(set_attr "type" "fmove_media")])
9215 (define_insn "negdf2_i"
9216 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9217 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9218 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9219 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9221 [(set_attr "type" "fmove")
9222 (set_attr "fp_mode" "double")])
9224 (define_expand "sqrtdf2"
9225 [(set (match_operand:DF 0 "arith_reg_operand" "")
9226 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9227 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9230 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9232 expand_df_unop (&gen_sqrtdf2_i, operands);
9237 (define_insn "*sqrtdf2_media"
9238 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9239 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9240 "TARGET_SHMEDIA_FPU"
9242 [(set_attr "type" "dfdiv_media")])
9244 (define_insn "sqrtdf2_i"
9245 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9246 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9247 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9248 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9250 [(set_attr "type" "dfdiv")
9251 (set_attr "fp_mode" "double")])
9253 (define_expand "absdf2"
9254 [(set (match_operand:DF 0 "arith_reg_operand" "")
9255 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9256 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9259 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9261 expand_df_unop (&gen_absdf2_i, operands);
9266 (define_insn "*absdf2_media"
9267 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9268 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9269 "TARGET_SHMEDIA_FPU"
9271 [(set_attr "type" "fmove_media")])
9273 (define_insn "absdf2_i"
9274 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9275 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9276 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9277 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9279 [(set_attr "type" "fmove")
9280 (set_attr "fp_mode" "double")])
9282 (define_expand "extendsfdf2"
9283 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9284 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9285 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9288 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9290 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9296 (define_insn "*extendsfdf2_media"
9297 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9298 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9299 "TARGET_SHMEDIA_FPU"
9301 [(set_attr "type" "dfpconv_media")])
9303 (define_insn "extendsfdf2_i4"
9304 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9305 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9306 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9307 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9309 [(set_attr "type" "fp")
9310 (set_attr "fp_mode" "double")])
9312 (define_expand "truncdfsf2"
9313 [(set (match_operand:SF 0 "fpul_operand" "")
9314 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9315 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9318 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9320 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9326 (define_insn "*truncdfsf2_media"
9327 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9328 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9329 "TARGET_SHMEDIA_FPU"
9331 [(set_attr "type" "dfpconv_media")])
9333 (define_insn "truncdfsf2_i4"
9334 [(set (match_operand:SF 0 "fpul_operand" "=y")
9335 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9336 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9337 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9339 [(set_attr "type" "fp")
9340 (set_attr "fp_mode" "double")])
9342 ;; Bit field extract patterns. These give better code for packed bitfields,
9343 ;; because they allow auto-increment addresses to be generated.
9345 (define_expand "insv"
9346 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9347 (match_operand:SI 1 "immediate_operand" "")
9348 (match_operand:SI 2 "immediate_operand" ""))
9349 (match_operand:SI 3 "general_operand" ""))]
9350 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9353 rtx addr_target, orig_address, shift_reg, qi_val;
9354 HOST_WIDE_INT bitsize, size, v = 0;
9355 rtx x = operands[3];
9357 /* ??? expmed doesn't care for non-register predicates. */
9358 if (! memory_operand (operands[0], VOIDmode)
9359 || ! immediate_operand (operands[1], VOIDmode)
9360 || ! immediate_operand (operands[2], VOIDmode)
9361 || ! general_operand (x, VOIDmode))
9363 /* If this isn't a 16 / 24 / 32 bit field, or if
9364 it doesn't start on a byte boundary, then fail. */
9365 bitsize = INTVAL (operands[1]);
9366 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9367 || (INTVAL (operands[2]) % 8) != 0)
9371 orig_address = XEXP (operands[0], 0);
9372 shift_reg = gen_reg_rtx (SImode);
9373 if (GET_CODE (x) == CONST_INT)
9376 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9380 emit_insn (gen_movsi (shift_reg, operands[3]));
9381 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9383 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9385 operands[0] = replace_equiv_address (operands[0], addr_target);
9386 emit_insn (gen_movqi (operands[0], qi_val));
9390 if (GET_CODE (x) == CONST_INT)
9392 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9395 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9396 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9398 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9399 emit_insn (gen_movqi (operands[0], qi_val));
9405 (define_insn "movua"
9406 [(set (match_operand:SI 0 "register_operand" "=z")
9407 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9408 (const_int 32) (const_int 0)))]
9411 [(set_attr "type" "movua")])
9413 ;; We shouldn't need this, but cse replaces increments with references
9414 ;; to other regs before flow has a chance to create post_inc
9415 ;; addressing modes, and only postreload's cse_move2add brings the
9416 ;; increments back to a usable form.
9418 [(set (match_operand:SI 0 "register_operand" "")
9419 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9420 (const_int 32) (const_int 0)))
9421 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9422 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9423 [(set (match_operand:SI 0 "register_operand" "")
9424 (sign_extract:SI (mem:SI (post_inc:SI
9425 (match_operand:SI 1 "register_operand" "")))
9426 (const_int 32) (const_int 0)))]
9429 (define_expand "extv"
9430 [(set (match_operand:SI 0 "register_operand" "")
9431 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9432 (match_operand 2 "const_int_operand" "")
9433 (match_operand 3 "const_int_operand" "")))]
9436 if (TARGET_SH4A_ARCH
9437 && INTVAL (operands[2]) == 32
9438 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9439 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9441 emit_insn (gen_movua (operands[0],
9442 adjust_address (operands[1], SImode, 0)));
9449 (define_expand "extzv"
9450 [(set (match_operand:SI 0 "register_operand" "")
9451 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9452 (match_operand 2 "const_int_operand" "")
9453 (match_operand 3 "const_int_operand" "")))]
9456 if (TARGET_SH4A_ARCH
9457 && INTVAL (operands[2]) == 32
9458 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9459 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9461 emit_insn (gen_movua (operands[0],
9462 adjust_address (operands[1], SImode, 0)));
9470 ;; -------------------------------------------------------------------------
9472 ;; -------------------------------------------------------------------------
9474 ;; This matches cases where a stack pointer increment at the start of the
9475 ;; epilogue combines with a stack slot read loading the return value.
9478 [(set (match_operand:SI 0 "arith_reg_operand" "")
9479 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9480 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9481 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9484 ;; See the comment on the dt combiner pattern above.
9487 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9488 (plus:SI (match_dup 0)
9491 (eq:SI (match_dup 0)
9496 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9497 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9498 ;; reload when the constant is too large for a reg+offset address.
9500 ;; ??? We would get much better code if this was done in reload. This would
9501 ;; require modifying find_reloads_address to recognize that if the constant
9502 ;; is out-of-range for an immediate add, then we get better code by reloading
9503 ;; the constant into a register than by reloading the sum into a register,
9504 ;; since the former is one instruction shorter if the address does not need
9505 ;; to be offsettable. Unfortunately this does not work, because there is
9506 ;; only one register, r0, that can be used as an index register. This register
9507 ;; is also the function return value register. So, if we try to force reload
9508 ;; to use double-reg addresses, then we end up with some instructions that
9509 ;; need to use r0 twice. The only way to fix this is to change the calling
9510 ;; convention so that r0 is not used to return values.
9513 [(set (match_operand:SI 0 "register_operand" "=r")
9514 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9515 (set (mem:SI (match_dup 0))
9516 (match_operand:SI 2 "general_movsrc_operand" ""))]
9517 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9518 "mov.l %2,@(%0,%1)")
9521 [(set (match_operand:SI 0 "register_operand" "=r")
9522 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9523 (set (match_operand:SI 2 "general_movdst_operand" "")
9524 (mem:SI (match_dup 0)))]
9525 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9526 "mov.l @(%0,%1),%2")
9529 [(set (match_operand:SI 0 "register_operand" "=r")
9530 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9531 (set (mem:HI (match_dup 0))
9532 (match_operand:HI 2 "general_movsrc_operand" ""))]
9533 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9534 "mov.w %2,@(%0,%1)")
9537 [(set (match_operand:SI 0 "register_operand" "=r")
9538 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9539 (set (match_operand:HI 2 "general_movdst_operand" "")
9540 (mem:HI (match_dup 0)))]
9541 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9542 "mov.w @(%0,%1),%2")
9545 [(set (match_operand:SI 0 "register_operand" "=r")
9546 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9547 (set (mem:QI (match_dup 0))
9548 (match_operand:QI 2 "general_movsrc_operand" ""))]
9549 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9550 "mov.b %2,@(%0,%1)")
9553 [(set (match_operand:SI 0 "register_operand" "=r")
9554 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9555 (set (match_operand:QI 2 "general_movdst_operand" "")
9556 (mem:QI (match_dup 0)))]
9557 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9558 "mov.b @(%0,%1),%2")
9561 [(set (match_operand:SI 0 "register_operand" "=r")
9562 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9563 (set (mem:SF (match_dup 0))
9564 (match_operand:SF 2 "general_movsrc_operand" ""))]
9565 "TARGET_SH1 && REGNO (operands[0]) == 0
9566 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9567 || (GET_CODE (operands[2]) == SUBREG
9568 && REGNO (SUBREG_REG (operands[2])) < 16))
9569 && reg_unused_after (operands[0], insn)"
9570 "mov.l %2,@(%0,%1)")
9573 [(set (match_operand:SI 0 "register_operand" "=r")
9574 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9575 (set (match_operand:SF 2 "general_movdst_operand" "")
9577 (mem:SF (match_dup 0)))]
9578 "TARGET_SH1 && REGNO (operands[0]) == 0
9579 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9580 || (GET_CODE (operands[2]) == SUBREG
9581 && REGNO (SUBREG_REG (operands[2])) < 16))
9582 && reg_unused_after (operands[0], insn)"
9583 "mov.l @(%0,%1),%2")
9586 [(set (match_operand:SI 0 "register_operand" "=r")
9587 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9588 (set (mem:SF (match_dup 0))
9589 (match_operand:SF 2 "general_movsrc_operand" ""))]
9590 "TARGET_SH2E && REGNO (operands[0]) == 0
9591 && ((GET_CODE (operands[2]) == REG
9592 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9593 || (GET_CODE (operands[2]) == SUBREG
9594 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9595 && reg_unused_after (operands[0], insn)"
9596 "fmov{.s|} %2,@(%0,%1)")
9599 [(set (match_operand:SI 0 "register_operand" "=r")
9600 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9601 (set (match_operand:SF 2 "general_movdst_operand" "")
9603 (mem:SF (match_dup 0)))]
9604 "TARGET_SH2E && REGNO (operands[0]) == 0
9605 && ((GET_CODE (operands[2]) == REG
9606 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9607 || (GET_CODE (operands[2]) == SUBREG
9608 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9609 && reg_unused_after (operands[0], insn)"
9610 "fmov{.s|} @(%0,%1),%2")
9612 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9613 (define_insn "sp_switch_1"
9620 xoperands[0] = sp_switch;
9621 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9622 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9623 return \"mov r0,r15\";
9625 [(set_attr "length" "10")])
9627 ;; Switch back to the original stack for interrupt functions with the
9628 ;; sp_switch attribute. */
9629 (define_insn "sp_switch_2"
9632 "mov.l @r15+,r15\;mov.l @r15+,r0"
9633 [(set_attr "length" "4")])
9635 ;; Integer vector moves
9637 (define_expand "movv8qi"
9638 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9639 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9641 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9643 (define_insn "movv8qi_i"
9644 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9645 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9647 && (register_operand (operands[0], V8QImode)
9648 || sh_register_operand (operands[1], V8QImode))"
9655 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9656 (set_attr "length" "4,4,16,4,4")])
9659 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9660 (subreg:V8QI (const_int 0) 0))]
9663 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9664 (const_int 0) (const_int 0) (const_int 0)
9665 (const_int 0) (const_int 0)]))])
9668 [(set (match_operand 0 "arith_reg_dest" "")
9669 (match_operand 1 "sh_rep_vec" ""))]
9670 "TARGET_SHMEDIA && reload_completed
9671 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9672 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9673 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9674 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9675 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9676 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9677 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9678 [(set (match_dup 0) (match_dup 1))
9682 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9683 rtx elt1 = XVECEXP (operands[1], 0, 1);
9686 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9690 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9691 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9693 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9694 operands[1] = XVECEXP (operands[1], 0, 0);
9697 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9699 = GEN_INT (TARGET_LITTLE_ENDIAN
9700 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9701 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9704 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9706 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9712 [(set (match_operand 0 "arith_reg_dest" "")
9713 (match_operand 1 "sh_const_vec" ""))]
9714 "TARGET_SHMEDIA && reload_completed
9715 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9716 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9717 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9718 [(set (match_dup 0) (match_dup 1))]
9721 rtx v = operands[1];
9722 enum machine_mode new_mode
9723 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9725 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9727 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9730 (define_expand "movv2hi"
9731 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9732 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9734 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9736 (define_insn "movv2hi_i"
9737 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9738 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9740 && (register_operand (operands[0], V2HImode)
9741 || sh_register_operand (operands[1], V2HImode))"
9748 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9749 (set_attr "length" "4,4,16,4,4")])
9751 (define_expand "movv4hi"
9752 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9753 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9755 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9757 (define_insn "movv4hi_i"
9758 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9759 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9761 && (register_operand (operands[0], V4HImode)
9762 || sh_register_operand (operands[1], V4HImode))"
9769 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9770 (set_attr "length" "4,4,16,4,4")])
9772 (define_expand "movv2si"
9773 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9774 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9776 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9778 (define_insn "movv2si_i"
9779 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9780 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9782 && (register_operand (operands[0], V2SImode)
9783 || sh_register_operand (operands[1], V2SImode))"
9790 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9791 (set_attr "length" "4,4,16,4,4")])
9793 ;; Multimedia Intrinsics
9795 (define_insn "absv2si2"
9796 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9797 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9800 [(set_attr "type" "mcmp_media")])
9802 (define_insn "absv4hi2"
9803 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9804 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9807 [(set_attr "type" "mcmp_media")])
9809 (define_insn "addv2si3"
9810 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9811 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9812 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9815 [(set_attr "type" "arith_media")])
9817 (define_insn "addv4hi3"
9818 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9819 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9820 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9823 [(set_attr "type" "arith_media")])
9825 (define_insn "ssaddv2si3"
9826 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9827 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9828 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9830 "madds.l %1, %2, %0"
9831 [(set_attr "type" "mcmp_media")])
9833 (define_insn "usaddv8qi3"
9834 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9835 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9836 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9838 "madds.ub %1, %2, %0"
9839 [(set_attr "type" "mcmp_media")])
9841 (define_insn "ssaddv4hi3"
9842 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9843 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9844 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9846 "madds.w %1, %2, %0"
9847 [(set_attr "type" "mcmp_media")])
9849 (define_insn "negcmpeqv8qi"
9850 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9851 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9852 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9854 "mcmpeq.b %N1, %N2, %0"
9855 [(set_attr "type" "mcmp_media")])
9857 (define_insn "negcmpeqv2si"
9858 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9859 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9860 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9862 "mcmpeq.l %N1, %N2, %0"
9863 [(set_attr "type" "mcmp_media")])
9865 (define_insn "negcmpeqv4hi"
9866 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9867 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9868 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9870 "mcmpeq.w %N1, %N2, %0"
9871 [(set_attr "type" "mcmp_media")])
9873 (define_insn "negcmpgtuv8qi"
9874 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9875 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9876 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9878 "mcmpgt.ub %N1, %N2, %0"
9879 [(set_attr "type" "mcmp_media")])
9881 (define_insn "negcmpgtv2si"
9882 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9883 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9884 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9886 "mcmpgt.l %N1, %N2, %0"
9887 [(set_attr "type" "mcmp_media")])
9889 (define_insn "negcmpgtv4hi"
9890 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9891 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9892 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9894 "mcmpgt.w %N1, %N2, %0"
9895 [(set_attr "type" "mcmp_media")])
9898 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9899 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9900 (match_operand:DI 2 "arith_reg_operand" "r"))
9901 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9902 (not:DI (match_dup 2)))))]
9905 [(set_attr "type" "arith_media")])
9907 (define_insn "mcnvs_lw"
9908 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9910 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9911 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9913 "mcnvs.lw %N1, %N2, %0"
9914 [(set_attr "type" "mcmp_media")])
9916 (define_insn "mcnvs_wb"
9917 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9919 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9920 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9922 "mcnvs.wb %N1, %N2, %0"
9923 [(set_attr "type" "mcmp_media")])
9925 (define_insn "mcnvs_wub"
9926 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9928 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9929 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9931 "mcnvs.wub %N1, %N2, %0"
9932 [(set_attr "type" "mcmp_media")])
9934 (define_insn "mextr_rl"
9935 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9936 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9937 (match_operand:HI 3 "mextr_bit_offset" "i"))
9938 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9939 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9940 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9943 static char templ[16];
9945 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9946 (int) INTVAL (operands[3]) >> 3);
9949 [(set_attr "type" "arith_media")])
9951 (define_insn "*mextr_lr"
9952 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9953 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9954 (match_operand:HI 3 "mextr_bit_offset" "i"))
9955 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9956 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9957 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9960 static char templ[16];
9962 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9963 (int) INTVAL (operands[4]) >> 3);
9966 [(set_attr "type" "arith_media")])
9968 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9969 ; vector then varies depending on endianness.
9970 (define_expand "mextr1"
9971 [(match_operand:DI 0 "arith_reg_dest" "")
9972 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9973 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9977 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9978 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9982 (define_expand "mextr2"
9983 [(match_operand:DI 0 "arith_reg_dest" "")
9984 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9985 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9989 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9990 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9994 (define_expand "mextr3"
9995 [(match_operand:DI 0 "arith_reg_dest" "")
9996 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9997 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10001 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10002 GEN_INT (3 * 8), GEN_INT (5 * 8)));
10006 (define_expand "mextr4"
10007 [(match_operand:DI 0 "arith_reg_dest" "")
10008 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10009 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10013 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10014 GEN_INT (4 * 8), GEN_INT (4 * 8)));
10018 (define_expand "mextr5"
10019 [(match_operand:DI 0 "arith_reg_dest" "")
10020 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10021 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10025 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10026 GEN_INT (5 * 8), GEN_INT (3 * 8)));
10030 (define_expand "mextr6"
10031 [(match_operand:DI 0 "arith_reg_dest" "")
10032 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10033 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10037 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10038 GEN_INT (6 * 8), GEN_INT (2 * 8)));
10042 (define_expand "mextr7"
10043 [(match_operand:DI 0 "arith_reg_dest" "")
10044 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10045 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10049 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10050 GEN_INT (7 * 8), GEN_INT (1 * 8)));
10054 (define_expand "mmacfx_wl"
10055 [(match_operand:V2SI 0 "arith_reg_dest" "")
10056 (match_operand:V2HI 1 "extend_reg_operand" "")
10057 (match_operand:V2HI 2 "extend_reg_operand" "")
10058 (match_operand:V2SI 3 "arith_reg_operand" "")]
10062 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10063 operands[1], operands[2]));
10067 (define_insn "mmacfx_wl_i"
10068 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10070 (match_operand:V2SI 1 "arith_reg_operand" "0")
10075 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10076 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10079 "mmacfx.wl %2, %3, %0"
10080 [(set_attr "type" "mac_media")])
10082 (define_expand "mmacnfx_wl"
10083 [(match_operand:V2SI 0 "arith_reg_dest" "")
10084 (match_operand:V2HI 1 "extend_reg_operand" "")
10085 (match_operand:V2HI 2 "extend_reg_operand" "")
10086 (match_operand:V2SI 3 "arith_reg_operand" "")]
10090 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10091 operands[1], operands[2]));
10095 (define_insn "mmacnfx_wl_i"
10096 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10098 (match_operand:V2SI 1 "arith_reg_operand" "0")
10103 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10104 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10107 "mmacnfx.wl %2, %3, %0"
10108 [(set_attr "type" "mac_media")])
10110 (define_insn "mulv2si3"
10111 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10112 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10113 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10115 "mmul.l %1, %2, %0"
10116 [(set_attr "type" "d2mpy_media")])
10118 (define_insn "mulv4hi3"
10119 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10120 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10121 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10123 "mmul.w %1, %2, %0"
10124 [(set_attr "type" "dmpy_media")])
10126 (define_insn "mmulfx_l"
10127 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10131 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10132 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10135 "mmulfx.l %1, %2, %0"
10136 [(set_attr "type" "d2mpy_media")])
10138 (define_insn "mmulfx_w"
10139 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10143 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10144 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10147 "mmulfx.w %1, %2, %0"
10148 [(set_attr "type" "dmpy_media")])
10150 (define_insn "mmulfxrp_w"
10151 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10156 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10157 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10161 "mmulfxrp.w %1, %2, %0"
10162 [(set_attr "type" "dmpy_media")])
10164 (define_expand "mmulhi_wl"
10165 [(match_operand:V2SI 0 "arith_reg_dest" "")
10166 (match_operand:V4HI 1 "arith_reg_operand" "")
10167 (match_operand:V4HI 2 "arith_reg_operand" "")]
10171 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10172 (operands[0], operands[1], operands[2]));
10176 (define_expand "mmullo_wl"
10177 [(match_operand:V2SI 0 "arith_reg_dest" "")
10178 (match_operand:V4HI 1 "arith_reg_operand" "")
10179 (match_operand:V4HI 2 "arith_reg_operand" "")]
10183 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10184 (operands[0], operands[1], operands[2]));
10188 (define_insn "mmul23_wl"
10189 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10192 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10193 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10194 (parallel [(const_int 2) (const_int 3)])))]
10196 "* return (TARGET_LITTLE_ENDIAN
10197 ? \"mmulhi.wl %1, %2, %0\"
10198 : \"mmullo.wl %1, %2, %0\");"
10199 [(set_attr "type" "dmpy_media")])
10201 (define_insn "mmul01_wl"
10202 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10205 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10206 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10207 (parallel [(const_int 0) (const_int 1)])))]
10209 "* return (TARGET_LITTLE_ENDIAN
10210 ? \"mmullo.wl %1, %2, %0\"
10211 : \"mmulhi.wl %1, %2, %0\");"
10212 [(set_attr "type" "dmpy_media")])
10214 (define_expand "mmulsum_wq"
10215 [(match_operand:DI 0 "arith_reg_dest" "")
10216 (match_operand:V4HI 1 "arith_reg_operand" "")
10217 (match_operand:V4HI 2 "arith_reg_operand" "")
10218 (match_operand:DI 3 "arith_reg_operand" "")]
10222 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10223 operands[1], operands[2]));
10227 (define_insn "mmulsum_wq_i"
10228 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10229 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10234 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10235 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10236 (parallel [(const_int 0)]))
10237 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10238 (sign_extend:V4DI (match_dup 3)))
10239 (parallel [(const_int 1)])))
10241 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10242 (sign_extend:V4DI (match_dup 3)))
10243 (parallel [(const_int 2)]))
10244 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10245 (sign_extend:V4DI (match_dup 3)))
10246 (parallel [(const_int 3)]))))))]
10248 "mmulsum.wq %2, %3, %0"
10249 [(set_attr "type" "mac_media")])
10251 (define_expand "mperm_w"
10252 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10253 (match_operand:V4HI 1 "arith_reg_operand" "r")
10254 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10258 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10259 (operands[0], operands[1], operands[2]));
10263 ; This use of vec_select isn't exactly correct according to rtl.texi
10264 ; (because not constant), but it seems a straightforward extension.
10265 (define_insn "mperm_w_little"
10266 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10268 (match_operand:V4HI 1 "arith_reg_operand" "r")
10270 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10271 (const_int 2) (const_int 0))
10272 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10273 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10274 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10275 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10276 "mperm.w %1, %N2, %0"
10277 [(set_attr "type" "arith_media")])
10279 (define_insn "mperm_w_big"
10280 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10282 (match_operand:V4HI 1 "arith_reg_operand" "r")
10284 [(zero_extract:QI (not:QI (match_operand:QI 2
10285 "extend_reg_or_0_operand" "rZ"))
10286 (const_int 2) (const_int 0))
10287 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10288 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10289 (zero_extract:QI (not:QI (match_dup 2))
10290 (const_int 2) (const_int 6))])))]
10291 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10292 "mperm.w %1, %N2, %0"
10293 [(set_attr "type" "arith_media")])
10295 (define_insn "mperm_w0"
10296 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10297 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10298 "trunc_hi_operand" "r"))))]
10300 "mperm.w %1, r63, %0"
10301 [(set_attr "type" "arith_media")])
10303 (define_expand "msad_ubq"
10304 [(match_operand:DI 0 "arith_reg_dest" "")
10305 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10306 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10307 (match_operand:DI 3 "arith_reg_operand" "")]
10311 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10312 operands[1], operands[2]));
10316 (define_insn "msad_ubq_i"
10317 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10322 (match_operand:DI 1 "arith_reg_operand" "0")
10323 (abs:DI (vec_select:DI
10326 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10328 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10329 (parallel [(const_int 0)]))))
10330 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10331 (zero_extend:V8DI (match_dup 3)))
10332 (parallel [(const_int 1)]))))
10334 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10335 (zero_extend:V8DI (match_dup 3)))
10336 (parallel [(const_int 2)])))
10337 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10338 (zero_extend:V8DI (match_dup 3)))
10339 (parallel [(const_int 3)])))))
10342 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10343 (zero_extend:V8DI (match_dup 3)))
10344 (parallel [(const_int 4)])))
10345 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10346 (zero_extend:V8DI (match_dup 3)))
10347 (parallel [(const_int 5)]))))
10349 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10350 (zero_extend:V8DI (match_dup 3)))
10351 (parallel [(const_int 6)])))
10352 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10353 (zero_extend:V8DI (match_dup 3)))
10354 (parallel [(const_int 7)])))))))]
10356 "msad.ubq %N2, %N3, %0"
10357 [(set_attr "type" "mac_media")])
10359 (define_insn "mshalds_l"
10360 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10363 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10364 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10365 (const_int 31)))))]
10367 "mshalds.l %1, %2, %0"
10368 [(set_attr "type" "mcmp_media")])
10370 (define_insn "mshalds_w"
10371 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10374 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10375 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10376 (const_int 15)))))]
10378 "mshalds.w %1, %2, %0"
10379 [(set_attr "type" "mcmp_media")])
10381 (define_insn "ashrv2si3"
10382 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10383 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10384 (match_operand:DI 2 "arith_reg_operand" "r")))]
10386 "mshard.l %1, %2, %0"
10387 [(set_attr "type" "arith_media")])
10389 (define_insn "ashrv4hi3"
10390 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10391 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10392 (match_operand:DI 2 "arith_reg_operand" "r")))]
10394 "mshard.w %1, %2, %0"
10395 [(set_attr "type" "arith_media")])
10397 (define_insn "mshards_q"
10398 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10400 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10401 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10403 "mshards.q %1, %N2, %0"
10404 [(set_attr "type" "mcmp_media")])
10406 (define_expand "mshfhi_b"
10407 [(match_operand:V8QI 0 "arith_reg_dest" "")
10408 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10409 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10413 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10414 (operands[0], operands[1], operands[2]));
10418 (define_expand "mshflo_b"
10419 [(match_operand:V8QI 0 "arith_reg_dest" "")
10420 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10421 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10425 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10426 (operands[0], operands[1], operands[2]));
10430 (define_insn "mshf4_b"
10432 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10434 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10435 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10436 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10437 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10439 "* return (TARGET_LITTLE_ENDIAN
10440 ? \"mshfhi.b %N1, %N2, %0\"
10441 : \"mshflo.b %N1, %N2, %0\");"
10442 [(set_attr "type" "arith_media")])
10444 (define_insn "mshf0_b"
10446 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10448 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10449 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10450 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10451 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10453 "* return (TARGET_LITTLE_ENDIAN
10454 ? \"mshflo.b %N1, %N2, %0\"
10455 : \"mshfhi.b %N1, %N2, %0\");"
10456 [(set_attr "type" "arith_media")])
10458 (define_expand "mshfhi_l"
10459 [(match_operand:V2SI 0 "arith_reg_dest" "")
10460 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10461 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10465 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10466 (operands[0], operands[1], operands[2]));
10470 (define_expand "mshflo_l"
10471 [(match_operand:V2SI 0 "arith_reg_dest" "")
10472 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10473 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10477 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10478 (operands[0], operands[1], operands[2]));
10482 (define_insn "mshf4_l"
10483 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10485 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10486 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10487 (parallel [(const_int 1) (const_int 3)])))]
10489 "* return (TARGET_LITTLE_ENDIAN
10490 ? \"mshfhi.l %N1, %N2, %0\"
10491 : \"mshflo.l %N1, %N2, %0\");"
10492 [(set_attr "type" "arith_media")])
10494 (define_insn "mshf0_l"
10495 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10497 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10498 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10499 (parallel [(const_int 0) (const_int 2)])))]
10501 "* return (TARGET_LITTLE_ENDIAN
10502 ? \"mshflo.l %N1, %N2, %0\"
10503 : \"mshfhi.l %N1, %N2, %0\");"
10504 [(set_attr "type" "arith_media")])
10506 (define_expand "mshfhi_w"
10507 [(match_operand:V4HI 0 "arith_reg_dest" "")
10508 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10509 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10513 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10514 (operands[0], operands[1], operands[2]));
10518 (define_expand "mshflo_w"
10519 [(match_operand:V4HI 0 "arith_reg_dest" "")
10520 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10521 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10525 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10526 (operands[0], operands[1], operands[2]));
10530 (define_insn "mshf4_w"
10531 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10533 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10534 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10535 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10537 "* return (TARGET_LITTLE_ENDIAN
10538 ? \"mshfhi.w %N1, %N2, %0\"
10539 : \"mshflo.w %N1, %N2, %0\");"
10540 [(set_attr "type" "arith_media")])
10542 (define_insn "mshf0_w"
10543 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10545 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10546 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10547 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10549 "* return (TARGET_LITTLE_ENDIAN
10550 ? \"mshflo.w %N1, %N2, %0\"
10551 : \"mshfhi.w %N1, %N2, %0\");"
10552 [(set_attr "type" "arith_media")])
10554 (define_insn "mshflo_w_x"
10555 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10557 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10558 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10559 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10561 "mshflo.w %N1, %N2, %0"
10562 [(set_attr "type" "arith_media")])
10564 /* These are useful to expand ANDs and as combiner patterns. */
10565 (define_insn_and_split "mshfhi_l_di"
10566 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10567 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10569 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10570 (const_int -4294967296))))]
10573 mshfhi.l %N1, %N2, %0
10575 "TARGET_SHMEDIA && reload_completed
10576 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10577 [(set (match_dup 3) (match_dup 4))
10578 (set (match_dup 5) (match_dup 6))]
10581 operands[3] = gen_lowpart (SImode, operands[0]);
10582 operands[4] = gen_highpart (SImode, operands[1]);
10583 operands[5] = gen_highpart (SImode, operands[0]);
10584 operands[6] = gen_highpart (SImode, operands[2]);
10586 [(set_attr "type" "arith_media")])
10588 (define_insn "*mshfhi_l_di_rev"
10589 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10590 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10591 (const_int -4294967296))
10592 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10595 "mshfhi.l %N2, %N1, %0"
10596 [(set_attr "type" "arith_media")])
10599 [(set (match_operand:DI 0 "arith_reg_dest" "")
10600 (ior:DI (zero_extend:DI (match_operand:SI 1
10601 "extend_reg_or_0_operand" ""))
10602 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10603 (const_int -4294967296))))
10604 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10609 emit_insn (gen_ashldi3_media (operands[3],
10610 simplify_gen_subreg (DImode, operands[1],
10613 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10617 (define_insn "mshflo_l_di"
10618 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10619 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10620 (const_int 4294967295))
10621 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10625 "mshflo.l %N1, %N2, %0"
10626 [(set_attr "type" "arith_media")])
10628 (define_insn "*mshflo_l_di_rev"
10629 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10630 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10632 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10633 (const_int 4294967295))))]
10636 "mshflo.l %N2, %N1, %0"
10637 [(set_attr "type" "arith_media")])
10639 ;; Combiner pattern for trampoline initialization.
10640 (define_insn_and_split "*double_shori"
10641 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10642 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10644 (match_operand:DI 2 "const_int_operand" "n")))]
10646 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10648 "rtx_equal_p (operands[0], operands[1])"
10652 HOST_WIDE_INT v = INTVAL (operands[2]);
10654 emit_insn (gen_shori_media (operands[0], operands[0],
10655 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10656 emit_insn (gen_shori_media (operands[0], operands[0],
10657 gen_int_mode (v, HImode)));
10662 (define_insn "*mshflo_l_di_x"
10663 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10664 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10666 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10670 "mshflo.l %N1, %N2, %0"
10671 [(set_attr "type" "arith_media")])
10673 (define_insn_and_split "concat_v2sf"
10674 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10675 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10676 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10677 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10681 mshflo.l %N1, %N2, %0
10684 "TARGET_SHMEDIA && reload_completed
10685 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10686 [(set (match_dup 3) (match_dup 1))
10687 (set (match_dup 4) (match_dup 2))]
10690 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10691 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10693 [(set_attr "type" "arith_media")])
10695 (define_insn "*mshflo_l_di_x_rev"
10696 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10697 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10699 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10702 "mshflo.l %N2, %N1, %0"
10703 [(set_attr "type" "arith_media")])
10705 (define_insn "ashlv2si3"
10706 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10707 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10708 (match_operand:DI 2 "arith_reg_operand" "r")))]
10710 "mshlld.l %1, %2, %0"
10711 [(set_attr "type" "arith_media")])
10713 (define_insn "ashlv4hi3"
10714 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10715 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10716 (match_operand:DI 2 "arith_reg_operand" "r")))]
10718 "mshlld.w %1, %2, %0"
10719 [(set_attr "type" "arith_media")])
10721 (define_insn "lshrv2si3"
10722 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10723 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10724 (match_operand:DI 2 "arith_reg_operand" "r")))]
10726 "mshlrd.l %1, %2, %0"
10727 [(set_attr "type" "arith_media")])
10729 (define_insn "lshrv4hi3"
10730 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10731 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10732 (match_operand:DI 2 "arith_reg_operand" "r")))]
10734 "mshlrd.w %1, %2, %0"
10735 [(set_attr "type" "arith_media")])
10737 (define_insn "subv2si3"
10738 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10739 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10740 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10742 "msub.l %N1, %2, %0"
10743 [(set_attr "type" "arith_media")])
10745 (define_insn "subv4hi3"
10746 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10747 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10748 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10750 "msub.w %N1, %2, %0"
10751 [(set_attr "type" "arith_media")])
10753 (define_insn "sssubv2si3"
10754 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10755 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10756 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10758 "msubs.l %N1, %2, %0"
10759 [(set_attr "type" "mcmp_media")])
10761 (define_insn "ussubv8qi3"
10762 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10763 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10764 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10766 "msubs.ub %1, %2, %0"
10767 [(set_attr "type" "mcmp_media")])
10769 (define_insn "sssubv4hi3"
10770 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10771 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10772 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10774 "msubs.w %N1, %2, %0"
10775 [(set_attr "type" "mcmp_media")])
10777 ;; Floating Point Intrinsics
10779 (define_insn "fcosa_s"
10780 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10781 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10785 [(set_attr "type" "atrans_media")])
10787 (define_insn "fsina_s"
10788 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10789 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10793 [(set_attr "type" "atrans_media")])
10795 (define_insn "fipr"
10796 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10797 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10798 "fp_arith_reg_operand" "f")
10799 (match_operand:V4SF 2
10800 "fp_arith_reg_operand" "f"))
10801 (parallel [(const_int 0)]))
10802 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10803 (parallel [(const_int 1)])))
10804 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10805 (parallel [(const_int 2)]))
10806 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10807 (parallel [(const_int 3)])))))]
10809 "fipr.s %1, %2, %0"
10810 [(set_attr "type" "fparith_media")])
10812 (define_insn "fsrra_s"
10813 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10814 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10818 [(set_attr "type" "atrans_media")])
10820 (define_insn "ftrv"
10821 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10825 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10826 (parallel [(const_int 0) (const_int 5)
10827 (const_int 10) (const_int 15)]))
10828 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10830 (vec_select:V4SF (match_dup 1)
10831 (parallel [(const_int 4) (const_int 9)
10832 (const_int 14) (const_int 3)]))
10833 (vec_select:V4SF (match_dup 2)
10834 (parallel [(const_int 1) (const_int 2)
10835 (const_int 3) (const_int 0)]))))
10838 (vec_select:V4SF (match_dup 1)
10839 (parallel [(const_int 8) (const_int 13)
10840 (const_int 2) (const_int 7)]))
10841 (vec_select:V4SF (match_dup 2)
10842 (parallel [(const_int 2) (const_int 3)
10843 (const_int 0) (const_int 1)])))
10845 (vec_select:V4SF (match_dup 1)
10846 (parallel [(const_int 12) (const_int 1)
10847 (const_int 6) (const_int 11)]))
10848 (vec_select:V4SF (match_dup 2)
10849 (parallel [(const_int 3) (const_int 0)
10850 (const_int 1) (const_int 2)]))))))]
10852 "ftrv.s %1, %2, %0"
10853 [(set_attr "type" "fparith_media")])
10856 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10857 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10861 [(set_attr "type" "arith_media")])
10863 (define_insn "nsbsi"
10864 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10866 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10870 [(set_attr "type" "arith_media")])
10872 (define_insn "nsbdi"
10873 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10875 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10879 [(set_attr "type" "arith_media")])
10881 (define_expand "ffsdi2"
10882 [(set (match_operand:DI 0 "arith_reg_dest" "")
10883 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10887 rtx scratch = gen_reg_rtx (DImode);
10890 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10891 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10892 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10893 emit_insn (gen_nsbdi (scratch, scratch));
10894 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10895 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10896 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10898 = gen_rtx_EXPR_LIST (REG_EQUAL,
10899 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10903 (define_expand "ffssi2"
10904 [(set (match_operand:SI 0 "arith_reg_dest" "")
10905 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10909 rtx scratch = gen_reg_rtx (SImode);
10910 rtx discratch = gen_reg_rtx (DImode);
10913 emit_insn (gen_adddi3 (discratch,
10914 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10916 emit_insn (gen_andcdi3 (discratch,
10917 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10919 emit_insn (gen_nsbsi (scratch, discratch));
10920 last = emit_insn (gen_subsi3 (operands[0],
10921 force_reg (SImode, GEN_INT (63)), scratch));
10923 = gen_rtx_EXPR_LIST (REG_EQUAL,
10924 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10928 (define_insn "byterev"
10929 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10930 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10931 (parallel [(const_int 7) (const_int 6) (const_int 5)
10932 (const_int 4) (const_int 3) (const_int 2)
10933 (const_int 1) (const_int 0)])))]
10936 [(set_attr "type" "arith_media")])
10938 (define_insn "prefetch"
10939 [(prefetch (match_operand:QI 0 "address_operand" "p")
10940 (match_operand:SI 1 "const_int_operand" "n")
10941 (match_operand:SI 2 "const_int_operand" "n"))]
10942 "TARGET_SHMEDIA || TARGET_HARD_SH4"
10945 if (TARGET_HARD_SH4)
10946 return \"pref @%0\";
10947 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10948 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10951 [(set_attr "type" "other")])