1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, 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)
146 (UNSPEC_DIV_INV_M0 30)
147 (UNSPEC_DIV_INV_M1 31)
148 (UNSPEC_DIV_INV_M2 32)
149 (UNSPEC_DIV_INV_M3 33)
150 (UNSPEC_DIV_INV20 34)
151 (UNSPEC_DIV_INV_TABLE 37)
157 ;; These are used with unspec_volatile.
163 (UNSPECV_WINDOW_END 10)
164 (UNSPECV_CONST_END 11)
167 ;; -------------------------------------------------------------------------
169 ;; -------------------------------------------------------------------------
174 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175 (const (symbol_ref "sh_cpu_attr")))
177 (define_attr "endian" "big,little"
178 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179 (const_string "little") (const_string "big"))))
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184 (const_string "yes") (const_string "no"))))
186 (define_attr "fmovd" "yes,no"
187 (const (if_then_else (symbol_ref "TARGET_FMOVD")
188 (const_string "yes") (const_string "no"))))
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
192 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194 (const_string "sh1"))))
196 ;; cbranch conditional branch instructions
197 ;; jump unconditional jumps
198 ;; arith ordinary arithmetic
199 ;; arith3 a compound insn that behaves similarly to a sequence of
200 ;; three insns of type arith
201 ;; arith3b like above, but might end with a redirected branch
203 ;; load_si Likewise, SImode variant for general register.
204 ;; fload Likewise, but load to fp register.
206 ;; move general purpose register to register
207 ;; mt_group other sh4 mt instructions
208 ;; fmove register to register, floating point
209 ;; smpy word precision integer multiply
210 ;; dmpy longword or doublelongword precision integer multiply
212 ;; pload load of pr reg, which can't be put into delay slot of rts
213 ;; prset copy register to pr reg, ditto
214 ;; pstore store of pr reg, which can't be put into delay slot of jsr
215 ;; prget copy pr to register, ditto
216 ;; pcload pc relative load of constant value
217 ;; pcfload Likewise, but load to fp register.
218 ;; pcload_si Likewise, SImode variant for general register.
219 ;; rte return from exception
220 ;; sfunc special function call with known used registers
221 ;; call function call
223 ;; fdiv floating point divide (or square root)
224 ;; gp_fpul move from general purpose register to fpul
225 ;; fpul_gp move from fpul to general purpose register
226 ;; mac_gp move from mac[lh] to general purpose register
227 ;; dfp_arith, dfp_cmp,dfp_conv
228 ;; ftrc_s fix_truncsfsi2_i4
229 ;; dfdiv double precision floating point divide (or square root)
230 ;; cwb ic_invalidate_line_i
231 ;; movua SH4a unaligned load
232 ;; fsrra square root reciprocal approximate
233 ;; fsca sine and cosine approximate
234 ;; tls_load load TLS related address
235 ;; arith_media SHmedia arithmetic, logical, and shift instructions
236 ;; cbranch_media SHmedia conditional branch instructions
237 ;; cmp_media SHmedia compare instructions
238 ;; dfdiv_media SHmedia double precision divide and square root
239 ;; dfmul_media SHmedia double precision multiply instruction
240 ;; dfparith_media SHmedia double precision floating point arithmetic
241 ;; dfpconv_media SHmedia double precision floating point conversions
242 ;; dmpy_media SHmedia longword multiply
243 ;; fcmp_media SHmedia floating point compare instructions
244 ;; fdiv_media SHmedia single precision divide and square root
245 ;; fload_media SHmedia floating point register load instructions
246 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
247 ;; fparith_media SHmedia single precision floating point arithmetic
248 ;; fpconv_media SHmedia single precision floating point conversions
249 ;; fstore_media SHmedia floating point register store instructions
250 ;; gettr_media SHmedia gettr instruction
251 ;; invalidate_line_media SHmedia invalidate_line sequence
252 ;; jump_media SHmedia unconditional branch instructions
253 ;; load_media SHmedia general register load instructions
254 ;; pt_media SHmedia pt instruction (expanded by assembler)
255 ;; ptabs_media SHmedia ptabs instruction
256 ;; store_media SHmedia general register store instructions
257 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
258 ;; mac_media SHmedia mac-style fixed point operations
259 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
260 ;; atrans_media SHmedia approximate transcendental functions
261 ;; ustore_media SHmedia unaligned stores
262 ;; nil no-op move, will be deleted.
265 "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"
266 (const_string "other"))
268 ;; We define a new attribute namely "insn_class".We use
269 ;; this for the DFA based pipeline description.
271 ;; mt_group SH4 "mt" group instructions.
273 ;; ex_group SH4 "ex" group instructions.
275 ;; ls_group SH4 "ls" group instructions.
278 (define_attr "insn_class"
279 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
280 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
281 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
282 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
283 (eq_attr "type" "cbranch,jump") (const_string "br_group")
284 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
285 (const_string "fe_group")
286 (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")]
287 (const_string "none")))
288 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
289 ;; so these do not belong in an insn group, although they are modeled
290 ;; with their own define_insn_reservations.
292 ;; Indicate what precision must be selected in fpscr for this insn, if any.
294 (define_attr "fp_mode" "single,double,none" (const_string "none"))
296 ;; Indicate if the fpu mode is set by this instruction
297 ;; "unknown" must have the value as "none" in fp_mode, and means
298 ;; that the instruction/abi has left the processor in an unknown
300 ;; "none" means that nothing has changed and no mode is set.
301 ;; This attribute is only used for the Renesas ABI.
302 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
304 ; If a conditional branch destination is within -252..258 bytes away
305 ; from the instruction it can be 2 bytes long. Something in the
306 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
307 ; branches are initially assumed to be 16 bytes long.
308 ; In machine_dependent_reorg, we split all branches that are longer than
311 ;; The maximum range used for SImode constant pool entries is 1018. A final
312 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
313 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
314 ;; instruction around the pool table, 2 bytes of alignment before the table,
315 ;; and 30 bytes of alignment after the table. That gives a maximum total
316 ;; pool size of 1058 bytes.
317 ;; Worst case code/pool content size ratio is 1:2 (using asms).
318 ;; Thus, in the worst case, there is one instruction in front of a maximum
319 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
320 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
321 ;; If we have a forward branch, the initial table will be put after the
322 ;; unconditional branch.
324 ;; ??? We could do much better by keeping track of the actual pcloads within
325 ;; the branch range and in the pcload range in front of the branch range.
327 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
329 (define_attr "short_cbranch_p" "no,yes"
330 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
332 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
334 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
338 ] (const_string "no")))
340 (define_attr "med_branch_p" "no,yes"
341 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
344 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
349 ] (const_string "no")))
351 (define_attr "med_cbranch_p" "no,yes"
352 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
355 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
360 ] (const_string "no")))
362 (define_attr "braf_branch_p" "no,yes"
363 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
368 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
370 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
373 ] (const_string "no")))
375 (define_attr "braf_cbranch_p" "no,yes"
376 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
378 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
381 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
383 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
386 ] (const_string "no")))
388 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
389 ; For wider ranges, we need a combination of a code and a data part.
390 ; If we can get a scratch register for a long range jump, the code
391 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
392 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
393 ; long; otherwise, it must be 6 bytes long.
395 ; All other instructions are two bytes long by default.
397 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
398 ;; but getattrtab doesn't understand this.
399 (define_attr "length" ""
400 (cond [(eq_attr "type" "cbranch")
401 (cond [(eq_attr "short_cbranch_p" "yes")
403 (eq_attr "med_cbranch_p" "yes")
405 (eq_attr "braf_cbranch_p" "yes")
407 ;; ??? using pc is not computed transitively.
408 (ne (match_dup 0) (match_dup 0))
410 (ne (symbol_ref ("flag_pic")) (const_int 0))
413 (eq_attr "type" "jump")
414 (cond [(eq_attr "med_branch_p" "yes")
416 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
418 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
419 (symbol_ref "code_for_indirect_jump_scratch")))
420 (cond [(eq_attr "braf_branch_p" "yes")
422 (eq (symbol_ref "flag_pic") (const_int 0))
424 (ne (symbol_ref "TARGET_SH2") (const_int 0))
425 (const_int 10)] (const_int 18))
426 (eq_attr "braf_branch_p" "yes")
428 ;; ??? using pc is not computed transitively.
429 (ne (match_dup 0) (match_dup 0))
431 (ne (symbol_ref ("flag_pic")) (const_int 0))
434 (eq_attr "type" "pt_media")
435 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
436 (const_int 20) (const_int 12))
437 (and (eq_attr "type" "jump_media")
438 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
440 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
444 ;; DFA descriptions for the pipelines
447 (include "shmedia.md")
450 (include "predicates.md")
452 ;; Definitions for filling delay slots
454 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
456 ;; ??? This should be (nil) instead of (const_int 0)
457 (define_attr "hit_stack" "yes,no"
458 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
461 (const_string "yes")))
463 (define_attr "interrupt_function" "no,yes"
464 (const (symbol_ref "current_function_interrupt")))
466 (define_attr "in_delay_slot" "yes,no"
467 (cond [(eq_attr "type" "cbranch") (const_string "no")
468 (eq_attr "type" "pcload,pcload_si") (const_string "no")
469 (eq_attr "needs_delay_slot" "yes") (const_string "no")
470 (eq_attr "length" "2") (const_string "yes")
471 ] (const_string "no")))
473 (define_attr "cond_delay_slot" "yes,no"
474 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
475 ] (const_string "no")))
477 (define_attr "is_sfunc" ""
478 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
480 (define_attr "is_mac_media" ""
481 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
483 (define_attr "branch_zero" "yes,no"
484 (cond [(eq_attr "type" "!cbranch") (const_string "no")
485 (ne (symbol_ref "(next_active_insn (insn)\
486 == (prev_active_insn\
487 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
488 && get_attr_length (next_active_insn (insn)) == 2")
490 (const_string "yes")]
491 (const_string "no")))
493 ;; SH4 Double-precision computation with double-precision result -
494 ;; the two halves are ready at different times.
495 (define_attr "dfp_comp" "yes,no"
496 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
497 (const_string "no")))
499 ;; Insns for which the latency of a preceding fp insn is decreased by one.
500 (define_attr "late_fp_use" "yes,no" (const_string "no"))
501 ;; And feeding insns for which this relevant.
502 (define_attr "any_fp_comp" "yes,no"
503 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
504 (const_string "yes")]
505 (const_string "no")))
507 (define_attr "any_int_load" "yes,no"
508 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
509 (const_string "yes")]
510 (const_string "no")))
512 (define_attr "highpart" "user, ignore, extend, depend, must_split"
513 (const_string "user"))
516 (eq_attr "needs_delay_slot" "yes")
517 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
519 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
520 ;; and thus we can't put a pop instruction in its delay slot.
521 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
522 ;; instruction can go in the delay slot.
524 ;; Since a normal return (rts) implicitly uses the PR register,
525 ;; we can't allow PR register loads in an rts delay slot.
528 (eq_attr "type" "return")
529 [(and (eq_attr "in_delay_slot" "yes")
530 (ior (and (eq_attr "interrupt_function" "no")
531 (eq_attr "type" "!pload,prset"))
532 (and (eq_attr "interrupt_function" "yes")
534 (ne (symbol_ref "TARGET_SH3") (const_int 0))
535 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
537 ;; Since a call implicitly uses the PR register, we can't allow
538 ;; a PR register store in a jsr delay slot.
541 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
542 [(and (eq_attr "in_delay_slot" "yes")
543 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
545 ;; Say that we have annulled true branches, since this gives smaller and
546 ;; faster code when branches are predicted as not taken.
548 ;; ??? The non-annulled condition should really be "in_delay_slot",
549 ;; but insns that can be filled in non-annulled get priority over insns
550 ;; that can only be filled in anulled.
553 (and (eq_attr "type" "cbranch")
554 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
555 ;; SH2e has a hardware bug that pretty much prohibits the use of
556 ;; annuled delay slots.
557 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
558 (not (eq_attr "cpu" "sh2e"))) (nil)])
560 ;; -------------------------------------------------------------------------
561 ;; SImode signed integer comparisons
562 ;; -------------------------------------------------------------------------
566 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
567 (match_operand:SI 1 "arith_operand" "K08,r"))
571 [(set_attr "type" "mt_group")])
573 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
574 ;; That would still allow reload to create cmpi instructions, but would
575 ;; perhaps allow forcing the constant into a register when that is better.
576 ;; Probably should use r0 for mem/imm compares, but force constant into a
577 ;; register for pseudo/imm compares.
579 (define_insn "cmpeqsi_t"
581 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
582 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
588 [(set_attr "type" "mt_group")])
590 (define_insn "cmpgtsi_t"
592 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
593 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
598 [(set_attr "type" "mt_group")])
600 (define_insn "cmpgesi_t"
602 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
603 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
608 [(set_attr "type" "mt_group")])
610 ;; -------------------------------------------------------------------------
611 ;; SImode unsigned integer comparisons
612 ;; -------------------------------------------------------------------------
614 (define_insn "cmpgeusi_t"
616 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
617 (match_operand:SI 1 "arith_reg_operand" "r")))]
620 [(set_attr "type" "mt_group")])
622 (define_insn "cmpgtusi_t"
624 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
625 (match_operand:SI 1 "arith_reg_operand" "r")))]
628 [(set_attr "type" "mt_group")])
630 ;; We save the compare operands in the cmpxx patterns and use them when
631 ;; we generate the branch.
633 (define_expand "cmpsi"
635 (compare (match_operand:SI 0 "cmpsi_operand" "")
636 (match_operand:SI 1 "arith_operand" "")))]
637 "TARGET_SH1 || TARGET_SHMEDIA"
640 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
641 && GET_CODE (operands[1]) != CONST_INT)
642 operands[0] = copy_to_mode_reg (SImode, operands[0]);
643 sh_compare_op0 = operands[0];
644 sh_compare_op1 = operands[1];
648 ;; -------------------------------------------------------------------------
649 ;; DImode signed integer comparisons
650 ;; -------------------------------------------------------------------------
652 ;; ??? Could get better scheduling by splitting the initial test from the
653 ;; rest of the insn after reload. However, the gain would hardly justify
654 ;; the sh.md size increase necessary to do that.
658 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
659 (match_operand:DI 1 "arith_operand" "r"))
662 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
664 [(set_attr "length" "6")
665 (set_attr "type" "arith3b")])
667 (define_insn "cmpeqdi_t"
669 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
670 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
673 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
674 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
675 [(set_attr "length" "6")
676 (set_attr "type" "arith3b")])
680 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
681 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
682 ;; If we applied this split when not optimizing, it would only be
683 ;; applied during the machine-dependent reorg, when no new basic blocks
685 "TARGET_SH1 && reload_completed && optimize"
686 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
687 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
688 (label_ref (match_dup 6))
690 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
695 = gen_rtx_REG (SImode,
696 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
698 = (operands[1] == const0_rtx
700 : gen_rtx_REG (SImode,
701 true_regnum (operands[1])
702 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
703 operands[4] = gen_lowpart (SImode, operands[0]);
704 operands[5] = gen_lowpart (SImode, operands[1]);
705 operands[6] = gen_label_rtx ();
708 (define_insn "cmpgtdi_t"
710 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
711 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
714 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
715 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
716 [(set_attr "length" "8")
717 (set_attr "type" "arith3")])
719 (define_insn "cmpgedi_t"
721 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
722 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
725 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
727 [(set_attr "length" "8,2")
728 (set_attr "type" "arith3,mt_group")])
730 ;; -------------------------------------------------------------------------
731 ;; DImode unsigned integer comparisons
732 ;; -------------------------------------------------------------------------
734 (define_insn "cmpgeudi_t"
736 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
737 (match_operand:DI 1 "arith_reg_operand" "r")))]
739 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
740 [(set_attr "length" "8")
741 (set_attr "type" "arith3")])
743 (define_insn "cmpgtudi_t"
745 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
746 (match_operand:DI 1 "arith_reg_operand" "r")))]
748 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
749 [(set_attr "length" "8")
750 (set_attr "type" "arith3")])
752 (define_insn "cmpeqsi_media"
753 [(set (match_operand:DI 0 "register_operand" "=r")
754 (eq:DI (match_operand:SI 1 "logical_operand" "%r")
755 (match_operand:SI 2 "cmp_operand" "Nr")))]
758 [(set_attr "type" "cmp_media")])
760 (define_insn "cmpeqdi_media"
761 [(set (match_operand:DI 0 "register_operand" "=r")
762 (eq:DI (match_operand:DI 1 "register_operand" "%r")
763 (match_operand:DI 2 "cmp_operand" "Nr")))]
766 [(set_attr "type" "cmp_media")])
768 (define_insn "cmpgtsi_media"
769 [(set (match_operand:DI 0 "register_operand" "=r")
770 (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
771 (match_operand:SI 2 "cmp_operand" "rN")))]
774 [(set_attr "type" "cmp_media")])
776 (define_insn "cmpgtdi_media"
777 [(set (match_operand:DI 0 "register_operand" "=r")
778 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
779 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
782 [(set_attr "type" "cmp_media")])
784 (define_insn "cmpgtusi_media"
785 [(set (match_operand:DI 0 "register_operand" "=r")
786 (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
787 (match_operand:SI 2 "cmp_operand" "rN")))]
789 "cmpgtu %N1, %N2, %0"
790 [(set_attr "type" "cmp_media")])
792 (define_insn "cmpgtudi_media"
793 [(set (match_operand:DI 0 "register_operand" "=r")
794 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
795 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
797 "cmpgtu %N1, %N2, %0"
798 [(set_attr "type" "cmp_media")])
800 (define_insn "cmpsieqsi_media"
801 [(set (match_operand:SI 0 "register_operand" "=r")
802 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
803 (match_operand:SI 2 "cmp_operand" "Nr")))]
806 [(set_attr "type" "cmp_media")])
808 (define_insn "cmpsieqdi_media"
809 [(set (match_operand:SI 0 "register_operand" "=r")
810 (eq:SI (match_operand:DI 1 "register_operand" "%r")
811 (match_operand:DI 2 "cmp_operand" "Nr")))]
814 [(set_attr "type" "cmp_media")])
816 (define_insn "cmpsigtsi_media"
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
819 (match_operand:SI 2 "cmp_operand" "rN")))]
822 [(set_attr "type" "cmp_media")])
824 (define_insn "cmpsigtdi_media"
825 [(set (match_operand:SI 0 "register_operand" "=r")
826 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
827 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
830 [(set_attr "type" "cmp_media")])
832 (define_insn "cmpsigtusi_media"
833 [(set (match_operand:SI 0 "register_operand" "=r")
834 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
835 (match_operand:SI 2 "cmp_operand" "rN")))]
837 "cmpgtu %N1, %N2, %0"
838 [(set_attr "type" "cmp_media")])
840 (define_insn "cmpsigtudi_media"
841 [(set (match_operand:SI 0 "register_operand" "=r")
842 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
843 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
845 "cmpgtu %N1, %N2, %0"
846 [(set_attr "type" "cmp_media")])
848 ; These two patterns are for combine.
849 (define_insn "*cmpne0si_media"
850 [(set (match_operand:DI 0 "register_operand" "=r")
851 (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
854 [(set_attr "type" "cmp_media")])
856 (define_insn "*cmpne0sisi_media"
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
861 [(set_attr "type" "cmp_media")])
863 ;; We save the compare operands in the cmpxx patterns and use them when
864 ;; we generate the branch.
866 (define_expand "cmpdi"
868 (compare (match_operand:DI 0 "arith_operand" "")
869 (match_operand:DI 1 "arith_operand" "")))]
870 "TARGET_SH2 || TARGET_SHMEDIA"
873 sh_compare_op0 = operands[0];
874 sh_compare_op1 = operands[1];
877 ;; -------------------------------------------------------------------------
878 ;; Conditional move instructions
879 ;; -------------------------------------------------------------------------
881 ;; The insn names may seem reversed, but note that cmveq performs the move
882 ;; if op1 == 0, and cmvne does it if op1 != 0.
884 (define_insn "movdicc_false"
885 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
886 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
888 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
889 (match_operand:DI 3 "arith_reg_operand" "0")))]
892 [(set_attr "type" "arith_media")])
894 (define_insn "movdicc_true"
895 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
896 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
898 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
899 (match_operand:DI 3 "arith_reg_operand" "0")))]
902 [(set_attr "type" "arith_media")])
905 [(set (match_operand:DI 0 "arith_reg_dest" "")
906 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
907 [(match_operand:DI 1 "arith_reg_operand" "")
909 (match_operand:DI 2 "arith_reg_dest" "")
911 (set (match_dup 2) (match_dup 0))]
912 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
914 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
917 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
918 VOIDmode, operands[1], CONST0_RTX (DImode));
922 [(set (match_operand:DI 0 "general_movdst_operand" "")
923 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
924 (set (match_operand:DI 2 "arith_reg_dest" "")
925 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
926 [(match_operand:DI 3 "arith_reg_operand" "")
930 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
932 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
935 (define_expand "movdicc"
936 [(set (match_operand:DI 0 "register_operand" "")
937 (if_then_else:DI (match_operand 1 "comparison_operator" "")
938 (match_operand:DI 2 "register_operand" "")
939 (match_operand:DI 3 "register_operand" "")))]
943 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
944 && GET_MODE (sh_compare_op0) == DImode
945 && sh_compare_op1 == const0_rtx)
946 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
947 sh_compare_op0, sh_compare_op1);
955 tmp = gen_reg_rtx (DImode);
957 switch (GET_CODE (operands[1]))
960 emit_insn (gen_seq (tmp));
961 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
965 emit_insn (gen_seq (tmp));
966 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
970 emit_insn (gen_sgt (tmp));
971 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
975 emit_insn (gen_slt (tmp));
976 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
980 emit_insn (gen_slt (tmp));
981 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
985 emit_insn (gen_sgt (tmp));
986 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
990 emit_insn (gen_sgtu (tmp));
991 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
995 emit_insn (gen_sltu (tmp));
996 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1000 emit_insn (gen_sltu (tmp));
1001 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1005 emit_insn (gen_sgtu (tmp));
1006 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1010 emit_insn (gen_sunordered (tmp));
1011 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1015 emit_insn (gen_sunordered (tmp));
1016 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1033 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1034 ;; SImode to DImode.
1035 (define_insn "movsicc_false"
1036 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1037 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1039 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1040 (match_operand:SI 3 "arith_reg_operand" "0")))]
1043 [(set_attr "type" "arith_media")])
1045 (define_insn "movsicc_true"
1046 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1047 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1049 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1050 (match_operand:SI 3 "arith_reg_operand" "0")))]
1053 [(set_attr "type" "arith_media")])
1056 [(set (match_operand:SI 0 "arith_reg_dest" "")
1057 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1058 [(match_operand:SI 1 "arith_reg_operand" "")
1060 (match_operand:SI 2 "arith_reg_dest" "")
1062 (set (match_dup 2) (match_dup 0))]
1063 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1065 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1068 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1069 VOIDmode, operands[1], CONST0_RTX (SImode));
1073 [(set (match_operand:SI 0 "general_movdst_operand" "")
1074 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1075 (set (match_operand:SI 2 "arith_reg_dest" "")
1076 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1077 [(match_operand:SI 3 "arith_reg_operand" "")
1081 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1082 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1084 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1087 replace_rtx (operands[4], operands[0], operands[1]);
1091 [(set (match_operand 0 "any_register_operand" "")
1092 (match_operand 1 "any_register_operand" ""))
1093 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1094 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1095 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1096 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1097 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1098 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1099 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1100 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1101 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1102 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1103 && (REGNO_REG_CLASS (REGNO (operands[0]))
1104 == REGNO_REG_CLASS (REGNO (operands[2])))
1105 && (REGNO_REG_CLASS (REGNO (operands[1]))
1106 == REGNO_REG_CLASS (REGNO (operands[0])))"
1107 [(set (match_dup 0) (match_dup 3))
1108 (set (match_dup 4) (match_dup 5))]
1112 rtx replacements[4];
1114 /* We want to replace occurrences of operands[0] with operands[1] and
1115 operands[2] with operands[0] in operands[4]/operands[5].
1116 Doing just two replace_rtx calls naively would result in the second
1117 replacement undoing all that the first did if operands[1] and operands[2]
1118 are identical, so we must do this simultaneously. */
1119 replacements[0] = operands[0];
1120 replacements[1] = operands[1];
1121 replacements[2] = operands[2];
1122 replacements[3] = operands[0];
1123 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1124 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1125 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1128 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1129 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1130 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1131 /* The operands array is aliased to recog_data.operand, which gets
1132 clobbered by extract_insn, so finish with it now. */
1133 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1134 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1135 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1136 always uses emit_insn. */
1137 /* Check that we don't violate matching constraints or earlyclobbers. */
1138 extract_insn (emit_insn (set1));
1139 if (! constrain_operands (1))
1141 extract_insn (emit (set2));
1142 if (! constrain_operands (1))
1146 tmp = replacements[0];
1147 replacements[0] = replacements[1];
1148 replacements[1] = tmp;
1149 tmp = replacements[2];
1150 replacements[2] = replacements[3];
1151 replacements[3] = tmp;
1152 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1153 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1154 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1160 ;; The register allocator is rather clumsy in handling multi-way conditional
1161 ;; moves, so allow the combiner to make them, and we split them up after
1163 (define_insn_and_split "*movsicc_umin"
1164 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1165 (umin:SI (if_then_else:SI
1166 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1168 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1169 (match_operand:SI 3 "register_operand" "0"))
1170 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1171 (clobber (match_scratch:SI 5 "=&r"))]
1172 "TARGET_SHMEDIA && no_new_pseudos"
1174 "TARGET_SHMEDIA && reload_completed"
1178 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1180 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1181 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1186 (define_insn "*movsicc_t_false"
1187 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1188 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1189 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1190 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1191 "TARGET_PRETEND_CMOVE
1192 && (arith_reg_operand (operands[1], SImode)
1193 || (immediate_operand (operands[1], SImode)
1194 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1195 "bt 0f\;mov %1,%0\\n0:"
1196 [(set_attr "type" "mt_group,arith") ;; poor approximation
1197 (set_attr "length" "4")])
1199 (define_insn "*movsicc_t_true"
1200 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1201 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1202 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1203 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1204 "TARGET_PRETEND_CMOVE
1205 && (arith_reg_operand (operands[1], SImode)
1206 || (immediate_operand (operands[1], SImode)
1207 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1208 "bf 0f\;mov %1,%0\\n0:"
1209 [(set_attr "type" "mt_group,arith") ;; poor approximation
1210 (set_attr "length" "4")])
1212 (define_expand "movsicc"
1213 [(set (match_operand:SI 0 "arith_reg_dest" "")
1214 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1215 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1216 (match_operand:SI 3 "arith_reg_operand" "")))]
1217 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1220 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1221 && GET_MODE (sh_compare_op0) == SImode
1223 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1224 && sh_compare_op1 == const0_rtx)
1225 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1226 sh_compare_op0, sh_compare_op1);
1227 else if (TARGET_PRETEND_CMOVE)
1229 enum rtx_code code = GET_CODE (operands[1]);
1230 enum rtx_code new_code = code;
1233 if (! currently_expanding_to_rtl)
1237 case LT: case LE: case LEU: case LTU:
1238 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1241 new_code = reverse_condition (code);
1243 case EQ: case GT: case GE: case GEU: case GTU:
1248 tmp = prepare_scc_operands (new_code);
1249 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1259 tmp = gen_reg_rtx (SImode);
1261 switch (GET_CODE (operands[1]))
1264 emit_insn (gen_seq (tmp));
1265 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1269 emit_insn (gen_seq (tmp));
1270 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1274 emit_insn (gen_sgt (tmp));
1275 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1279 emit_insn (gen_slt (tmp));
1280 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1284 emit_insn (gen_slt (tmp));
1285 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1289 emit_insn (gen_sgt (tmp));
1290 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1294 emit_insn (gen_sgtu (tmp));
1295 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1299 emit_insn (gen_sltu (tmp));
1300 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1304 emit_insn (gen_sltu (tmp));
1305 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1309 emit_insn (gen_sgtu (tmp));
1310 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1314 emit_insn (gen_sunordered (tmp));
1315 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1319 emit_insn (gen_sunordered (tmp));
1320 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1337 (define_expand "movqicc"
1338 [(set (match_operand:QI 0 "register_operand" "")
1339 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1340 (match_operand:QI 2 "register_operand" "")
1341 (match_operand:QI 3 "register_operand" "")))]
1345 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1346 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1347 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1348 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1352 ;; -------------------------------------------------------------------------
1353 ;; Addition instructions
1354 ;; -------------------------------------------------------------------------
1356 (define_expand "adddi3"
1357 [(set (match_operand:DI 0 "arith_reg_operand" "")
1358 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1359 (match_operand:DI 2 "arith_operand" "")))]
1365 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1367 operands[2] = force_reg (DImode, operands[2]);
1368 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1373 (define_insn "*adddi3_media"
1374 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1375 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1376 (match_operand:DI 2 "arith_operand" "r,I10")))]
1381 [(set_attr "type" "arith_media")])
1383 (define_insn "*adddisi3_media"
1384 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1385 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1386 (match_operand:DI 2 "arith_operand" "r,I10")))]
1391 [(set_attr "type" "arith_media")
1392 (set_attr "highpart" "ignore")])
1394 (define_insn "adddi3z_media"
1395 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1397 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1398 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1400 "addz.l %1, %N2, %0"
1401 [(set_attr "type" "arith_media")
1402 (set_attr "highpart" "ignore")])
1404 (define_insn "adddi3_compact"
1405 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1406 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1407 (match_operand:DI 2 "arith_reg_operand" "r")))
1408 (clobber (reg:SI T_REG))]
1411 [(set_attr "length" "6")])
1414 [(set (match_operand:DI 0 "arith_reg_dest" "")
1415 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1416 (match_operand:DI 2 "arith_reg_operand" "")))
1417 (clobber (reg:SI T_REG))]
1418 "TARGET_SH1 && reload_completed"
1422 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1423 high0 = gen_rtx_REG (SImode,
1424 true_regnum (operands[0])
1425 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1426 high2 = gen_rtx_REG (SImode,
1427 true_regnum (operands[2])
1428 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1429 emit_insn (gen_clrt ());
1430 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1431 emit_insn (gen_addc1 (high0, high0, high2));
1436 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1438 (match_operand:SI 2 "arith_reg_operand" "r"))
1441 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1444 [(set_attr "type" "arith")])
1446 (define_insn "addc1"
1447 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1448 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1449 (match_operand:SI 2 "arith_reg_operand" "r"))
1451 (clobber (reg:SI T_REG))]
1454 [(set_attr "type" "arith")])
1456 (define_expand "addsi3"
1457 [(set (match_operand:SI 0 "arith_reg_operand" "")
1458 (plus:SI (match_operand:SI 1 "arith_operand" "")
1459 (match_operand:SI 2 "arith_operand" "")))]
1464 operands[1] = force_reg (SImode, operands[1]);
1467 (define_insn "addsi3_media"
1468 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1469 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1470 (match_operand:SI 2 "arith_operand" "r,I10")))]
1475 [(set_attr "type" "arith_media")
1476 (set_attr "highpart" "ignore")])
1478 (define_insn "addsidi3_media"
1479 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1480 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1482 (match_operand:SI 2 "arith_operand"
1488 [(set_attr "type" "arith_media")
1489 (set_attr "highpart" "ignore")])
1491 (define_insn "*addsi3_compact"
1492 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1493 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1494 (match_operand:SI 2 "arith_operand" "rI08")))]
1497 [(set_attr "type" "arith")])
1499 ;; -------------------------------------------------------------------------
1500 ;; Subtraction instructions
1501 ;; -------------------------------------------------------------------------
1503 (define_expand "subdi3"
1504 [(set (match_operand:DI 0 "arith_reg_operand" "")
1505 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1506 (match_operand:DI 2 "arith_reg_operand" "")))]
1512 operands[1] = force_reg (DImode, operands[1]);
1513 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1518 (define_insn "*subdi3_media"
1519 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1520 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1521 (match_operand:DI 2 "arith_reg_operand" "r")))]
1524 [(set_attr "type" "arith_media")])
1526 (define_insn "subdisi3_media"
1527 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1528 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1529 (match_operand:DI 2 "arith_reg_operand" "r")))]
1532 [(set_attr "type" "arith_media")
1533 (set_attr "highpart" "ignore")])
1535 (define_insn "subdi3_compact"
1536 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1537 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1538 (match_operand:DI 2 "arith_reg_operand" "r")))
1539 (clobber (reg:SI T_REG))]
1542 [(set_attr "length" "6")])
1545 [(set (match_operand:DI 0 "arith_reg_dest" "")
1546 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1547 (match_operand:DI 2 "arith_reg_operand" "")))
1548 (clobber (reg:SI T_REG))]
1549 "TARGET_SH1 && reload_completed"
1553 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1554 high0 = gen_rtx_REG (SImode,
1555 true_regnum (operands[0])
1556 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1557 high2 = gen_rtx_REG (SImode,
1558 true_regnum (operands[2])
1559 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1560 emit_insn (gen_clrt ());
1561 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1562 emit_insn (gen_subc1 (high0, high0, high2));
1567 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1568 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1569 (match_operand:SI 2 "arith_reg_operand" "r"))
1572 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1577 [(set_attr "type" "arith")])
1579 (define_insn "subc1"
1580 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1581 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1582 (match_operand:SI 2 "arith_reg_operand" "r"))
1584 (clobber (reg:SI T_REG))]
1587 [(set_attr "type" "arith")])
1589 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1590 ;; pattern for this case. This helps multimedia applications that compute
1591 ;; the sum of absolute differences.
1592 (define_insn "mov_neg_si_t"
1593 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1596 [(set_attr "type" "arith")])
1598 (define_insn "*subsi3_internal"
1599 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1600 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1601 (match_operand:SI 2 "arith_reg_operand" "r")))]
1604 [(set_attr "type" "arith")])
1606 (define_insn_and_split "*subsi3_media"
1607 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1608 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1609 (match_operand:SI 2 "extend_reg_operand" "r")))]
1611 && (operands[1] != constm1_rtx
1612 || (GET_CODE (operands[2]) != TRUNCATE
1613 && GET_CODE (operands[2]) != SUBREG))"
1615 "operands[1] == constm1_rtx"
1616 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1618 [(set_attr "type" "arith_media")
1619 (set_attr "highpart" "ignore")])
1622 [(set (match_operand:SI 0 "arith_reg_dest" "")
1623 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1624 "general_extend_operand"
1626 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1627 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1628 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1632 [(set (match_operand:SI 0 "arith_reg_dest" "")
1633 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1634 "general_extend_operand"
1636 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1637 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1638 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1640 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1641 ;; will sometimes save one instruction. Otherwise we might get
1642 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1645 (define_expand "subsi3"
1646 [(set (match_operand:SI 0 "arith_reg_operand" "")
1647 (minus:SI (match_operand:SI 1 "arith_operand" "")
1648 (match_operand:SI 2 "arith_reg_operand" "")))]
1652 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1654 emit_insn (gen_negsi2 (operands[0], operands[2]));
1655 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1660 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1662 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1663 operands[1] = force_reg (SImode, operands[1]);
1667 ;; -------------------------------------------------------------------------
1668 ;; Division instructions
1669 ;; -------------------------------------------------------------------------
1671 ;; We take advantage of the library routines which don't clobber as many
1672 ;; registers as a normal function call would.
1674 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1675 ;; also has an effect on the register that holds the address of the sfunc.
1676 ;; To make this work, we have an extra dummy insn that shows the use
1677 ;; of this register for reorg.
1679 (define_insn "use_sfunc_addr"
1680 [(set (reg:SI PR_REG)
1681 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1682 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1684 [(set_attr "length" "0")])
1686 (define_insn "udivsi3_sh2a"
1687 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1688 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1689 (match_operand:SI 2 "arith_reg_operand" "z")))]
1692 [(set_attr "type" "arith")
1693 (set_attr "in_delay_slot" "no")])
1695 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1696 ;; hard register 0. If we used hard register 0, then the next instruction
1697 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1698 ;; gets allocated to a stack slot that needs its address reloaded, then
1699 ;; there is nothing to prevent reload from using r0 to reload the address.
1700 ;; This reload would clobber the value in r0 we are trying to store.
1701 ;; If we let reload allocate r0, then this problem can never happen.
1703 (define_insn "udivsi3_i1"
1704 [(set (match_operand:SI 0 "register_operand" "=z")
1705 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1706 (clobber (reg:SI T_REG))
1707 (clobber (reg:SI PR_REG))
1708 (clobber (reg:SI R4_REG))
1709 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1710 "TARGET_SH1 && ! TARGET_SH4"
1712 [(set_attr "type" "sfunc")
1713 (set_attr "needs_delay_slot" "yes")])
1715 ; Since shmedia-nofpu code could be linked against shcompact code, and
1716 ; the udivsi3 libcall has the same name, we must consider all registers
1717 ; clobbered that are in the union of the registers clobbered by the
1718 ; shmedia and the shcompact implementation. Note, if the shcompact
1719 ; implementation actually used shcompact code, we'd need to clobber
1720 ; also r23 and fr23.
1721 (define_insn "udivsi3_i1_media"
1722 [(set (match_operand:SI 0 "register_operand" "=z")
1723 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1724 (clobber (reg:SI T_MEDIA_REG))
1725 (clobber (reg:SI PR_MEDIA_REG))
1726 (clobber (reg:SI R20_REG))
1727 (clobber (reg:SI R21_REG))
1728 (clobber (reg:SI R22_REG))
1729 (clobber (reg:DI TR0_REG))
1730 (clobber (reg:DI TR1_REG))
1731 (clobber (reg:DI TR2_REG))
1732 (use (match_operand 1 "target_operand" "b"))]
1733 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1735 [(set_attr "type" "sfunc")
1736 (set_attr "needs_delay_slot" "yes")])
1738 (define_expand "udivsi3_i4_media"
1740 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1742 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1743 (set (match_dup 5) (float:DF (match_dup 3)))
1744 (set (match_dup 6) (float:DF (match_dup 4)))
1745 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1746 (set (match_dup 8) (fix:DI (match_dup 7)))
1747 (set (match_operand:SI 0 "register_operand" "")
1748 (truncate:SI (match_dup 8)))]
1749 "TARGET_SHMEDIA_FPU"
1752 operands[3] = gen_reg_rtx (DImode);
1753 operands[4] = gen_reg_rtx (DImode);
1754 operands[5] = gen_reg_rtx (DFmode);
1755 operands[6] = gen_reg_rtx (DFmode);
1756 operands[7] = gen_reg_rtx (DFmode);
1757 operands[8] = gen_reg_rtx (DImode);
1760 (define_insn "udivsi3_i4"
1761 [(set (match_operand:SI 0 "register_operand" "=y")
1762 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1763 (clobber (reg:SI T_REG))
1764 (clobber (reg:SI PR_REG))
1765 (clobber (reg:DF DR0_REG))
1766 (clobber (reg:DF DR2_REG))
1767 (clobber (reg:DF DR4_REG))
1768 (clobber (reg:SI R0_REG))
1769 (clobber (reg:SI R1_REG))
1770 (clobber (reg:SI R4_REG))
1771 (clobber (reg:SI R5_REG))
1772 (use (reg:PSI FPSCR_REG))
1773 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1774 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1776 [(set_attr "type" "sfunc")
1777 (set_attr "fp_mode" "double")
1778 (set_attr "needs_delay_slot" "yes")])
1780 (define_insn "udivsi3_i4_single"
1781 [(set (match_operand:SI 0 "register_operand" "=y")
1782 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1783 (clobber (reg:SI T_REG))
1784 (clobber (reg:SI PR_REG))
1785 (clobber (reg:DF DR0_REG))
1786 (clobber (reg:DF DR2_REG))
1787 (clobber (reg:DF DR4_REG))
1788 (clobber (reg:SI R0_REG))
1789 (clobber (reg:SI R1_REG))
1790 (clobber (reg:SI R4_REG))
1791 (clobber (reg:SI R5_REG))
1792 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1793 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1795 [(set_attr "type" "sfunc")
1796 (set_attr "needs_delay_slot" "yes")])
1798 (define_insn "udivsi3_i4_int"
1799 [(set (match_operand:SI 0 "register_operand" "=z")
1800 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1801 (clobber (reg:SI T_REG))
1802 (clobber (reg:SI R1_REG))
1803 (clobber (reg:SI PR_REG))
1804 (clobber (reg:SI MACH_REG))
1805 (clobber (reg:SI MACL_REG))
1806 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1809 [(set_attr "type" "sfunc")
1810 (set_attr "needs_delay_slot" "yes")])
1813 (define_expand "udivsi3"
1814 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1815 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1816 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1817 (parallel [(set (match_operand:SI 0 "register_operand" "")
1818 (udiv:SI (reg:SI R4_REG)
1820 (clobber (reg:SI T_REG))
1821 (clobber (reg:SI PR_REG))
1822 (clobber (reg:SI R4_REG))
1823 (use (match_dup 3))])]
1829 operands[3] = gen_reg_rtx (Pmode);
1830 /* Emit the move of the address to a pseudo outside of the libcall. */
1831 if (TARGET_DIVIDE_CALL_TABLE)
1833 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1834 that causes problems when the divide code is supposed to come from a
1835 separate library. Division by zero is undefined, so dividing 1 can be
1836 implemented by comparing with the divisor. */
1837 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1839 emit_insn (gen_cmpsi (operands[1], operands[2]));
1840 emit_insn (gen_sgeu (operands[0]));
1843 else if (operands[2] == const0_rtx)
1845 emit_move_insn (operands[0], operands[2]);
1848 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1849 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1851 else if (TARGET_DIVIDE_CALL_FP)
1853 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1854 if (TARGET_FPU_SINGLE)
1855 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1857 last = gen_udivsi3_i4 (operands[0], operands[3]);
1859 else if (TARGET_SHMEDIA_FPU)
1861 operands[1] = force_reg (SImode, operands[1]);
1862 operands[2] = force_reg (SImode, operands[2]);
1863 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1866 else if (TARGET_SH2A)
1868 operands[1] = force_reg (SImode, operands[1]);
1869 operands[2] = force_reg (SImode, operands[2]);
1870 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1873 else if (TARGET_SH5)
1875 function_symbol (operands[3],
1876 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1880 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1881 else if (TARGET_FPU_ANY)
1882 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1884 last = gen_udivsi3_i1 (operands[0], operands[3]);
1888 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1889 last = gen_udivsi3_i1 (operands[0], operands[3]);
1891 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1892 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1893 last = emit_insn (last);
1894 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1895 invariant code motion can move it. */
1896 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1897 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1901 (define_insn "divsi3_sh2a"
1902 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1903 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1904 (match_operand:SI 2 "arith_reg_operand" "z")))]
1907 [(set_attr "type" "arith")
1908 (set_attr "in_delay_slot" "no")])
1910 (define_insn "divsi3_i1"
1911 [(set (match_operand:SI 0 "register_operand" "=z")
1912 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1913 (clobber (reg:SI T_REG))
1914 (clobber (reg:SI PR_REG))
1915 (clobber (reg:SI R1_REG))
1916 (clobber (reg:SI R2_REG))
1917 (clobber (reg:SI R3_REG))
1918 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1919 "TARGET_SH1 && ! TARGET_SH4"
1921 [(set_attr "type" "sfunc")
1922 (set_attr "needs_delay_slot" "yes")])
1924 (define_insn "divsi3_i1_media"
1925 [(set (match_operand:SI 0 "register_operand" "=z")
1926 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1927 (clobber (reg:SI T_MEDIA_REG))
1928 (clobber (reg:SI PR_MEDIA_REG))
1929 (clobber (reg:SI R1_REG))
1930 (clobber (reg:SI R20_REG))
1931 (clobber (reg:SI R21_REG))
1932 (clobber (reg:SI TR0_REG))
1933 (use (match_operand 1 "target_operand" "b"))]
1934 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1936 [(set_attr "type" "sfunc")])
1938 (define_insn "divsi3_media_2"
1939 [(set (match_operand:SI 0 "register_operand" "=z")
1940 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1941 (clobber (reg:SI T_MEDIA_REG))
1942 (clobber (reg:SI PR_MEDIA_REG))
1943 (clobber (reg:SI R1_REG))
1944 (clobber (reg:SI R21_REG))
1945 (clobber (reg:SI TR0_REG))
1946 (use (reg:SI R20_REG))
1947 (use (match_operand 1 "target_operand" "b"))]
1948 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1950 [(set_attr "type" "sfunc")])
1952 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1953 ;; hard reg clobbers and data dependencies that we need when we want
1954 ;; to rematerialize the division into a call.
1955 (define_insn_and_split "divsi_inv_call"
1956 [(set (match_operand:SI 0 "register_operand" "=r")
1957 (div:SI (match_operand:SI 1 "register_operand" "r")
1958 (match_operand:SI 2 "register_operand" "r")))
1959 (clobber (reg:SI R4_REG))
1960 (clobber (reg:SI R5_REG))
1961 (clobber (reg:SI T_MEDIA_REG))
1962 (clobber (reg:SI PR_MEDIA_REG))
1963 (clobber (reg:SI R1_REG))
1964 (clobber (reg:SI R21_REG))
1965 (clobber (reg:SI TR0_REG))
1966 (clobber (reg:SI R20_REG))
1967 (use (match_operand:SI 3 "register_operand" "r"))]
1970 "&& (high_life_started || reload_completed)"
1971 [(set (match_dup 0) (match_dup 3))]
1973 [(set_attr "highpart" "must_split")])
1975 ;; This is the combiner pattern for -mdiv=inv:call .
1976 (define_insn_and_split "*divsi_inv_call_combine"
1977 [(set (match_operand:SI 0 "register_operand" "=z")
1978 (div:SI (match_operand:SI 1 "register_operand" "r")
1979 (match_operand:SI 2 "register_operand" "r")))
1980 (clobber (reg:SI R4_REG))
1981 (clobber (reg:SI R5_REG))
1982 (clobber (reg:SI T_MEDIA_REG))
1983 (clobber (reg:SI PR_MEDIA_REG))
1984 (clobber (reg:SI R1_REG))
1985 (clobber (reg:SI R21_REG))
1986 (clobber (reg:SI TR0_REG))
1987 (clobber (reg:SI R20_REG))
1988 (use (unspec:SI [(match_dup 1)
1989 (match_operand:SI 3 "" "")
1990 (unspec:SI [(match_operand:SI 4 "" "")
1992 (match_operand:DI 5 "" "")]
1994 (match_operand:DI 6 "" "")
1997 UNSPEC_DIV_INV_M3))]
2000 "&& (high_life_started || reload_completed)"
2004 const char *name = sh_divsi3_libfunc;
2005 enum sh_function_kind kind = SFUNC_GOT;
2008 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2009 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2010 while (TARGET_DIVIDE_INV_CALL2)
2012 rtx x = operands[3];
2014 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2016 x = XVECEXP (x, 0, 0);
2017 name = \"__sdivsi3_2\";
2018 kind = SFUNC_STATIC;
2019 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2022 sym = function_symbol (NULL, name, kind);
2023 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2026 [(set_attr "highpart" "must_split")])
2028 (define_expand "divsi3_i4_media"
2029 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2030 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2031 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2032 (set (match_operand:SI 0 "register_operand" "=r")
2033 (fix:SI (match_dup 5)))]
2034 "TARGET_SHMEDIA_FPU"
2037 operands[3] = gen_reg_rtx (DFmode);
2038 operands[4] = gen_reg_rtx (DFmode);
2039 operands[5] = gen_reg_rtx (DFmode);
2042 (define_insn "divsi3_i4"
2043 [(set (match_operand:SI 0 "register_operand" "=y")
2044 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2045 (clobber (reg:SI PR_REG))
2046 (clobber (reg:DF DR0_REG))
2047 (clobber (reg:DF DR2_REG))
2048 (use (reg:PSI FPSCR_REG))
2049 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2050 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2052 [(set_attr "type" "sfunc")
2053 (set_attr "fp_mode" "double")
2054 (set_attr "needs_delay_slot" "yes")])
2056 (define_insn "divsi3_i4_single"
2057 [(set (match_operand:SI 0 "register_operand" "=y")
2058 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2059 (clobber (reg:SI PR_REG))
2060 (clobber (reg:DF DR0_REG))
2061 (clobber (reg:DF DR2_REG))
2062 (clobber (reg:SI R2_REG))
2063 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2064 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2066 [(set_attr "type" "sfunc")
2067 (set_attr "needs_delay_slot" "yes")])
2069 (define_insn "divsi3_i4_int"
2070 [(set (match_operand:SI 0 "register_operand" "=z")
2071 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2072 (clobber (reg:SI T_REG))
2073 (clobber (reg:SI PR_REG))
2074 (clobber (reg:SI R1_REG))
2075 (clobber (reg:SI MACH_REG))
2076 (clobber (reg:SI MACL_REG))
2077 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2080 [(set_attr "type" "sfunc")
2081 (set_attr "needs_delay_slot" "yes")])
2083 (define_expand "divsi3"
2084 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2085 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2086 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2087 (parallel [(set (match_operand:SI 0 "register_operand" "")
2088 (div:SI (reg:SI R4_REG)
2090 (clobber (reg:SI T_REG))
2091 (clobber (reg:SI PR_REG))
2092 (clobber (reg:SI R1_REG))
2093 (clobber (reg:SI R2_REG))
2094 (clobber (reg:SI R3_REG))
2095 (use (match_dup 3))])]
2101 operands[3] = gen_reg_rtx (Pmode);
2102 /* Emit the move of the address to a pseudo outside of the libcall. */
2103 if (TARGET_DIVIDE_CALL_TABLE)
2105 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2106 last = gen_divsi3_i4_int (operands[0], operands[3]);
2108 else if (TARGET_DIVIDE_CALL_FP)
2110 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2111 if (TARGET_FPU_SINGLE)
2112 last = gen_divsi3_i4_single (operands[0], operands[3]);
2114 last = gen_divsi3_i4 (operands[0], operands[3]);
2116 else if (TARGET_SH2A)
2118 operands[1] = force_reg (SImode, operands[1]);
2119 operands[2] = force_reg (SImode, operands[2]);
2120 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2123 else if (TARGET_DIVIDE_INV)
2125 rtx dividend = operands[1];
2126 rtx divisor = operands[2];
2128 rtx nsb_res = gen_reg_rtx (DImode);
2129 rtx norm64 = gen_reg_rtx (DImode);
2130 rtx tab_ix = gen_reg_rtx (DImode);
2131 rtx norm32 = gen_reg_rtx (SImode);
2132 rtx i92 = force_reg (DImode, GEN_INT (92));
2133 rtx scratch0a = gen_reg_rtx (DImode);
2134 rtx scratch0b = gen_reg_rtx (DImode);
2135 rtx inv0 = gen_reg_rtx (SImode);
2136 rtx scratch1a = gen_reg_rtx (DImode);
2137 rtx scratch1b = gen_reg_rtx (DImode);
2138 rtx shift = gen_reg_rtx (DImode);
2140 rtx inv1 = gen_reg_rtx (SImode);
2141 rtx scratch2a = gen_reg_rtx (DImode);
2142 rtx scratch2b = gen_reg_rtx (SImode);
2143 rtx inv2 = gen_reg_rtx (SImode);
2144 rtx scratch3a = gen_reg_rtx (DImode);
2145 rtx scratch3b = gen_reg_rtx (DImode);
2146 rtx scratch3c = gen_reg_rtx (DImode);
2147 rtx scratch3d = gen_reg_rtx (SImode);
2148 rtx scratch3e = gen_reg_rtx (DImode);
2149 rtx result = gen_reg_rtx (SImode);
2151 if (! arith_reg_or_0_operand (dividend, SImode))
2152 dividend = force_reg (SImode, dividend);
2153 if (! arith_reg_operand (divisor, SImode))
2154 divisor = force_reg (SImode, divisor);
2155 if (flag_pic && Pmode != DImode)
2157 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2158 tab_base = gen_datalabel_ref (tab_base);
2159 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2163 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2164 tab_base = gen_datalabel_ref (tab_base);
2165 tab_base = force_reg (DImode, tab_base);
2167 if (TARGET_DIVIDE_INV20U)
2168 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2170 i2p27 = GEN_INT (0);
2171 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2172 i43 = force_reg (DImode, GEN_INT (43));
2175 emit_insn (gen_nsbdi (nsb_res,
2176 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2177 emit_insn (gen_ashldi3_media (norm64,
2178 gen_rtx_SUBREG (DImode, divisor, 0),
2180 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2181 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2182 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2183 inv0, scratch0a, scratch0b,
2184 scratch1a, scratch1b));
2185 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2186 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2188 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2190 scratch3a, scratch3b, scratch3c,
2191 scratch2a, scratch2b, scratch3d, scratch3e));
2192 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2193 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2194 else if (TARGET_DIVIDE_INV_FP)
2195 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2196 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2197 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2198 gen_reg_rtx (DFmode)));
2200 emit_move_insn (operands[0], result);
2203 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2205 operands[1] = force_reg (SImode, operands[1]);
2206 operands[2] = force_reg (SImode, operands[2]);
2207 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2210 else if (TARGET_SH5)
2212 if (TARGET_DIVIDE_CALL2)
2214 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2215 tab_base = gen_datalabel_ref (tab_base);
2216 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2218 if (TARGET_FPU_ANY && TARGET_SH1)
2219 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2220 else if (TARGET_DIVIDE_CALL2)
2221 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2223 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2226 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2227 (operands[0], operands[3]));
2228 else if (TARGET_FPU_ANY)
2229 last = gen_divsi3_i4_single (operands[0], operands[3]);
2231 last = gen_divsi3_i1 (operands[0], operands[3]);
2235 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2236 last = gen_divsi3_i1 (operands[0], operands[3]);
2238 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2239 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2240 last = emit_insn (last);
2241 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2242 invariant code motion can move it. */
2243 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2244 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2248 ;; operands: scratch, tab_base, tab_ix
2249 ;; These are unspecs because we could generate an indexed addressing mode
2250 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2251 ;; confuse reload. See PR27117.
2253 (define_insn "divsi_inv_qitable"
2254 [(set (match_operand:DI 0 "register_operand" "=r")
2255 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2256 (match_operand:DI 2 "register_operand" "r")]
2257 UNSPEC_DIV_INV_TABLE)))]
2261 [(set_attr "type" "load_media")
2262 (set_attr "highpart" "user")])
2264 ;; operands: scratch, tab_base, tab_ix
2265 (define_insn "divsi_inv_hitable"
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2268 (match_operand:DI 2 "register_operand" "r")]
2269 UNSPEC_DIV_INV_TABLE)))]
2273 [(set_attr "type" "load_media")
2274 (set_attr "highpart" "user")])
2276 ;; operands: inv0, tab_base, tab_ix, norm32
2277 ;; scratch equiv in sdivsi3_2: r19, r21
2278 (define_expand "divsi_inv_m0"
2279 [(set (match_operand:SI 0 "register_operand" "=r")
2280 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2281 (match_operand:DI 2 "register_operand" "r")
2282 (match_operand:SI 3 "register_operand" "r")]
2284 (clobber (match_operand:DI 4 "register_operand" "=r"))
2285 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2293 ldx.ub r20, r21, r19 // u0.8
2295 muls.l r25, r19, r19 // s2.38
2296 ldx.w r20, r21, r21 // s2.14
2297 shari r19, 24, r19 // truncate to s2.14
2298 sub r21, r19, r19 // some 11 bit inverse in s1.14
2301 rtx inv0 = operands[0];
2302 rtx tab_base = operands[1];
2303 rtx tab_ix = operands[2];
2304 rtx norm32 = operands[3];
2305 rtx scratch0 = operands[4];
2306 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2307 rtx scratch1 = operands[5];
2309 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2310 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2311 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2312 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2313 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2314 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2318 ;; operands: inv1, tab_base, tab_ix, norm32
2319 (define_insn_and_split "divsi_inv_m1"
2320 [(set (match_operand:SI 0 "register_operand" "=r")
2321 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2322 (match_operand:DI 2 "register_operand" "r")
2323 (match_operand:SI 3 "register_operand" "r")]
2325 (clobber (match_operand:SI 4 "register_operand" "=r"))
2326 (clobber (match_operand:DI 5 "register_operand" "=r"))
2327 (clobber (match_operand:DI 6 "register_operand" "=r"))
2328 (clobber (match_operand:DI 7 "register_operand" "=r"))
2329 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2337 muls.l r19, r19, r18 // u0.28
2338 muls.l r25, r18, r18 // s2.58
2339 shlli r19, 45, r0 // multiply by two and convert to s2.58
2341 shari r18, 28, r18 // some 18 bit inverse in s1.30
2344 rtx inv1 = operands[0];
2345 rtx tab_base = operands[1];
2346 rtx tab_ix = operands[2];
2347 rtx norm32 = operands[3];
2348 rtx inv0 = operands[4];
2349 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2350 rtx scratch0a = operands[5];
2351 rtx scratch0b = operands[6];
2352 rtx scratch0 = operands[7];
2353 rtx scratch1 = operands[8];
2354 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2356 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2357 scratch0a, scratch0b));
2358 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2359 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2360 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2361 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2362 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2366 ;; operands: inv2, norm32, inv1, i92
2367 (define_insn_and_split "divsi_inv_m2"
2368 [(set (match_operand:SI 0 "register_operand" "=r")
2369 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2370 (match_operand:SI 2 "register_operand" "r")
2371 (match_operand:DI 3 "register_operand" "r")]
2373 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2381 muls.l r18, r25, r0 // s2.60
2382 shari r0, 16, r0 // s-16.44
2384 muls.l r0, r18, r19 // s-16.74
2385 shari r19, 30, r19 // s-16.44
2387 rtx inv2 = operands[0];
2388 rtx norm32 = operands[1];
2389 rtx inv1 = operands[2];
2390 rtx i92 = operands[3];
2391 rtx scratch0 = operands[4];
2392 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2394 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2395 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2396 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2397 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2398 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2402 (define_insn_and_split "divsi_inv_m3"
2403 [(set (match_operand:SI 0 "register_operand" "=r")
2404 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2405 (match_operand:SI 2 "register_operand" "r")
2406 (match_operand:SI 3 "register_operand" "r")
2407 (match_operand:DI 4 "register_operand" "r")
2408 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2409 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2411 (clobber (match_operand:DI 7 "register_operand" "=r"))
2412 (clobber (match_operand:DI 8 "register_operand" "=r"))
2413 (clobber (match_operand:DI 9 "register_operand" "=r"))
2414 (clobber (match_operand:DI 10 "register_operand" "=r"))
2415 (clobber (match_operand:SI 11 "register_operand" "=r"))
2416 (clobber (match_operand:SI 12 "register_operand" "=r"))
2417 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2425 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2426 r0: scratch0 r19: scratch1 r21: scratch2
2428 muls.l r18, r4, r25 // s32.30
2429 muls.l r19, r4, r19 // s15.30
2431 shari r19, 14, r19 // s18.-14
2437 rtx result = operands[0];
2438 rtx dividend = operands[1];
2439 rtx inv1 = operands[2];
2440 rtx inv2 = operands[3];
2441 rtx shift = operands[4];
2442 rtx scratch0 = operands[7];
2443 rtx scratch1 = operands[8];
2444 rtx scratch2 = operands[9];
2446 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2447 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2448 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2449 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2450 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2451 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2452 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2456 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2457 ;; inv1: tab_base, tab_ix, norm32
2458 ;; inv2: norm32, inv1, i92
2459 (define_insn_and_split "divsi_inv_m1_3"
2460 [(set (match_operand:SI 0 "register_operand" "=r")
2461 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2462 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2463 (match_operand:DI 3 "register_operand" "r")
2464 (match_operand:SI 4 "register_operand" "r")]
2466 (unspec:SI [(match_dup 4)
2467 (unspec:SI [(match_dup 2)
2469 (match_dup 4)] UNSPEC_DIV_INV_M1)
2470 (match_operand:SI 5 "" "")]
2472 (match_operand:DI 6 "register_operand" "r")
2473 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2474 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2476 (clobber (match_operand:DI 9 "register_operand" "=r"))
2477 (clobber (match_operand:DI 10 "register_operand" "=r"))
2478 (clobber (match_operand:DI 11 "register_operand" "=r"))
2479 (clobber (match_operand:DI 12 "register_operand" "=r"))
2480 (clobber (match_operand:SI 13 "register_operand" "=r"))
2481 (clobber (match_operand:SI 14 "register_operand" "=r"))
2482 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2484 && (TARGET_DIVIDE_INV_MINLAT
2485 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2491 rtx result = operands[0];
2492 rtx dividend = operands[1];
2493 rtx tab_base = operands[2];
2494 rtx tab_ix = operands[3];
2495 rtx norm32 = operands[4];
2496 /* rtx i92 = operands[5]; */
2497 rtx shift = operands[6];
2498 rtx i2p27 = operands[7];
2499 rtx i43 = operands[8];
2500 rtx scratch0 = operands[9];
2501 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2502 rtx scratch1 = operands[10];
2503 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2504 rtx scratch2 = operands[11];
2505 rtx scratch3 = operands[12];
2506 rtx scratch4 = operands[13];
2507 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2508 rtx scratch5 = operands[14];
2509 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2510 rtx scratch6 = operands[15];
2512 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2513 scratch0, scratch1));
2514 /* inv0 == scratch4 */
2515 if (! TARGET_DIVIDE_INV20U)
2517 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2519 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2523 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2524 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2526 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2527 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2528 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2529 /* inv1 == scratch4 */
2531 if (TARGET_DIVIDE_INV_MINLAT)
2533 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2534 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2535 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2536 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2537 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2538 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2539 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2540 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2541 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2542 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2543 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2547 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2548 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2549 emit_insn (gen_nsbdi (scratch6,
2550 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2551 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2552 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2553 emit_insn (gen_divsi_inv20 (scratch2,
2554 norm32, scratch4, dividend,
2555 scratch6, scratch3, i43,
2556 /* scratch0 may be shared with i2p27. */
2557 scratch0, scratch1, scratch5,
2558 label, label, i2p27));
2560 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2561 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2565 (define_insn "divsi_inv20"
2566 [(set (match_operand:DI 0 "register_operand" "=&r")
2567 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2568 (match_operand:SI 2 "register_operand" "r")
2569 (match_operand:SI 3 "register_operand" "r")
2570 (match_operand:DI 4 "register_operand" "r")
2571 (match_operand:DI 5 "register_operand" "r")
2572 (match_operand:DI 6 "register_operand" "r")
2573 (match_operand:DI 12 "register_operand" "r")
2574 (match_operand 10 "target_operand" "b")
2575 (match_operand 11 "immediate_operand" "i")]
2577 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2578 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2579 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2581 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2584 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2585 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2586 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2587 %10 label (tr), %11 label (imm)
2589 muls.l inv1, norm32, scratch0 // s2.60
2590 muls.l inv1, dividend, result // s32.30
2591 xor i2p27, result_sign, round_scratch
2592 bge/u dividend_nsb, i43, tr.. (label)
2593 shari scratch0, 16, scratch0 // s-16.44
2594 muls.l sratch0_si, inv1, scratch0 // s-16.74
2595 sub result, round_scratch, result
2596 shari dividend, 14, scratch1 // s19.-14
2597 shari scratch0, 30, scratch0 // s-16.44
2598 muls.l scratch0, scratch1, round_scratch // s15.30
2600 sub result, round_scratch, result */
2602 int likely = TARGET_DIVIDE_INV20L;
2604 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2605 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2606 output_asm_insn (likely
2607 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2608 : \"bge/u\t%4, %6, %10\", operands);
2609 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2610 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2611 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2613 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2614 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2617 (define_insn_and_split "divsi_inv_fp"
2618 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2619 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2620 (match_operand:SI 2 "register_operand" "rf")))
2621 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2622 (clobber (match_operand:SI 4 "register_operand" "=r"))
2623 (clobber (match_operand:SI 5 "register_operand" "=r"))
2624 (clobber (match_operand:DF 6 "register_operand" "=r"))
2625 (clobber (match_operand:DF 7 "register_operand" "=r"))
2626 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2627 "TARGET_SHMEDIA_FPU"
2629 "&& (high_life_started || reload_completed)"
2630 [(set (match_dup 0) (match_dup 3))]
2632 [(set_attr "highpart" "must_split")])
2634 ;; If a matching group of divide-by-inverse instructions is in the same
2635 ;; basic block after gcse & loop optimizations, we want to transform them
2636 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2637 (define_insn_and_split "*divsi_inv_fp_combine"
2638 [(set (match_operand:SI 0 "register_operand" "=f")
2639 (div:SI (match_operand:SI 1 "register_operand" "f")
2640 (match_operand:SI 2 "register_operand" "f")))
2641 (use (unspec:SI [(match_dup 1)
2642 (match_operand:SI 3 "" "")
2643 (unspec:SI [(match_operand:SI 4 "" "")
2645 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2646 (match_operand:DI 6 "" "")
2648 (const_int 0)] UNSPEC_DIV_INV_M3))
2649 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2650 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2651 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2652 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2653 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2654 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2657 [(set (match_dup 9) (float:DF (match_dup 1)))
2658 (set (match_dup 10) (float:DF (match_dup 2)))
2659 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2661 (fix:SI (match_dup 11)))
2662 (set (match_dup 0) (match_dup 8))]
2665 if (! fp_arith_reg_operand (operands[1], SImode))
2667 emit_move_insn (operands[7], operands[1]);
2668 operands[1] = operands[7];
2670 if (! fp_arith_reg_operand (operands[2], SImode))
2672 emit_move_insn (operands[8], operands[2]);
2673 operands[2] = operands[8];
2676 [(set_attr "highpart" "must_split")])
2678 ;; -------------------------------------------------------------------------
2679 ;; Multiplication instructions
2680 ;; -------------------------------------------------------------------------
2682 (define_insn "umulhisi3_i"
2683 [(set (reg:SI MACL_REG)
2684 (mult:SI (zero_extend:SI
2685 (match_operand:HI 0 "arith_reg_operand" "r"))
2687 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2690 [(set_attr "type" "smpy")])
2692 (define_insn "mulhisi3_i"
2693 [(set (reg:SI MACL_REG)
2694 (mult:SI (sign_extend:SI
2695 (match_operand:HI 0 "arith_reg_operand" "r"))
2697 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2700 [(set_attr "type" "smpy")])
2702 (define_expand "mulhisi3"
2703 [(set (reg:SI MACL_REG)
2704 (mult:SI (sign_extend:SI
2705 (match_operand:HI 1 "arith_reg_operand" ""))
2707 (match_operand:HI 2 "arith_reg_operand" ""))))
2708 (set (match_operand:SI 0 "arith_reg_operand" "")
2715 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2716 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2717 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2718 invariant code motion can move it. */
2719 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2720 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2721 /* expand_binop can't find a suitable code in umul_widen_optab to
2722 make a REG_EQUAL note from, so make one here.
2723 See also smulsi3_highpart.
2724 ??? Alternatively, we could put this at the calling site of expand_binop,
2725 i.e. expand_expr. */
2727 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2732 (define_expand "umulhisi3"
2733 [(set (reg:SI MACL_REG)
2734 (mult:SI (zero_extend:SI
2735 (match_operand:HI 1 "arith_reg_operand" ""))
2737 (match_operand:HI 2 "arith_reg_operand" ""))))
2738 (set (match_operand:SI 0 "arith_reg_operand" "")
2745 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2746 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2747 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2748 invariant code motion can move it. */
2749 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2750 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2751 /* expand_binop can't find a suitable code in umul_widen_optab to
2752 make a REG_EQUAL note from, so make one here.
2753 See also smulsi3_highpart.
2754 ??? Alternatively, we could put this at the calling site of expand_binop,
2755 i.e. expand_expr. */
2757 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2762 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2763 ;; a call to a routine which clobbers known registers.
2766 [(set (match_operand:SI 1 "register_operand" "=z")
2767 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2768 (clobber (reg:SI MACL_REG))
2769 (clobber (reg:SI T_REG))
2770 (clobber (reg:SI PR_REG))
2771 (clobber (reg:SI R3_REG))
2772 (clobber (reg:SI R2_REG))
2773 (clobber (reg:SI R1_REG))
2774 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2777 [(set_attr "type" "sfunc")
2778 (set_attr "needs_delay_slot" "yes")])
2780 (define_expand "mulsi3_call"
2781 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2782 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2783 (parallel[(set (match_operand:SI 0 "register_operand" "")
2784 (mult:SI (reg:SI R4_REG)
2786 (clobber (reg:SI MACL_REG))
2787 (clobber (reg:SI T_REG))
2788 (clobber (reg:SI PR_REG))
2789 (clobber (reg:SI R3_REG))
2790 (clobber (reg:SI R2_REG))
2791 (clobber (reg:SI R1_REG))
2792 (use (match_operand:SI 3 "register_operand" ""))])]
2796 (define_insn "mul_r"
2797 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2798 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2799 (match_operand:SI 2 "arith_reg_operand" "z")))]
2802 [(set_attr "type" "dmpy")])
2804 (define_insn "mul_l"
2805 [(set (reg:SI MACL_REG)
2806 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2807 (match_operand:SI 1 "arith_reg_operand" "r")))]
2810 [(set_attr "type" "dmpy")])
2812 (define_expand "mulsi3"
2813 [(set (reg:SI MACL_REG)
2814 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2815 (match_operand:SI 2 "arith_reg_operand" "")))
2816 (set (match_operand:SI 0 "arith_reg_operand" "")
2825 /* The address must be set outside the libcall,
2826 since it goes into a pseudo. */
2827 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2828 rtx addr = force_reg (SImode, sym);
2829 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2832 last = emit_insn (insns);
2836 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2838 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2839 /* consec_sets_giv can only recognize the first insn that sets a
2840 giv as the giv insn. So we must tag this also with a REG_EQUAL
2842 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2844 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2845 invariant code motion can move it. */
2846 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2847 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2851 (define_insn "mulsidi3_i"
2852 [(set (reg:SI MACH_REG)
2856 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2857 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2859 (set (reg:SI MACL_REG)
2860 (mult:SI (match_dup 0)
2864 [(set_attr "type" "dmpy")])
2866 (define_expand "mulsidi3"
2867 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2868 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2869 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2870 "TARGET_SH2 || TARGET_SHMEDIA"
2875 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2881 (define_insn "mulsidi3_media"
2882 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2883 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2884 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2887 [(set_attr "type" "dmpy_media")
2888 (set_attr "highpart" "ignore")])
2890 (define_insn "mulsidi3_compact"
2891 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2893 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2894 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2895 (clobber (reg:SI MACH_REG))
2896 (clobber (reg:SI MACL_REG))]
2901 [(set (match_operand:DI 0 "arith_reg_dest" "")
2903 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2904 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2905 (clobber (reg:SI MACH_REG))
2906 (clobber (reg:SI MACL_REG))]
2911 rtx low_dst = gen_lowpart (SImode, operands[0]);
2912 rtx high_dst = gen_highpart (SImode, operands[0]);
2914 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2916 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2917 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2918 /* We need something to tag the possible REG_EQUAL notes on to. */
2919 emit_move_insn (operands[0], operands[0]);
2923 (define_insn "umulsidi3_i"
2924 [(set (reg:SI MACH_REG)
2928 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2929 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2931 (set (reg:SI MACL_REG)
2932 (mult:SI (match_dup 0)
2936 [(set_attr "type" "dmpy")])
2938 (define_expand "umulsidi3"
2939 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2940 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2941 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2942 "TARGET_SH2 || TARGET_SHMEDIA"
2947 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2953 (define_insn "umulsidi3_media"
2954 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2955 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2956 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2959 [(set_attr "type" "dmpy_media")
2960 (set_attr "highpart" "ignore")])
2962 (define_insn "umulsidi3_compact"
2963 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2965 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2966 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2967 (clobber (reg:SI MACH_REG))
2968 (clobber (reg:SI MACL_REG))]
2973 [(set (match_operand:DI 0 "arith_reg_dest" "")
2974 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2975 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2976 (clobber (reg:SI MACH_REG))
2977 (clobber (reg:SI MACL_REG))]
2982 rtx low_dst = gen_lowpart (SImode, operands[0]);
2983 rtx high_dst = gen_highpart (SImode, operands[0]);
2985 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2987 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2988 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2989 /* We need something to tag the possible REG_EQUAL notes on to. */
2990 emit_move_insn (operands[0], operands[0]);
2994 (define_insn "smulsi3_highpart_i"
2995 [(set (reg:SI MACH_REG)
2999 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3000 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3002 (clobber (reg:SI MACL_REG))]
3005 [(set_attr "type" "dmpy")])
3007 (define_expand "smulsi3_highpart"
3009 [(set (reg:SI MACH_REG)
3013 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3014 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3016 (clobber (reg:SI MACL_REG))])
3017 (set (match_operand:SI 0 "arith_reg_operand" "")
3024 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3025 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3026 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3027 invariant code motion can move it. */
3028 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3029 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3030 /* expand_binop can't find a suitable code in mul_highpart_optab to
3031 make a REG_EQUAL note from, so make one here.
3032 See also {,u}mulhisi.
3033 ??? Alternatively, we could put this at the calling site of expand_binop,
3034 i.e. expand_mult_highpart. */
3036 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
3041 (define_insn "umulsi3_highpart_i"
3042 [(set (reg:SI MACH_REG)
3046 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3047 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3049 (clobber (reg:SI MACL_REG))]
3052 [(set_attr "type" "dmpy")])
3054 (define_expand "umulsi3_highpart"
3056 [(set (reg:SI MACH_REG)
3060 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3061 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3063 (clobber (reg:SI MACL_REG))])
3064 (set (match_operand:SI 0 "arith_reg_operand" "")
3071 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3072 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3073 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3074 invariant code motion can move it. */
3075 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3076 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3080 (define_insn_and_split "muldi3"
3081 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3082 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3083 (match_operand:DI 2 "arith_reg_operand" "r")))
3084 (clobber (match_scratch:DI 3 "=&r"))
3085 (clobber (match_scratch:DI 4 "=r"))]
3092 rtx op3_v2si, op2_v2si;
3094 op3_v2si = operands[3];
3095 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3097 op3_v2si = XEXP (op3_v2si, 0);
3098 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3100 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3101 op2_v2si = operands[2];
3102 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3104 op2_v2si = XEXP (op2_v2si, 0);
3105 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3107 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3108 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3109 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3110 emit_insn (gen_umulsidi3_media (operands[4],
3111 sh_gen_truncate (SImode, operands[1], 0),
3112 sh_gen_truncate (SImode, operands[2], 0)));
3113 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3114 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3115 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3116 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3121 ;; -------------------------------------------------------------------------
3122 ;; Logical operations
3123 ;; -------------------------------------------------------------------------
3125 (define_insn "*andsi3_compact"
3126 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3127 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3128 (match_operand:SI 2 "logical_operand" "r,K08")))]
3131 [(set_attr "type" "arith")])
3133 (define_insn "*andsi3_media"
3134 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3135 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3136 (match_operand:SI 2 "logical_operand" "r,I10")))]
3141 [(set_attr "type" "arith_media")])
3143 ;; If the constant is 255, then emit an extu.b instruction instead of an
3144 ;; and, since that will give better code.
3146 (define_expand "andsi3"
3147 [(set (match_operand:SI 0 "arith_reg_operand" "")
3148 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3149 (match_operand:SI 2 "logical_operand" "")))]
3154 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3156 emit_insn (gen_zero_extendqisi2 (operands[0],
3157 gen_lowpart (QImode, operands[1])));
3162 (define_insn_and_split "anddi3"
3163 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3164 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3165 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3172 && ! logical_operand (operands[2], DImode)"
3176 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3177 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3179 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3182 [(set_attr "type" "arith_media")])
3184 (define_insn "andcsi3"
3185 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3186 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3187 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3190 [(set_attr "type" "arith_media")])
3192 (define_insn "andcdi3"
3193 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3194 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3195 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3198 [(set_attr "type" "arith_media")])
3200 (define_expand "iorsi3"
3201 [(set (match_operand:SI 0 "arith_reg_operand" "")
3202 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3203 (match_operand:SI 2 "logical_operand" "")))]
3207 (define_insn "*iorsi3_compact"
3208 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3209 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3210 (match_operand:SI 2 "logical_operand" "r,K08")))]
3213 [(set_attr "type" "arith")])
3215 (define_insn "*iorsi3_media"
3216 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3217 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3218 (match_operand:SI 2 "logical_operand" "r,I10")))]
3223 [(set_attr "type" "arith_media")])
3225 (define_insn "iordi3"
3226 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3227 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3228 (match_operand:DI 2 "logical_operand" "r,I10")))]
3233 [(set_attr "type" "arith_media")])
3235 (define_insn_and_split "*logical_sidi3"
3236 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3237 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3238 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3239 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3242 "&& reload_completed"
3243 [(set (match_dup 0) (match_dup 3))]
3247 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3248 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3249 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3252 (define_insn_and_split "*logical_sidisi3"
3253 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3254 (truncate:SI (sign_extend:DI
3255 (match_operator:SI 3 "logical_operator"
3256 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3257 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3261 [(set (match_dup 0) (match_dup 3))])
3263 (define_insn_and_split "*logical_sidi3_2"
3264 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3265 (sign_extend:DI (truncate:SI (sign_extend:DI
3266 (match_operator:SI 3 "logical_operator"
3267 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3268 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3272 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3274 (define_expand "xorsi3"
3275 [(set (match_operand:SI 0 "arith_reg_operand" "")
3276 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3277 (match_operand:SI 2 "xor_operand" "")))]
3281 (define_insn "*xorsi3_compact"
3282 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3283 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3284 (match_operand:SI 2 "logical_operand" "K08,r")))]
3287 [(set_attr "type" "arith")])
3289 (define_insn "*xorsi3_media"
3290 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3291 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3292 (match_operand:SI 2 "xor_operand" "r,I06")))]
3297 [(set_attr "type" "arith_media")])
3299 (define_insn "xordi3"
3300 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3301 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3302 (match_operand:DI 2 "xor_operand" "r,I06")))]
3307 [(set_attr "type" "arith_media")])
3309 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3310 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3312 [(set (match_operand:DI 0 "arith_reg_dest" "")
3313 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3314 [(match_operand 1 "any_register_operand" "")
3315 (match_operand 2 "any_register_operand" "")])))]
3317 [(set (match_dup 5) (match_dup 4))
3318 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3321 enum machine_mode inmode = GET_MODE (operands[1]);
3324 if (GET_CODE (operands[0]) == SUBREG)
3326 offset = SUBREG_BYTE (operands[0]);
3327 operands[0] = SUBREG_REG (operands[0]);
3329 gcc_assert (GET_CODE (operands[0]) == REG);
3330 if (! TARGET_LITTLE_ENDIAN)
3331 offset += 8 - GET_MODE_SIZE (inmode);
3332 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3335 ;; -------------------------------------------------------------------------
3336 ;; Shifts and rotates
3337 ;; -------------------------------------------------------------------------
3339 (define_expand "rotldi3"
3340 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3341 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3342 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3344 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3346 (define_insn "rotldi3_mextr"
3347 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3348 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3349 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3353 static char templ[16];
3355 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3356 8 - (int) (INTVAL (operands[2]) >> 3));
3359 [(set_attr "type" "arith_media")])
3361 (define_expand "rotrdi3"
3362 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3363 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3364 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3366 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3368 (define_insn "rotrdi3_mextr"
3369 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3370 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3371 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3375 static char templ[16];
3377 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3380 [(set_attr "type" "arith_media")])
3383 [(set (match_operand:DI 0 "arith_reg_dest" "")
3384 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3385 "ua_address_operand" "")))
3386 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3388 (clobber (match_operand:DI 3 "register_operand" ""))]
3390 [(match_dup 4) (match_dup 5)]
3393 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3394 (operands[3], operands[1]));
3395 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3396 GEN_INT (56), GEN_INT (8));
3399 (define_insn "rotlsi3_1"
3400 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3401 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3404 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3407 [(set_attr "type" "arith")])
3409 (define_insn "rotlsi3_31"
3410 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3411 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3413 (clobber (reg:SI T_REG))]
3416 [(set_attr "type" "arith")])
3418 (define_insn "rotlsi3_16"
3419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3420 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3424 [(set_attr "type" "arith")])
3426 (define_expand "rotlsi3"
3427 [(set (match_operand:SI 0 "arith_reg_dest" "")
3428 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3429 (match_operand:SI 2 "immediate_operand" "")))]
3433 static const char rot_tab[] = {
3434 000, 000, 000, 000, 000, 000, 010, 001,
3435 001, 001, 011, 013, 003, 003, 003, 003,
3436 003, 003, 003, 003, 003, 013, 012, 002,
3437 002, 002, 010, 000, 000, 000, 000, 000,
3442 if (GET_CODE (operands[2]) != CONST_INT)
3444 count = INTVAL (operands[2]);
3445 choice = rot_tab[count];
3446 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3452 emit_move_insn (operands[0], operands[1]);
3453 count -= (count & 16) * 2;
3456 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3463 parts[0] = gen_reg_rtx (SImode);
3464 parts[1] = gen_reg_rtx (SImode);
3465 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3466 emit_move_insn (parts[choice-1], operands[1]);
3467 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3468 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3469 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3470 count = (count & ~16) - 8;
3474 for (; count > 0; count--)
3475 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3476 for (; count < 0; count++)
3477 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3482 (define_insn "*rotlhi3_8"
3483 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3484 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3488 [(set_attr "type" "arith")])
3490 (define_expand "rotlhi3"
3491 [(set (match_operand:HI 0 "arith_reg_operand" "")
3492 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3493 (match_operand:HI 2 "immediate_operand" "")))]
3497 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3504 (define_insn "ashlsi3_sh2a"
3505 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3506 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3507 (match_operand:SI 2 "arith_reg_operand" "r")))]
3510 [(set_attr "type" "arith")
3511 (set_attr "length" "4")])
3513 ;; This pattern is used by init_expmed for computing the costs of shift
3516 (define_insn_and_split "ashlsi3_std"
3517 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3518 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3519 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3520 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3522 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3523 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3531 && GET_CODE (operands[2]) == CONST_INT
3532 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3533 [(set (match_dup 3) (match_dup 2))
3535 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3536 (clobber (match_dup 4))])]
3537 "operands[4] = gen_rtx_SCRATCH (SImode);"
3538 [(set_attr "length" "*,*,*,4")
3539 (set_attr "type" "dyn_shift,arith,arith,arith")])
3541 (define_insn "ashlhi3_k"
3542 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3543 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3544 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3545 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3549 [(set_attr "type" "arith")])
3551 (define_insn "ashlsi3_n"
3552 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3553 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3554 (match_operand:SI 2 "const_int_operand" "n")))
3555 (clobber (reg:SI T_REG))]
3556 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3558 [(set (attr "length")
3559 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3561 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3563 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3565 (const_string "8")))
3566 (set_attr "type" "arith")])
3569 [(set (match_operand:SI 0 "arith_reg_dest" "")
3570 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3571 (match_operand:SI 2 "const_int_operand" "")))
3572 (clobber (reg:SI T_REG))]
3573 "TARGET_SH1 && reload_completed"
3574 [(use (reg:SI R0_REG))]
3577 gen_shifty_op (ASHIFT, operands);
3581 (define_insn "ashlsi3_media"
3582 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3583 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3584 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3589 [(set_attr "type" "arith_media")
3590 (set_attr "highpart" "ignore")])
3592 (define_expand "ashlsi3"
3593 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3594 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3595 (match_operand:SI 2 "nonmemory_operand" "")))
3596 (clobber (reg:SI T_REG))])]
3602 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3605 if (GET_CODE (operands[2]) == CONST_INT
3606 && sh_dynamicalize_shift_p (operands[2]))
3607 operands[2] = force_reg (SImode, operands[2]);
3610 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3613 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3617 (define_insn "*ashlhi3_n"
3618 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3619 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3620 (match_operand:HI 2 "const_int_operand" "n")))
3621 (clobber (reg:SI T_REG))]
3624 [(set (attr "length")
3625 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3627 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3629 (const_string "6")))
3630 (set_attr "type" "arith")])
3632 (define_expand "ashlhi3"
3633 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3634 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3635 (match_operand:SI 2 "nonmemory_operand" "")))
3636 (clobber (reg:SI T_REG))])]
3640 if (GET_CODE (operands[2]) != CONST_INT)
3642 /* It may be possible to call gen_ashlhi3 directly with more generic
3643 operands. Make sure operands[1] is a HImode register here. */
3644 if (!arith_reg_operand (operands[1], HImode))
3645 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3649 [(set (match_operand:HI 0 "arith_reg_dest" "")
3650 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3651 (match_operand:HI 2 "const_int_operand" "")))
3652 (clobber (reg:SI T_REG))]
3653 "TARGET_SH1 && reload_completed"
3654 [(use (reg:SI R0_REG))]
3657 gen_shifty_hi_op (ASHIFT, operands);
3662 ; arithmetic shift right
3665 (define_insn "ashrsi3_sh2a"
3666 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3667 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3668 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3671 [(set_attr "type" "dyn_shift")
3672 (set_attr "length" "4")])
3674 (define_insn "ashrsi3_k"
3675 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3676 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3677 (match_operand:SI 2 "const_int_operand" "M")))
3678 (clobber (reg:SI T_REG))]
3679 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3681 [(set_attr "type" "arith")])
3683 ;; We can't do HImode right shifts correctly unless we start out with an
3684 ;; explicit zero / sign extension; doing that would result in worse overall
3685 ;; code, so just let the machine independent code widen the mode.
3686 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3689 ;; ??? This should be a define expand.
3691 (define_insn "ashrsi2_16"
3692 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3693 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3697 [(set_attr "length" "4")])
3700 [(set (match_operand:SI 0 "arith_reg_dest" "")
3701 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3704 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3705 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3706 "operands[2] = gen_lowpart (HImode, operands[0]);")
3708 ;; ??? This should be a define expand.
3710 (define_insn "ashrsi2_31"
3711 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3712 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3714 (clobber (reg:SI T_REG))]
3717 [(set_attr "length" "4")])
3720 [(set (match_operand:SI 0 "arith_reg_dest" "")
3721 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3723 (clobber (reg:SI T_REG))]
3728 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3729 emit_insn (gen_mov_neg_si_t (operands[0]));
3734 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3736 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3738 && peep2_reg_dead_p (2, operands[0])
3739 && peep2_reg_dead_p (2, operands[1])"
3743 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3747 (define_insn "ashlsi_c"
3748 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3749 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3751 (lt:SI (match_dup 1) (const_int 0)))]
3754 [(set_attr "type" "arith")])
3756 (define_insn "*ashlsi_c_void"
3757 [(set (reg:SI T_REG)
3758 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3759 (clobber (match_scratch:SI 1 "=0"))]
3760 "TARGET_SH1 && cse_not_expected"
3762 [(set_attr "type" "arith")])
3764 (define_insn "ashrsi3_d"
3765 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3770 [(set_attr "type" "dyn_shift")])
3772 (define_insn "ashrsi3_n"
3773 [(set (reg:SI R4_REG)
3774 (ashiftrt:SI (reg:SI R4_REG)
3775 (match_operand:SI 0 "const_int_operand" "i")))
3776 (clobber (reg:SI T_REG))
3777 (clobber (reg:SI PR_REG))
3778 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3781 [(set_attr "type" "sfunc")
3782 (set_attr "needs_delay_slot" "yes")])
3784 (define_insn "ashrsi3_media"
3785 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3786 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3787 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3792 [(set_attr "type" "arith_media")
3793 (set_attr "highpart" "ignore")])
3795 (define_expand "ashrsi3"
3796 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3797 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3798 (match_operand:SI 2 "nonmemory_operand" "")))
3799 (clobber (reg:SI T_REG))])]
3805 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3808 if (expand_ashiftrt (operands))
3814 ;; logical shift right
3816 (define_insn "lshrsi3_sh2a"
3817 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3818 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3819 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3822 [(set_attr "type" "dyn_shift")
3823 (set_attr "length" "4")])
3825 (define_insn "lshrsi3_d"
3826 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3827 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3828 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3831 [(set_attr "type" "dyn_shift")])
3833 ;; Only the single bit shift clobbers the T bit.
3835 (define_insn "lshrsi3_m"
3836 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3837 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3838 (match_operand:SI 2 "const_int_operand" "M")))
3839 (clobber (reg:SI T_REG))]
3840 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3842 [(set_attr "type" "arith")])
3844 (define_insn "lshrsi3_k"
3845 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3846 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3847 (match_operand:SI 2 "const_int_operand" "P27")))]
3848 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3849 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3851 [(set_attr "type" "arith")])
3853 (define_insn "lshrsi3_n"
3854 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3855 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3856 (match_operand:SI 2 "const_int_operand" "n")))
3857 (clobber (reg:SI T_REG))]
3858 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3860 [(set (attr "length")
3861 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3863 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3865 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3867 (const_string "8")))
3868 (set_attr "type" "arith")])
3871 [(set (match_operand:SI 0 "arith_reg_dest" "")
3872 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3873 (match_operand:SI 2 "const_int_operand" "")))
3874 (clobber (reg:SI T_REG))]
3875 "TARGET_SH1 && reload_completed"
3876 [(use (reg:SI R0_REG))]
3879 gen_shifty_op (LSHIFTRT, operands);
3883 (define_insn "lshrsi3_media"
3884 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3885 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3886 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3891 [(set_attr "type" "arith_media")
3892 (set_attr "highpart" "ignore")])
3894 (define_expand "lshrsi3"
3895 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3896 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3897 (match_operand:SI 2 "nonmemory_operand" "")))
3898 (clobber (reg:SI T_REG))])]
3904 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3907 if (GET_CODE (operands[2]) == CONST_INT
3908 && sh_dynamicalize_shift_p (operands[2]))
3909 operands[2] = force_reg (SImode, operands[2]);
3910 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3912 rtx count = copy_to_mode_reg (SImode, operands[2]);
3913 emit_insn (gen_negsi2 (count, count));
3914 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3917 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3921 ;; ??? This should be a define expand.
3923 (define_insn "ashldi3_k"
3924 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3925 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3927 (clobber (reg:SI T_REG))]
3929 "shll %R0\;rotcl %S0"
3930 [(set_attr "length" "4")
3931 (set_attr "type" "arith")])
3933 (define_insn "ashldi3_media"
3934 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3935 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3936 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3941 [(set_attr "type" "arith_media")])
3943 (define_insn "*ashldisi3_media"
3944 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3945 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3946 (match_operand:DI 2 "const_int_operand" "n")))]
3947 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3948 "shlli.l %1, %2, %0"
3949 [(set_attr "type" "arith_media")
3950 (set_attr "highpart" "ignore")])
3952 (define_expand "ashldi3"
3953 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3954 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3955 (match_operand:DI 2 "immediate_operand" "")))
3956 (clobber (reg:SI T_REG))])]
3962 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3965 if (GET_CODE (operands[2]) != CONST_INT
3966 || INTVAL (operands[2]) != 1)
3970 ;; ??? This should be a define expand.
3972 (define_insn "lshrdi3_k"
3973 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3974 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3976 (clobber (reg:SI T_REG))]
3978 "shlr %S0\;rotcr %R0"
3979 [(set_attr "length" "4")
3980 (set_attr "type" "arith")])
3982 (define_insn "lshrdi3_media"
3983 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3984 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3985 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3987 && (arith_reg_dest (operands[0], DImode)
3988 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3992 [(set_attr "type" "arith_media")])
3994 (define_insn "*lshrdisi3_media"
3995 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3996 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3997 (match_operand:DI 2 "const_int_operand" "n")))]
3998 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3999 "shlri.l %1, %2, %0"
4000 [(set_attr "type" "arith_media")
4001 (set_attr "highpart" "ignore")])
4003 (define_expand "lshrdi3"
4004 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4005 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4006 (match_operand:DI 2 "immediate_operand" "")))
4007 (clobber (reg:SI T_REG))])]
4013 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4016 if (GET_CODE (operands[2]) != CONST_INT
4017 || INTVAL (operands[2]) != 1)
4021 ;; ??? This should be a define expand.
4023 (define_insn "ashrdi3_k"
4024 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4025 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4027 (clobber (reg:SI T_REG))]
4029 "shar %S0\;rotcr %R0"
4030 [(set_attr "length" "4")
4031 (set_attr "type" "arith")])
4033 (define_insn "ashrdi3_media"
4034 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4035 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4036 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4038 && (arith_reg_dest (operands[0], DImode)
4039 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4043 [(set_attr "type" "arith_media")])
4045 (define_insn "*ashrdisi3_media"
4046 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4047 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4048 (match_operand:DI 2 "const_int_operand" "n")))]
4049 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4050 "shari.l %1, %2, %0"
4051 [(set_attr "type" "arith_media")
4052 (set_attr "highpart" "ignore")])
4054 (define_insn "ashrdisi3_media_high"
4055 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4057 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4058 (match_operand:DI 2 "const_int_operand" "n"))))]
4059 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4061 [(set_attr "type" "arith_media")])
4063 (define_insn "ashrdisi3_media_opaque"
4064 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4065 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4066 (match_operand:DI 2 "const_int_operand" "n")]
4070 [(set_attr "type" "arith_media")])
4072 (define_expand "ashrdi3"
4073 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4074 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4075 (match_operand:DI 2 "immediate_operand" "")))
4076 (clobber (reg:SI T_REG))])]
4082 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4085 if (GET_CODE (operands[2]) != CONST_INT
4086 || INTVAL (operands[2]) != 1)
4090 ;; combined left/right shift
4093 [(set (match_operand:SI 0 "register_operand" "")
4094 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4095 (match_operand:SI 2 "const_int_operand" ""))
4096 (match_operand:SI 3 "const_int_operand" "")))]
4097 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4098 [(use (reg:SI R0_REG))]
4099 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4103 [(set (match_operand:SI 0 "register_operand" "")
4104 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4105 (match_operand:SI 2 "const_int_operand" ""))
4106 (match_operand:SI 3 "const_int_operand" "")))
4107 (clobber (reg:SI T_REG))]
4108 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4109 [(use (reg:SI R0_REG))]
4110 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4114 [(set (match_operand:SI 0 "register_operand" "=r")
4115 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4116 (match_operand:SI 2 "const_int_operand" "n"))
4117 (match_operand:SI 3 "const_int_operand" "n")))
4118 (clobber (reg:SI T_REG))]
4119 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4121 [(set (attr "length")
4122 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4124 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4126 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4128 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4130 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4132 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4134 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4135 (const_string "16")]
4136 (const_string "18")))
4137 (set_attr "type" "arith")])
4140 [(set (match_operand:SI 0 "register_operand" "=z")
4141 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4142 (match_operand:SI 2 "const_int_operand" "n"))
4143 (match_operand:SI 3 "const_int_operand" "n")))
4144 (clobber (reg:SI T_REG))]
4145 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4147 [(set (attr "length")
4148 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4150 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4152 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4154 (const_string "10")))
4155 (set_attr "type" "arith")])
4157 ;; shift left / and combination with a scratch register: The combine pass
4158 ;; does not accept the individual instructions, even though they are
4159 ;; cheap. But it needs a precise description so that it is usable after
4161 (define_insn "and_shl_scratch"
4162 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4166 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4167 (match_operand:SI 2 "const_int_operand" "N,n"))
4168 (match_operand:SI 3 "" "0,r"))
4169 (match_operand:SI 4 "const_int_operand" "n,n"))
4170 (match_operand:SI 5 "const_int_operand" "n,n")))
4171 (clobber (reg:SI T_REG))]
4174 [(set (attr "length")
4175 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4177 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4179 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4181 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4182 (const_string "10")]
4183 (const_string "12")))
4184 (set_attr "type" "arith")])
4187 [(set (match_operand:SI 0 "register_operand" "")
4191 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4192 (match_operand:SI 2 "const_int_operand" ""))
4193 (match_operand:SI 3 "register_operand" ""))
4194 (match_operand:SI 4 "const_int_operand" ""))
4195 (match_operand:SI 5 "const_int_operand" "")))
4196 (clobber (reg:SI T_REG))]
4198 [(use (reg:SI R0_REG))]
4201 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4203 if (INTVAL (operands[2]))
4205 gen_shifty_op (LSHIFTRT, operands);
4207 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4208 operands[2] = operands[4];
4209 gen_shifty_op (ASHIFT, operands);
4210 if (INTVAL (operands[5]))
4212 operands[2] = operands[5];
4213 gen_shifty_op (LSHIFTRT, operands);
4218 ;; signed left/right shift combination.
4220 [(set (match_operand:SI 0 "register_operand" "")
4222 (ashift:SI (match_operand:SI 1 "register_operand" "")
4223 (match_operand:SI 2 "const_int_operand" ""))
4224 (match_operand:SI 3 "const_int_operand" "")
4226 (clobber (reg:SI T_REG))]
4228 [(use (reg:SI R0_REG))]
4229 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4232 (define_insn "shl_sext_ext"
4233 [(set (match_operand:SI 0 "register_operand" "=r")
4235 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4236 (match_operand:SI 2 "const_int_operand" "n"))
4237 (match_operand:SI 3 "const_int_operand" "n")
4239 (clobber (reg:SI T_REG))]
4240 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4242 [(set (attr "length")
4243 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4245 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4247 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4249 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4251 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4253 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4255 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4257 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4258 (const_string "16")]
4259 (const_string "18")))
4260 (set_attr "type" "arith")])
4262 (define_insn "shl_sext_sub"
4263 [(set (match_operand:SI 0 "register_operand" "=z")
4265 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4266 (match_operand:SI 2 "const_int_operand" "n"))
4267 (match_operand:SI 3 "const_int_operand" "n")
4269 (clobber (reg:SI T_REG))]
4270 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4272 [(set (attr "length")
4273 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4275 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4277 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4279 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4280 (const_string "12")]
4281 (const_string "14")))
4282 (set_attr "type" "arith")])
4284 ;; These patterns are found in expansions of DImode shifts by 16, and
4285 ;; allow the xtrct instruction to be generated from C source.
4287 (define_insn "xtrct_left"
4288 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4289 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4291 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4295 [(set_attr "type" "arith")])
4297 (define_insn "xtrct_right"
4298 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4299 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4301 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4305 [(set_attr "type" "arith")])
4307 ;; -------------------------------------------------------------------------
4309 ;; -------------------------------------------------------------------------
4312 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4313 (neg:SI (plus:SI (reg:SI T_REG)
4314 (match_operand:SI 1 "arith_reg_operand" "r"))))
4316 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4320 [(set_attr "type" "arith")])
4322 (define_insn "*negdi_media"
4323 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4324 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4327 [(set_attr "type" "arith_media")])
4329 (define_expand "negdi2"
4330 [(set (match_operand:DI 0 "arith_reg_operand" "")
4331 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4337 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4338 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4340 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4341 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4343 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4344 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4346 emit_insn (gen_clrt ());
4347 emit_insn (gen_negc (low_dst, low_src));
4348 emit_insn (gen_negc (high_dst, high_src));
4353 (define_insn "negsi2"
4354 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4355 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4358 [(set_attr "type" "arith")])
4360 (define_insn "one_cmplsi2"
4361 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4362 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4365 [(set_attr "type" "arith")])
4367 (define_expand "one_cmpldi2"
4368 [(set (match_operand:DI 0 "arith_reg_dest" "")
4369 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4371 "TARGET_SHMEDIA" "")
4373 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4374 This can be used as some kind of conditional execution, which is useful
4377 [(set (match_operand:SI 0 "arith_reg_dest" "")
4378 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4379 (match_operand:SI 1 "arith_reg_operand" ""))
4383 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4384 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4388 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4389 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4390 (match_operand:SI 1 "arith_reg_operand" "0")
4391 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4393 "bf 0f\;neg %2,%0\\n0:"
4394 [(set_attr "type" "arith") ;; poor approximation
4395 (set_attr "length" "4")])
4398 ;; -------------------------------------------------------------------------
4399 ;; Zero extension instructions
4400 ;; -------------------------------------------------------------------------
4402 (define_insn "zero_extendsidi2"
4403 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4404 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4406 "addz.l %1, r63, %0"
4407 [(set_attr "type" "arith_media")
4408 (set_attr "highpart" "extend")])
4410 (define_insn "zero_extendhidi2"
4411 [(set (match_operand:DI 0 "register_operand" "=r,r")
4412 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4417 [(set_attr "type" "*,load_media")
4418 (set (attr "highpart")
4419 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4420 (const_string "user")]
4421 (const_string "ignore")))])
4424 [(set (match_operand:DI 0 "register_operand" "")
4425 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4426 "TARGET_SHMEDIA && reload_completed"
4427 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4428 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4431 if (GET_CODE (operands[1]) == TRUNCATE)
4432 operands[1] = XEXP (operands[1], 0);
4435 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4436 ;; reload the entire truncate expression.
4437 (define_insn_and_split "*loaddi_trunc"
4438 [(set (match_operand 0 "any_register_operand" "=r")
4439 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4440 "TARGET_SHMEDIA && reload_completed"
4442 "TARGET_SHMEDIA && reload_completed"
4443 [(set (match_dup 0) (match_dup 1))]
4444 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4446 (define_insn "zero_extendqidi2"
4447 [(set (match_operand:DI 0 "register_operand" "=r,r")
4448 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4453 [(set_attr "type" "arith_media,load_media")
4454 (set (attr "highpart")
4455 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4456 (const_string "user")]
4457 (const_string "ignore")))])
4459 (define_expand "zero_extendhisi2"
4460 [(set (match_operand:SI 0 "arith_reg_operand" "")
4461 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4465 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4466 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4469 (define_insn "*zero_extendhisi2_compact"
4470 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4471 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4474 [(set_attr "type" "arith")])
4476 (define_insn "*zero_extendhisi2_media"
4477 [(set (match_operand:SI 0 "register_operand" "=r,r")
4478 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4483 [(set_attr "type" "arith_media,load_media")
4484 (set (attr "highpart")
4485 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4486 (const_string "user")]
4487 (const_string "ignore")))])
4490 [(set (match_operand:SI 0 "register_operand" "")
4491 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4492 "TARGET_SHMEDIA && reload_completed"
4493 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4494 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4497 rtx op1 = operands[1];
4499 if (GET_CODE (op1) == TRUNCATE)
4500 op1 = XEXP (op1, 0);
4502 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4503 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4506 (define_expand "zero_extendqisi2"
4507 [(set (match_operand:SI 0 "arith_reg_operand" "")
4508 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4512 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4513 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4516 (define_insn "*zero_extendqisi2_compact"
4517 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4518 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4521 [(set_attr "type" "arith")])
4523 (define_insn "*zero_extendqisi2_media"
4524 [(set (match_operand:SI 0 "register_operand" "=r,r")
4525 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4530 [(set_attr "type" "arith_media,load_media")
4531 (set (attr "highpart")
4532 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4533 (const_string "user")]
4534 (const_string "ignore")))])
4536 (define_insn "zero_extendqihi2"
4537 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4538 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4541 [(set_attr "type" "arith")])
4543 ;; -------------------------------------------------------------------------
4544 ;; Sign extension instructions
4545 ;; -------------------------------------------------------------------------
4547 ;; ??? This should be a define expand.
4548 ;; ??? Or perhaps it should be dropped?
4550 ;; convert_move generates good code for SH[1-4].
4551 (define_insn "extendsidi2"
4552 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4553 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4559 [(set_attr "type" "arith_media,load_media,fpconv_media")
4560 (set (attr "highpart")
4561 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4562 (const_string "user")]
4563 (const_string "extend")))])
4565 (define_insn "extendhidi2"
4566 [(set (match_operand:DI 0 "register_operand" "=r,r")
4567 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4572 [(set_attr "type" "*,load_media")
4573 (set (attr "highpart")
4574 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4575 (const_string "user")]
4576 (const_string "ignore")))])
4579 [(set (match_operand:DI 0 "register_operand" "")
4580 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4581 "TARGET_SHMEDIA && reload_completed"
4582 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4583 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4586 if (GET_CODE (operands[1]) == TRUNCATE)
4587 operands[1] = XEXP (operands[1], 0);
4590 (define_insn "extendqidi2"
4591 [(set (match_operand:DI 0 "register_operand" "=r,r")
4592 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4597 [(set_attr "type" "*,load_media")
4598 (set (attr "highpart")
4599 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4600 (const_string "user")]
4601 (const_string "ignore")))])
4604 [(set (match_operand:DI 0 "register_operand" "")
4605 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4606 "TARGET_SHMEDIA && reload_completed"
4607 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4608 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4611 if (GET_CODE (operands[1]) == TRUNCATE)
4612 operands[1] = XEXP (operands[1], 0);
4615 (define_expand "extendhisi2"
4616 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4617 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4621 (define_insn "*extendhisi2_compact"
4622 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4623 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4628 [(set_attr "type" "arith,load")])
4630 (define_insn "*extendhisi2_media"
4631 [(set (match_operand:SI 0 "register_operand" "=r,r")
4632 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4637 [(set_attr "type" "arith_media,load_media")
4638 (set (attr "highpart")
4639 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4640 (const_string "user")]
4641 (const_string "ignore")))])
4644 [(set (match_operand:SI 0 "register_operand" "")
4645 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4646 "TARGET_SHMEDIA && reload_completed"
4647 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4648 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4651 rtx op1 = operands[1];
4652 if (GET_CODE (op1) == TRUNCATE)
4653 op1 = XEXP (op1, 0);
4655 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4656 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4659 (define_expand "extendqisi2"
4660 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4661 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4665 (define_insn "*extendqisi2_compact"
4666 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4667 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4672 [(set_attr "type" "arith,load")])
4674 (define_insn "*extendqisi2_media"
4675 [(set (match_operand:SI 0 "register_operand" "=r,r")
4676 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4681 [(set_attr "type" "arith_media,load_media")
4682 (set (attr "highpart")
4683 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4684 (const_string "user")]
4685 (const_string "ignore")))])
4688 [(set (match_operand:SI 0 "register_operand" "")
4689 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4690 "TARGET_SHMEDIA && reload_completed"
4691 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4692 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4695 rtx op1 = operands[1];
4696 if (GET_CODE (op1) == TRUNCATE)
4697 op1 = XEXP (op1, 0);
4699 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4700 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4703 (define_insn "extendqihi2"
4704 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4705 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4710 [(set_attr "type" "arith,load")])
4712 /* It would seem useful to combine the truncXi patterns into the movXi
4713 patterns, but unary operators are ignored when matching constraints,
4714 so we need separate patterns. */
4715 (define_insn "truncdisi2"
4716 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4717 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4726 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4727 (set (attr "highpart")
4728 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4729 (const_string "user")]
4730 (const_string "extend")))])
4732 (define_insn "truncdihi2"
4733 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4734 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4737 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4739 [(set_attr "type" "arith_media,store_media")
4740 (set_attr "length" "8,4")
4741 (set (attr "highpart")
4742 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4743 (const_string "user")]
4744 (const_string "extend")))])
4746 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4747 ; Because we use zero extension, we can't provide signed QImode compares
4748 ; using a simple compare or conditional banch insn.
4749 (define_insn "truncdiqi2"
4750 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4751 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4756 [(set_attr "type" "arith_media,store")
4757 (set (attr "highpart")
4758 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4759 (const_string "user")]
4760 (const_string "extend")))])
4761 ;; -------------------------------------------------------------------------
4762 ;; Move instructions
4763 ;; -------------------------------------------------------------------------
4765 ;; define push and pop so it is easy for sh.c
4766 ;; We can't use push and pop on SHcompact because the stack must always
4767 ;; be 8-byte aligned.
4769 (define_expand "push"
4770 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4771 (match_operand:SI 0 "register_operand" "r,l,x"))]
4772 "TARGET_SH1 && ! TARGET_SH5"
4775 (define_expand "pop"
4776 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4777 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4778 "TARGET_SH1 && ! TARGET_SH5"
4781 (define_expand "push_e"
4782 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4783 (match_operand:SF 0 "" ""))
4784 (use (reg:PSI FPSCR_REG))
4785 (clobber (scratch:SI))])]
4786 "TARGET_SH1 && ! TARGET_SH5"
4789 (define_insn "push_fpul"
4790 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4791 "TARGET_SH2E && ! TARGET_SH5"
4793 [(set_attr "type" "store")
4794 (set_attr "late_fp_use" "yes")
4795 (set_attr "hit_stack" "yes")])
4797 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4799 (define_expand "push_4"
4800 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4801 (match_operand:DF 0 "" ""))
4802 (use (reg:PSI FPSCR_REG))
4803 (clobber (scratch:SI))])]
4804 "TARGET_SH1 && ! TARGET_SH5"
4807 (define_expand "pop_e"
4808 [(parallel [(set (match_operand:SF 0 "" "")
4809 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4810 (use (reg:PSI FPSCR_REG))
4811 (clobber (scratch:SI))])]
4812 "TARGET_SH1 && ! TARGET_SH5"
4815 (define_insn "pop_fpul"
4816 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4817 "TARGET_SH2E && ! TARGET_SH5"
4819 [(set_attr "type" "load")
4820 (set_attr "hit_stack" "yes")])
4822 (define_expand "pop_4"
4823 [(parallel [(set (match_operand:DF 0 "" "")
4824 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4825 (use (reg:PSI FPSCR_REG))
4826 (clobber (scratch:SI))])]
4827 "TARGET_SH1 && ! TARGET_SH5"
4830 (define_expand "push_fpscr"
4835 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4836 gen_rtx_PRE_DEC (Pmode,
4837 stack_pointer_rtx)),
4839 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4843 (define_expand "pop_fpscr"
4848 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4849 gen_frame_mem (PSImode,
4850 gen_rtx_POST_INC (Pmode,
4851 stack_pointer_rtx))));
4852 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4856 ;; These two patterns can happen as the result of optimization, when
4857 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4858 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4861 [(set (reg:SI T_REG) (const_int 0))]
4866 [(set (reg:SI T_REG) (const_int 1))]
4870 ;; t/r must come after r/r, lest reload will try to reload stuff like
4871 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4872 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4873 (define_insn "movsi_i"
4874 [(set (match_operand:SI 0 "general_movdst_operand"
4875 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4876 (match_operand:SI 1 "general_movsrc_operand"
4877 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4881 && (register_operand (operands[0], SImode)
4882 || register_operand (operands[1], SImode))"
4899 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4900 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4902 ;; t/r must come after r/r, lest reload will try to reload stuff like
4903 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4904 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4905 ;; will require a reload.
4906 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4907 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4908 (define_insn "movsi_ie"
4909 [(set (match_operand:SI 0 "general_movdst_operand"
4910 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4911 (match_operand:SI 1 "general_movsrc_operand"
4912 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4913 "(TARGET_SH2E || TARGET_SH2A)
4914 && (register_operand (operands[0], SImode)
4915 || register_operand (operands[1], SImode))"
4940 ! move optimized away"
4941 [(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")
4942 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4943 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4945 (define_insn "movsi_i_lowpart"
4946 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4947 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4949 && (register_operand (operands[0], SImode)
4950 || register_operand (operands[1], SImode))"
4960 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4962 (define_insn_and_split "load_ra"
4963 [(set (match_operand:SI 0 "general_movdst_operand" "")
4964 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4967 "&& ! currently_expanding_to_rtl"
4968 [(set (match_dup 0) (match_dup 1))]
4971 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4972 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4975 ;; The '?'s in the following constraints may not reflect the time taken
4976 ;; to perform the move. They are there to discourage the use of floating-
4977 ;; point registers for storing integer values.
4978 (define_insn "*movsi_media"
4979 [(set (match_operand:SI 0 "general_movdst_operand"
4980 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4981 (match_operand:SI 1 "general_movsrc_operand"
4982 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4984 && (register_operand (operands[0], SImode)
4985 || sh_register_operand (operands[1], SImode)
4986 || GET_CODE (operands[1]) == TRUNCATE)"
5001 [(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")
5002 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5003 (set (attr "highpart")
5004 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5005 (const_string "user")]
5006 (const_string "ignore")))])
5008 (define_insn "*movsi_media_nofpu"
5009 [(set (match_operand:SI 0 "general_movdst_operand"
5010 "=r,r,r,r,m,*b,r,*b")
5011 (match_operand:SI 1 "general_movsrc_operand"
5012 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5014 && (register_operand (operands[0], SImode)
5015 || sh_register_operand (operands[1], SImode)
5016 || GET_CODE (operands[1]) == TRUNCATE)"
5026 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5027 (set_attr "length" "4,4,8,4,4,4,4,12")
5028 (set (attr "highpart")
5029 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5030 (const_string "user")]
5031 (const_string "ignore")))])
5033 (define_expand "movsi_const"
5034 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5035 (const:SI (sign_extend:SI
5038 (match_operand:DI 1 "immediate_operand" "s")
5041 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5044 (truncate:HI (match_dup 1))))))]
5045 "TARGET_SHMEDIA && reload_completed
5046 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5049 if (GET_CODE (operands[1]) == LABEL_REF
5050 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5051 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5052 else if (GOTOFF_P (operands[1]))
5054 rtx unspec = XEXP (operands[1], 0);
5056 if (! UNSPEC_GOTOFF_P (unspec))
5058 unspec = XEXP (unspec, 0);
5059 if (! UNSPEC_GOTOFF_P (unspec))
5062 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5063 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5064 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5068 (define_expand "movsi_const_16bit"
5069 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5070 (const:SI (sign_extend:SI
5072 (match_operand:DI 1 "immediate_operand" "s")))))]
5073 "TARGET_SHMEDIA && flag_pic && reload_completed
5074 && GET_CODE (operands[1]) == SYMBOL_REF"
5078 [(set (match_operand:SI 0 "arith_reg_dest" "")
5079 (match_operand:SI 1 "immediate_operand" ""))]
5080 "TARGET_SHMEDIA && reload_completed
5081 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5085 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5087 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5094 [(set (match_operand:SI 0 "register_operand" "")
5095 (match_operand:SI 1 "immediate_operand" ""))]
5096 "TARGET_SHMEDIA && reload_completed
5097 && ((GET_CODE (operands[1]) == CONST_INT
5098 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5099 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5100 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5102 (define_expand "movsi"
5103 [(set (match_operand:SI 0 "general_movdst_operand" "")
5104 (match_operand:SI 1 "general_movsrc_operand" ""))]
5106 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5108 (define_expand "ic_invalidate_line"
5109 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5110 (match_dup 1)] UNSPEC_ICACHE)
5111 (clobber (scratch:SI))])]
5112 "TARGET_HARD_SH4 || TARGET_SH5"
5117 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5120 else if (TARGET_SHCOMPACT)
5122 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5123 operands[1] = force_reg (Pmode, operands[1]);
5124 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5127 else if (TARGET_SH4A_ARCH)
5129 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5132 operands[0] = force_reg (Pmode, operands[0]);
5133 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5137 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5138 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5139 ;; the requirement *1*00 for associative address writes. The alignment of
5140 ;; %0 implies that its least significant bit is cleared,
5141 ;; thus we clear the V bit of a matching entry if there is one.
5142 (define_insn "ic_invalidate_line_i"
5143 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5144 (match_operand:SI 1 "register_operand" "r")]
5146 (clobber (match_scratch:SI 2 "=&r"))]
5148 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5149 [(set_attr "length" "8")
5150 (set_attr "type" "cwb")])
5152 (define_insn "ic_invalidate_line_sh4a"
5153 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5156 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5157 [(set_attr "length" "16")
5158 (set_attr "type" "cwb")])
5160 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5161 ;; an add in the code that calculates the address.
5162 (define_insn "ic_invalidate_line_media"
5163 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5166 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5167 [(set_attr "length" "16")
5168 (set_attr "type" "invalidate_line_media")])
5170 (define_insn "ic_invalidate_line_compact"
5171 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5172 (match_operand:SI 1 "register_operand" "r")]
5174 (clobber (reg:SI PR_REG))]
5177 [(set_attr "type" "sfunc")
5178 (set_attr "needs_delay_slot" "yes")])
5180 (define_expand "initialize_trampoline"
5181 [(match_operand:SI 0 "" "")
5182 (match_operand:SI 1 "" "")
5183 (match_operand:SI 2 "" "")]
5189 tramp = force_reg (Pmode, operands[0]);
5190 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5192 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5193 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5195 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5199 (define_insn "initialize_trampoline_compact"
5200 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5201 (match_operand:SI 1 "register_operand" "r")
5202 (reg:SI R2_REG) (reg:SI R3_REG)]
5205 (clobber (reg:SI PR_REG))]
5208 [(set_attr "type" "sfunc")
5209 (set_attr "needs_delay_slot" "yes")])
5211 (define_insn "movqi_i"
5212 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5213 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
5215 && (arith_reg_operand (operands[0], QImode)
5216 || arith_reg_operand (operands[1], QImode))"
5224 [(set_attr "type" "move,load,store,move,move,move")])
5226 (define_insn "*movqi_media"
5227 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5228 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5230 && (arith_reg_operand (operands[0], QImode)
5231 || extend_reg_or_0_operand (operands[1], QImode))"
5237 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5238 (set (attr "highpart")
5239 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5240 (const_string "user")]
5241 (const_string "ignore")))])
5243 (define_expand "movqi"
5244 [(set (match_operand:QI 0 "general_operand" "")
5245 (match_operand:QI 1 "general_operand" ""))]
5247 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5249 (define_expand "reload_inqi"
5250 [(set (match_operand:SI 2 "" "=&r")
5251 (match_operand:QI 1 "inqhi_operand" ""))
5252 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5253 (truncate:QI (match_dup 3)))]
5257 rtx inner = XEXP (operands[1], 0);
5258 int regno = REGNO (inner);
5260 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5261 operands[1] = gen_rtx_REG (SImode, regno);
5262 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5265 /* When storing r0, we have to avoid reg+reg addressing. */
5266 (define_insn "movhi_i"
5267 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5268 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5270 && (arith_reg_operand (operands[0], HImode)
5271 || arith_reg_operand (operands[1], HImode))
5272 && (GET_CODE (operands[0]) != MEM
5273 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5274 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5275 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5285 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5287 (define_insn "*movhi_media"
5288 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5289 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5291 && (arith_reg_operand (operands[0], HImode)
5292 || arith_reg_or_0_operand (operands[1], HImode))"
5299 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5300 (set (attr "highpart")
5301 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5302 (const_string "user")]
5303 (const_string "ignore")))])
5306 [(set (match_operand:HI 0 "register_operand" "")
5307 (match_operand:HI 1 "immediate_operand" ""))]
5308 "TARGET_SHMEDIA && reload_completed
5309 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5310 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5312 (define_expand "movhi"
5313 [(set (match_operand:HI 0 "general_movdst_operand" "")
5314 (match_operand:HI 1 "general_movsrc_operand" ""))]
5316 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5318 (define_expand "reload_inhi"
5319 [(set (match_operand:SI 2 "" "=&r")
5320 (match_operand:HI 1 "inqhi_operand" ""))
5321 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5322 (truncate:HI (match_dup 3)))]
5326 rtx inner = XEXP (operands[1], 0);
5327 int regno = REGNO (inner);
5329 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5330 operands[1] = gen_rtx_REG (SImode, regno);
5331 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5334 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5335 ;; compiled with -m2 -ml -O3 -funroll-loops
5336 (define_insn "*movdi_i"
5337 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5338 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5340 && (arith_reg_operand (operands[0], DImode)
5341 || arith_reg_operand (operands[1], DImode))"
5342 "* return output_movedouble (insn, operands, DImode);"
5343 [(set_attr "length" "4")
5344 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5346 ;; If the output is a register and the input is memory or a register, we have
5347 ;; to be careful and see which word needs to be loaded first.
5350 [(set (match_operand:DI 0 "general_movdst_operand" "")
5351 (match_operand:DI 1 "general_movsrc_operand" ""))]
5352 "TARGET_SH1 && reload_completed"
5353 [(set (match_dup 2) (match_dup 3))
5354 (set (match_dup 4) (match_dup 5))]
5359 if ((GET_CODE (operands[0]) == MEM
5360 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5361 || (GET_CODE (operands[1]) == MEM
5362 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5365 switch (GET_CODE (operands[0]))
5368 regno = REGNO (operands[0]);
5371 regno = subreg_regno (operands[0]);
5381 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5383 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5384 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5385 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5386 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5390 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5391 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5392 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5393 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5396 if (operands[2] == 0 || operands[3] == 0
5397 || operands[4] == 0 || operands[5] == 0)
5401 ;; The '?'s in the following constraints may not reflect the time taken
5402 ;; to perform the move. They are there to discourage the use of floating-
5403 ;; point registers for storing integer values.
5404 (define_insn "*movdi_media"
5405 [(set (match_operand:DI 0 "general_movdst_operand"
5406 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5407 (match_operand:DI 1 "general_movsrc_operand"
5408 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5410 && (register_operand (operands[0], DImode)
5411 || sh_register_operand (operands[1], DImode))"
5426 [(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")
5427 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5429 (define_insn "*movdi_media_nofpu"
5430 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5431 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5433 && (register_operand (operands[0], DImode)
5434 || sh_register_operand (operands[1], DImode))"
5444 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5445 (set_attr "length" "4,4,16,4,4,4,4,*")])
5447 (define_insn "*movdi_media_I16"
5448 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5449 (match_operand:DI 1 "const_int_operand" "I16"))]
5450 "TARGET_SHMEDIA && reload_completed"
5452 [(set_attr "type" "arith_media")
5453 (set_attr "length" "4")])
5456 [(set (match_operand:DI 0 "arith_reg_dest" "")
5457 (match_operand:DI 1 "immediate_operand" ""))]
5458 "TARGET_SHMEDIA && reload_completed
5459 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5460 [(set (match_dup 0) (match_dup 1))]
5465 if (TARGET_SHMEDIA64)
5466 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5468 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5470 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5476 (define_expand "movdi_const"
5477 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5478 (const:DI (sign_extend:DI
5481 (match_operand:DI 1 "immediate_operand" "s")
5484 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5490 (const_int 32)))))))
5492 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5498 (const_int 16)))))))
5500 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5505 "TARGET_SHMEDIA64 && reload_completed
5506 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5509 sh_mark_label (operands[1], 4);
5512 (define_expand "movdi_const_32bit"
5513 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5514 (const:DI (sign_extend:DI
5517 (match_operand:DI 1 "immediate_operand" "s")
5520 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5525 "TARGET_SHMEDIA32 && reload_completed
5526 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5529 sh_mark_label (operands[1], 2);
5532 (define_expand "movdi_const_16bit"
5533 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5534 (const:DI (sign_extend:DI
5536 (match_operand:DI 1 "immediate_operand" "s")))))]
5537 "TARGET_SHMEDIA && flag_pic && reload_completed
5538 && GET_CODE (operands[1]) == SYMBOL_REF"
5542 [(set (match_operand:DI 0 "ext_dest_operand" "")
5543 (match_operand:DI 1 "immediate_operand" ""))]
5544 "TARGET_SHMEDIA && reload_completed
5545 && GET_CODE (operands[1]) == CONST_INT
5546 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5547 [(set (match_dup 0) (match_dup 2))
5551 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5552 unsigned HOST_WIDE_INT low = val;
5553 unsigned HOST_WIDE_INT high = val;
5554 unsigned HOST_WIDE_INT sign;
5555 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5557 /* Zero-extend the 16 least-significant bits. */
5560 /* Arithmetic shift right the word by 16 bits. */
5562 if (GET_CODE (operands[0]) == SUBREG
5563 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5572 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5578 /* If we can't generate the constant with a two-insn movi / shori
5579 sequence, try some other strategies. */
5580 if (! CONST_OK_FOR_I16 (high))
5582 /* Try constant load / left shift. We know VAL != 0. */
5583 val2 = val ^ (val-1);
5586 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5588 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5589 || (! CONST_OK_FOR_I16 (high >> 16)
5590 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5592 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5593 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5594 GEN_INT (trailing_zeroes));
5598 /* Try constant load / right shift. */
5599 val2 = (val >> 15) + 1;
5600 if (val2 == (val2 & -val2))
5602 int shift = 49 - exact_log2 (val2);
5604 val2 = trunc_int_for_mode (val << shift, DImode);
5605 if (CONST_OK_FOR_I16 (val2))
5607 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5613 val2 = val & 0xffff;
5614 if ((val >> 16 & 0xffff) == val2
5615 && (val >> 32 & 0xffff) == val2
5616 && (val >> 48 & 0xffff) == val2)
5618 val2 = (HOST_WIDE_INT) val >> 48;
5619 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5620 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5623 /* Try movi / mshflo.l */
5624 val2 = (HOST_WIDE_INT) val >> 32;
5625 if (val2 == ((unsigned HOST_WIDE_INT)
5626 trunc_int_for_mode (val, SImode)))
5628 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5632 /* Try movi / mshflo.l w/ r63. */
5633 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5634 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5636 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5642 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5645 operands[2] = GEN_INT (val2);
5649 [(set (match_operand:DI 0 "ext_dest_operand" "")
5650 (match_operand:DI 1 "immediate_operand" ""))]
5651 "TARGET_SHMEDIA && reload_completed
5652 && GET_CODE (operands[1]) == CONST_DOUBLE"
5653 [(set (match_dup 0) (match_dup 2))
5655 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5658 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5659 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5660 unsigned HOST_WIDE_INT val = low;
5661 unsigned HOST_WIDE_INT sign;
5663 /* Zero-extend the 16 least-significant bits. */
5665 operands[1] = GEN_INT (val);
5667 /* Arithmetic shift right the double-word by 16 bits. */
5669 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5672 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5676 /* This will only be true if high is a sign-extension of low, i.e.,
5677 it must be either 0 or (unsigned)-1, and be zero iff the
5678 most-significant bit of low is set. */
5679 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5680 operands[2] = GEN_INT (low);
5682 operands[2] = immed_double_const (low, high, DImode);
5685 (define_insn "shori_media"
5686 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5687 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5689 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5690 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5694 [(set_attr "type" "arith_media,*")])
5696 (define_insn "*shori_media_si"
5697 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5698 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5700 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5704 (define_expand "movdi"
5705 [(set (match_operand:DI 0 "general_movdst_operand" "")
5706 (match_operand:DI 1 "general_movsrc_operand" ""))]
5708 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5710 (define_insn "movdf_media"
5711 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5712 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5714 && (register_operand (operands[0], DFmode)
5715 || sh_register_operand (operands[1], DFmode))"
5726 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5728 (define_insn "movdf_media_nofpu"
5729 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5730 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5732 && (register_operand (operands[0], DFmode)
5733 || sh_register_operand (operands[1], DFmode))"
5739 [(set_attr "type" "arith_media,*,load_media,store_media")])
5742 [(set (match_operand:DF 0 "arith_reg_dest" "")
5743 (match_operand:DF 1 "immediate_operand" ""))]
5744 "TARGET_SHMEDIA && reload_completed"
5745 [(set (match_dup 3) (match_dup 2))]
5748 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5750 REAL_VALUE_TYPE value;
5752 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5753 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5755 if (HOST_BITS_PER_WIDE_INT >= 64)
5756 operands[2] = immed_double_const ((unsigned long) values[endian]
5757 | ((HOST_WIDE_INT) values[1 - endian]
5761 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5762 operands[2] = immed_double_const (values[endian], values[1 - endian],
5766 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5769 ;; ??? This should be a define expand.
5771 (define_insn "movdf_k"
5772 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5773 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5775 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5776 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5777 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5778 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5779 && (arith_reg_operand (operands[0], DFmode)
5780 || arith_reg_operand (operands[1], DFmode))"
5781 "* return output_movedouble (insn, operands, DFmode);"
5782 [(set_attr "length" "4")
5783 (set_attr "type" "move,pcload,load,store")])
5785 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5786 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5787 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5788 ;; the d/m/c/X alternative, which is split later into single-precision
5789 ;; instructions. And when not optimizing, no splits are done before fixing
5790 ;; up pcloads, so we need usable length information for that.
5791 (define_insn "movdf_i4"
5792 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5793 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5794 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5795 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5796 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5797 && (arith_reg_operand (operands[0], DFmode)
5798 || arith_reg_operand (operands[1], DFmode))"
5810 [(set_attr_alternative "length"
5811 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5813 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5814 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5815 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5817 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5818 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5819 ;; increment or decrement r15 explicitly.
5821 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5822 (const_int 10) (const_int 8))
5824 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5825 (const_int 10) (const_int 8))])
5826 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5827 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5828 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5829 (const_string "double")
5830 (const_string "none")))])
5832 ;; Moving DFmode between fp/general registers through memory
5833 ;; (the top of the stack) is faster than moving through fpul even for
5834 ;; little endian. Because the type of an instruction is important for its
5835 ;; scheduling, it is beneficial to split these operations, rather than
5836 ;; emitting them in one single chunk, even if this will expose a stack
5837 ;; use that will prevent scheduling of other stack accesses beyond this
5840 [(set (match_operand:DF 0 "register_operand" "")
5841 (match_operand:DF 1 "register_operand" ""))
5842 (use (match_operand:PSI 2 "fpscr_operand" ""))
5843 (clobber (match_scratch:SI 3 "=X"))]
5844 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5845 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5851 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5853 emit_move_insn (stack_pointer_rtx,
5854 plus_constant (stack_pointer_rtx, -8));
5855 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5858 tos = gen_tmp_stack_mem (DFmode,
5859 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5860 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5861 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5862 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5863 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5864 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5866 tos = gen_tmp_stack_mem (DFmode,
5867 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5868 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5869 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5870 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5872 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5876 ;; local-alloc sometimes allocates scratch registers even when not required,
5877 ;; so we must be prepared to handle these.
5879 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5881 [(set (match_operand:DF 0 "general_movdst_operand" "")
5882 (match_operand:DF 1 "general_movsrc_operand" ""))
5883 (use (match_operand:PSI 2 "fpscr_operand" ""))
5884 (clobber (match_scratch:SI 3 ""))]
5885 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5887 && true_regnum (operands[0]) < 16
5888 && true_regnum (operands[1]) < 16"
5889 [(set (match_dup 0) (match_dup 1))]
5892 /* If this was a reg <-> mem operation with base + index reg addressing,
5893 we have to handle this in a special way. */
5894 rtx mem = operands[0];
5896 if (! memory_operand (mem, DFmode))
5901 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5902 mem = SUBREG_REG (mem);
5903 if (GET_CODE (mem) == MEM)
5905 rtx addr = XEXP (mem, 0);
5906 if (GET_CODE (addr) == PLUS
5907 && GET_CODE (XEXP (addr, 0)) == REG
5908 && GET_CODE (XEXP (addr, 1)) == REG)
5911 rtx reg0 = gen_rtx_REG (Pmode, 0);
5912 rtx regop = operands[store_p], word0 ,word1;
5914 if (GET_CODE (regop) == SUBREG)
5915 alter_subreg (®op);
5916 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5920 mem = copy_rtx (mem);
5921 PUT_MODE (mem, SImode);
5922 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5923 alter_subreg (&word0);
5924 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5925 alter_subreg (&word1);
5926 if (store_p || ! refers_to_regno_p (REGNO (word0),
5927 REGNO (word0) + 1, addr, 0))
5930 ? gen_movsi_ie (mem, word0)
5931 : gen_movsi_ie (word0, mem));
5932 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5933 mem = copy_rtx (mem);
5935 ? gen_movsi_ie (mem, word1)
5936 : gen_movsi_ie (word1, mem));
5937 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5941 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5942 emit_insn (gen_movsi_ie (word1, mem));
5943 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5944 mem = copy_rtx (mem);
5945 emit_insn (gen_movsi_ie (word0, mem));
5952 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5954 [(set (match_operand:DF 0 "register_operand" "")
5955 (match_operand:DF 1 "memory_operand" ""))
5956 (use (match_operand:PSI 2 "fpscr_operand" ""))
5957 (clobber (reg:SI R0_REG))]
5958 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5959 [(parallel [(set (match_dup 0) (match_dup 1))
5961 (clobber (scratch:SI))])]
5964 (define_expand "reload_indf__frn"
5965 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5966 (match_operand:DF 1 "immediate_operand" "FQ"))
5967 (use (reg:PSI FPSCR_REG))
5968 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5972 (define_expand "reload_outdf__RnFRm"
5973 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5974 (match_operand:DF 1 "register_operand" "af,r"))
5975 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5979 ;; Simplify no-op moves.
5981 [(set (match_operand:SF 0 "register_operand" "")
5982 (match_operand:SF 1 "register_operand" ""))
5983 (use (match_operand:PSI 2 "fpscr_operand" ""))
5984 (clobber (match_scratch:SI 3 ""))]
5985 "TARGET_SH2E && reload_completed
5986 && true_regnum (operands[0]) == true_regnum (operands[1])"
5987 [(set (match_dup 0) (match_dup 0))]
5990 ;; fmovd substitute post-reload splits
5992 [(set (match_operand:DF 0 "register_operand" "")
5993 (match_operand:DF 1 "register_operand" ""))
5994 (use (match_operand:PSI 2 "fpscr_operand" ""))
5995 (clobber (match_scratch:SI 3 ""))]
5996 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5997 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5998 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6002 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6003 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6004 gen_rtx_REG (SFmode, src), operands[2]));
6005 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6006 gen_rtx_REG (SFmode, src + 1), operands[2]));
6011 [(set (match_operand:DF 0 "register_operand" "")
6012 (mem:DF (match_operand:SI 1 "register_operand" "")))
6013 (use (match_operand:PSI 2 "fpscr_operand" ""))
6014 (clobber (match_scratch:SI 3 ""))]
6015 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6016 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6017 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6021 int regno = true_regnum (operands[0]);
6023 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6025 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6026 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6027 regno + !! TARGET_LITTLE_ENDIAN),
6028 mem2, operands[2]));
6029 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6030 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6031 regno + ! TARGET_LITTLE_ENDIAN),
6032 change_address (mem, SFmode, NULL_RTX),
6038 [(set (match_operand:DF 0 "register_operand" "")
6039 (match_operand:DF 1 "memory_operand" ""))
6040 (use (match_operand:PSI 2 "fpscr_operand" ""))
6041 (clobber (match_scratch:SI 3 ""))]
6042 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6043 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6047 int regno = true_regnum (operands[0]);
6048 rtx addr, insn, adjust = NULL_RTX;
6049 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6050 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6051 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6053 operands[1] = copy_rtx (mem2);
6054 addr = XEXP (mem2, 0);
6055 if (GET_CODE (addr) != POST_INC)
6057 /* If we have to modify the stack pointer, the value that we have
6058 read with post-increment might be modified by an interrupt,
6059 so write it back. */
6060 if (REGNO (addr) == STACK_POINTER_REGNUM)
6061 adjust = gen_push_e (reg0);
6063 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6064 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6066 addr = XEXP (addr, 0);
6067 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6068 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6069 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6073 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6078 [(set (match_operand:DF 0 "memory_operand" "")
6079 (match_operand:DF 1 "register_operand" ""))
6080 (use (match_operand:PSI 2 "fpscr_operand" ""))
6081 (clobber (match_scratch:SI 3 ""))]
6082 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6083 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6087 int regno = true_regnum (operands[1]);
6088 rtx insn, addr, adjust = NULL_RTX;
6090 operands[0] = copy_rtx (operands[0]);
6091 PUT_MODE (operands[0], SFmode);
6092 insn = emit_insn (gen_movsf_ie (operands[0],
6093 gen_rtx_REG (SFmode,
6094 regno + ! TARGET_LITTLE_ENDIAN),
6096 operands[0] = copy_rtx (operands[0]);
6097 addr = XEXP (operands[0], 0);
6098 if (GET_CODE (addr) != PRE_DEC)
6100 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6101 emit_insn_before (adjust, insn);
6102 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6104 addr = XEXP (addr, 0);
6106 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6107 insn = emit_insn (gen_movsf_ie (operands[0],
6108 gen_rtx_REG (SFmode,
6109 regno + !! TARGET_LITTLE_ENDIAN),
6111 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6115 ;; If the output is a register and the input is memory or a register, we have
6116 ;; to be careful and see which word needs to be loaded first.
6119 [(set (match_operand:DF 0 "general_movdst_operand" "")
6120 (match_operand:DF 1 "general_movsrc_operand" ""))]
6121 "TARGET_SH1 && reload_completed"
6122 [(set (match_dup 2) (match_dup 3))
6123 (set (match_dup 4) (match_dup 5))]
6128 if ((GET_CODE (operands[0]) == MEM
6129 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6130 || (GET_CODE (operands[1]) == MEM
6131 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6134 switch (GET_CODE (operands[0]))
6137 regno = REGNO (operands[0]);
6140 regno = subreg_regno (operands[0]);
6150 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6152 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6153 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6154 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6155 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6159 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6160 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6161 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6162 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6165 if (operands[2] == 0 || operands[3] == 0
6166 || operands[4] == 0 || operands[5] == 0)
6170 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6171 ;; used only once, let combine add in the index again.
6174 [(set (match_operand:SI 0 "register_operand" "")
6175 (match_operand:SI 1 "" ""))
6176 (clobber (match_operand 2 "register_operand" ""))]
6177 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6178 && ALLOW_INDEXED_ADDRESS"
6179 [(use (reg:SI R0_REG))]
6182 rtx addr, reg, const_int;
6184 if (GET_CODE (operands[1]) != MEM)
6186 addr = XEXP (operands[1], 0);
6187 if (GET_CODE (addr) != PLUS)
6189 reg = XEXP (addr, 0);
6190 const_int = XEXP (addr, 1);
6191 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6192 && GET_CODE (const_int) == CONST_INT))
6194 emit_move_insn (operands[2], const_int);
6195 emit_move_insn (operands[0],
6196 change_address (operands[1], VOIDmode,
6197 gen_rtx_PLUS (SImode, reg, operands[2])));
6202 [(set (match_operand:SI 1 "" "")
6203 (match_operand:SI 0 "register_operand" ""))
6204 (clobber (match_operand 2 "register_operand" ""))]
6205 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6206 && ALLOW_INDEXED_ADDRESS"
6207 [(use (reg:SI R0_REG))]
6210 rtx addr, reg, const_int;
6212 if (GET_CODE (operands[1]) != MEM)
6214 addr = XEXP (operands[1], 0);
6215 if (GET_CODE (addr) != PLUS)
6217 reg = XEXP (addr, 0);
6218 const_int = XEXP (addr, 1);
6219 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6220 && GET_CODE (const_int) == CONST_INT))
6222 emit_move_insn (operands[2], const_int);
6223 emit_move_insn (change_address (operands[1], VOIDmode,
6224 gen_rtx_PLUS (SImode, reg, operands[2])),
6229 (define_expand "movdf"
6230 [(set (match_operand:DF 0 "general_movdst_operand" "")
6231 (match_operand:DF 1 "general_movsrc_operand" ""))]
6235 if (prepare_move_operands (operands, DFmode)) DONE;
6238 if (TARGET_SHMEDIA_FPU)
6239 emit_insn (gen_movdf_media (operands[0], operands[1]));
6241 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6244 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6246 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6251 ;;This is incompatible with the way gcc uses subregs.
6252 ;;(define_insn "movv2sf_i"
6253 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6254 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6255 ;; "TARGET_SHMEDIA_FPU
6256 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6257 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6261 ;; fst%M0.p %m0, %1"
6262 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6264 (define_insn_and_split "movv2sf_i"
6265 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6266 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6267 "TARGET_SHMEDIA_FPU"
6269 "TARGET_SHMEDIA_FPU && reload_completed"
6270 [(set (match_dup 0) (match_dup 1))]
6273 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6274 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6277 (define_expand "movv2sf"
6278 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6279 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6280 "TARGET_SHMEDIA_FPU"
6283 if (prepare_move_operands (operands, V2SFmode))
6287 (define_expand "addv2sf3"
6288 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6289 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6290 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6291 "TARGET_SHMEDIA_FPU"
6294 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6298 (define_expand "subv2sf3"
6299 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6300 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6301 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6302 "TARGET_SHMEDIA_FPU"
6305 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6309 (define_expand "mulv2sf3"
6310 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6311 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6312 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6313 "TARGET_SHMEDIA_FPU"
6316 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6320 (define_expand "divv2sf3"
6321 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6322 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6323 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6324 "TARGET_SHMEDIA_FPU"
6327 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6331 (define_insn_and_split "*movv4sf_i"
6332 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6333 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6334 "TARGET_SHMEDIA_FPU"
6336 "&& reload_completed"
6342 for (i = 0; i < 4/2; i++)
6346 if (GET_CODE (operands[0]) == MEM)
6347 x = adjust_address (operands[0], V2SFmode,
6348 i * GET_MODE_SIZE (V2SFmode));
6350 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6352 if (GET_CODE (operands[1]) == MEM)
6353 y = adjust_address (operands[1], V2SFmode,
6354 i * GET_MODE_SIZE (V2SFmode));
6356 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6358 emit_insn (gen_movv2sf_i (x, y));
6363 [(set_attr "length" "8")])
6365 (define_expand "movv4sf"
6366 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6367 (match_operand:V4SF 1 "general_operand" ""))]
6368 "TARGET_SHMEDIA_FPU"
6371 if (prepare_move_operands (operands, V4SFmode))
6375 (define_insn_and_split "*movv16sf_i"
6376 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6377 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6378 "TARGET_SHMEDIA_FPU"
6380 "&& reload_completed"
6386 for (i = 0; i < 16/2; i++)
6390 if (GET_CODE (operands[0]) == MEM)
6391 x = adjust_address (operands[0], V2SFmode,
6392 i * GET_MODE_SIZE (V2SFmode));
6395 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6399 if (GET_CODE (operands[1]) == MEM)
6400 y = adjust_address (operands[1], V2SFmode,
6401 i * GET_MODE_SIZE (V2SFmode));
6404 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6408 emit_insn (gen_movv2sf_i (x, y));
6413 [(set_attr "length" "32")])
6415 (define_expand "movv16sf"
6416 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6417 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6418 "TARGET_SHMEDIA_FPU"
6421 if (prepare_move_operands (operands, V16SFmode))
6425 (define_insn "movsf_media"
6426 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6427 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6429 && (register_operand (operands[0], SFmode)
6430 || sh_register_operand (operands[1], SFmode))"
6441 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6442 (set (attr "highpart")
6443 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6444 (const_string "user")]
6445 (const_string "ignore")))])
6447 (define_insn "movsf_media_nofpu"
6448 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6449 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6451 && (register_operand (operands[0], SFmode)
6452 || sh_register_operand (operands[1], SFmode))"
6458 [(set_attr "type" "arith_media,*,load_media,store_media")
6459 (set (attr "highpart")
6460 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6461 (const_string "user")]
6462 (const_string "ignore")))])
6465 [(set (match_operand:SF 0 "arith_reg_dest" "")
6466 (match_operand:SF 1 "immediate_operand" ""))]
6467 "TARGET_SHMEDIA && reload_completed
6468 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6469 [(set (match_dup 3) (match_dup 2))]
6473 REAL_VALUE_TYPE value;
6475 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6476 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6477 operands[2] = GEN_INT (values);
6479 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6482 (define_insn "movsf_i"
6483 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6484 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6487 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6488 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6489 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6490 && (arith_reg_operand (operands[0], SFmode)
6491 || arith_reg_operand (operands[1], SFmode))"
6500 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6502 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6503 ;; update_flow_info would not know where to put REG_EQUAL notes
6504 ;; when the destination changes mode.
6505 (define_insn "movsf_ie"
6506 [(set (match_operand:SF 0 "general_movdst_operand"
6507 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6508 (match_operand:SF 1 "general_movsrc_operand"
6509 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6510 (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"))
6511 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6514 && (arith_reg_operand (operands[0], SFmode)
6515 || arith_reg_operand (operands[1], SFmode)
6516 || arith_reg_operand (operands[3], SImode)
6517 || (fpul_operand (operands[0], SFmode)
6518 && memory_operand (operands[1], SFmode)
6519 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6520 || (fpul_operand (operands[1], SFmode)
6521 && memory_operand (operands[0], SFmode)
6522 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6542 ! move optimized away"
6543 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6544 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6545 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6546 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6547 (const_string "single")
6548 (const_string "none")))])
6551 [(set (match_operand:SF 0 "register_operand" "")
6552 (match_operand:SF 1 "register_operand" ""))
6553 (use (match_operand:PSI 2 "fpscr_operand" ""))
6554 (clobber (reg:SI FPUL_REG))]
6556 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6558 (clobber (scratch:SI))])
6559 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6561 (clobber (scratch:SI))])]
6564 (define_expand "movsf"
6565 [(set (match_operand:SF 0 "general_movdst_operand" "")
6566 (match_operand:SF 1 "general_movsrc_operand" ""))]
6570 if (prepare_move_operands (operands, SFmode))
6574 if (TARGET_SHMEDIA_FPU)
6575 emit_insn (gen_movsf_media (operands[0], operands[1]));
6577 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6582 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6587 (define_insn "mov_nop"
6588 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6591 [(set_attr "length" "0")
6592 (set_attr "type" "nil")])
6594 (define_expand "reload_insf__frn"
6595 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6596 (match_operand:SF 1 "immediate_operand" "FQ"))
6597 (use (reg:PSI FPSCR_REG))
6598 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6602 (define_expand "reload_insi__i_fpul"
6603 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6604 (match_operand:SI 1 "immediate_operand" "i"))
6605 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6609 (define_expand "ptabs"
6610 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6614 if (!TARGET_PT_FIXED)
6616 rtx eq = operands[1];
6618 /* ??? For canonical RTL we really should remove any CONST from EQ
6619 before wrapping it in the AND, and finally wrap the EQ into a
6620 const if is constant. However, for reload we must expose the
6621 input register or symbolic constant, and we can't have
6622 different insn structures outside of the operands for different
6623 alternatives of the same pattern. */
6624 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6627 = (gen_rtx_IF_THEN_ELSE
6630 gen_rtx_MEM (PDImode, operands[1]),
6631 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6632 PDImode, operands[1])));
6636 ;; expanded by ptabs expander.
6637 (define_insn "*extendsipdi_media"
6638 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6639 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6643 (mem:PDI (match_dup 1))
6644 (sign_extend:PDI (match_dup 1))))]
6645 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6649 [(set_attr "type" "ptabs_media,pt_media")
6650 (set_attr "length" "4,*")])
6652 (define_insn "*truncdipdi_media"
6653 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6654 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6658 (mem:PDI (match_dup 1))
6659 (truncate:PDI (match_dup 1))))]
6660 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6664 [(set_attr "type" "ptabs_media,pt_media")
6665 (set_attr "length" "4,*")])
6667 (define_insn "*movsi_y"
6668 [(set (match_operand:SI 0 "register_operand" "=y,y")
6669 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6670 (clobber (match_scratch:SI 2 "=&z,r"))]
6672 && (reload_in_progress || reload_completed)"
6674 [(set_attr "length" "4")
6675 (set_attr "type" "pcload,move")])
6678 [(set (match_operand:SI 0 "register_operand" "")
6679 (match_operand:SI 1 "immediate_operand" ""))
6680 (clobber (match_operand:SI 2 "register_operand" ""))]
6682 [(set (match_dup 2) (match_dup 1))
6683 (set (match_dup 0) (match_dup 2))]
6687 [(set (match_operand:SI 0 "register_operand" "")
6688 (match_operand:SI 1 "memory_operand" ""))
6689 (clobber (reg:SI R0_REG))]
6691 [(set (match_dup 0) (match_dup 1))]
6694 ;; ------------------------------------------------------------------------
6695 ;; Define the real conditional branch instructions.
6696 ;; ------------------------------------------------------------------------
6698 (define_insn "branch_true"
6699 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6700 (label_ref (match_operand 0 "" ""))
6703 "* return output_branch (1, insn, operands);"
6704 [(set_attr "type" "cbranch")])
6706 (define_insn "branch_false"
6707 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6708 (label_ref (match_operand 0 "" ""))
6711 "* return output_branch (0, insn, operands);"
6712 [(set_attr "type" "cbranch")])
6714 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6715 ;; which destination is too far away.
6716 ;; The const_int_operand is distinct for each branch target; it avoids
6717 ;; unwanted matches with redundant_insn.
6718 (define_insn "block_branch_redirect"
6719 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6722 [(set_attr "length" "0")])
6724 ;; This one has the additional purpose to record a possible scratch register
6725 ;; for the following branch.
6726 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6727 ;; because the insn then might be deemed dead and deleted. And we can't
6728 ;; make the use in the jump insn explicit because that would disable
6729 ;; delay slot scheduling from the target.
6730 (define_insn "indirect_jump_scratch"
6731 [(set (match_operand:SI 0 "register_operand" "=r")
6732 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6733 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6736 [(set_attr "length" "0")])
6738 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6739 ;; being pulled into the delay slot of a condbranch that has been made to
6740 ;; jump around the unconditional jump because it was out of range.
6741 (define_insn "stuff_delay_slot"
6743 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6744 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6747 [(set_attr "length" "0")
6748 (set_attr "cond_delay_slot" "yes")])
6750 ;; Conditional branch insns
6752 (define_expand "beq_media"
6754 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6755 (match_operand:DI 2 "arith_operand" "r,I06"))
6756 (match_operand 0 "" "")
6759 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6761 (define_insn "*beq_media_i"
6763 (if_then_else (match_operator 3 "equality_comparison_operator"
6764 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6765 (match_operand:DI 2 "arith_operand" "r,I06")])
6766 (match_operand 0 "target_operand" "b,b")
6771 b%o3i%' %1, %2, %0%>"
6772 [(set_attr "type" "cbranch_media")])
6774 (define_insn "*beq_media_i32"
6776 (if_then_else (match_operator 3 "equality_comparison_operator"
6777 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6778 (match_operand:SI 2 "arith_operand" "r,I06")])
6779 (match_operand 0 "target_operand" "b,b")
6784 b%o3i%' %1, %2, %0%>"
6785 [(set_attr "type" "cbranch_media")])
6787 (define_expand "bne_media"
6789 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6790 (match_operand:DI 2 "arith_operand" "r,I06"))
6791 (match_operand 0 "" "")
6794 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6796 (define_expand "bgt_media"
6798 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6799 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6800 (match_operand 0 "" "")
6803 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6805 (define_expand "bge_media"
6807 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6808 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6809 (match_operand 0 "" "")
6812 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6814 (define_expand "bgtu_media"
6816 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6817 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6818 (match_operand 0 "" "")
6821 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6823 (define_expand "bgeu_media"
6825 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6826 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6827 (match_operand 0 "" "")
6830 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6832 (define_insn "*bgt_media_i"
6834 (if_then_else (match_operator 3 "greater_comparison_operator"
6835 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6836 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6837 (match_operand 0 "target_operand" "b")
6840 "b%o3%' %N1, %N2, %0%>"
6841 [(set_attr "type" "cbranch_media")])
6843 (define_insn "*bgt_media_i32"
6845 (if_then_else (match_operator 3 "greater_comparison_operator"
6846 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6847 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6848 (match_operand 0 "target_operand" "b")
6851 "b%o3%' %N1, %N2, %0%>"
6852 [(set_attr "type" "cbranch_media")])
6854 ;; These are only needed to make invert_jump() happy - otherwise, jump
6855 ;; optimization will be silently disabled.
6856 (define_insn "*blt_media_i"
6858 (if_then_else (match_operator 3 "less_comparison_operator"
6859 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6860 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6861 (match_operand 0 "target_operand" "b")
6864 "b%o3%' %N2, %N1, %0%>"
6865 [(set_attr "type" "cbranch_media")])
6867 (define_insn "*blt_media_i32"
6869 (if_then_else (match_operator 3 "less_comparison_operator"
6870 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6871 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6872 (match_operand 0 "target_operand" "b")
6875 "b%o3%' %N2, %N1, %0%>"
6876 [(set_attr "type" "cbranch_media")])
6878 (define_expand "beq"
6880 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6881 (label_ref (match_operand 0 "" ""))
6888 enum machine_mode mode = GET_MODE (sh_compare_op0);
6890 if (mode != DImode && mode != SImode)
6892 rtx tmp = gen_reg_rtx (DImode);
6894 emit_insn (gen_seq (tmp));
6895 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6899 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6900 if (CONSTANT_P (sh_compare_op1)
6901 && (GET_CODE (sh_compare_op1) != CONST_INT
6902 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6903 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6904 emit_jump_insn (gen_beq_media (operands[0],
6905 sh_compare_op0, sh_compare_op1));
6909 from_compare (operands, EQ);
6912 (define_expand "bne"
6914 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6915 (label_ref (match_operand 0 "" ""))
6922 enum machine_mode mode = GET_MODE (sh_compare_op0);
6924 if (mode != DImode && mode != SImode)
6926 rtx tmp = gen_reg_rtx (DImode);
6928 emit_insn (gen_seq (tmp));
6929 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6933 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6934 if (CONSTANT_P (sh_compare_op1)
6935 && (GET_CODE (sh_compare_op1) != CONST_INT
6936 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6937 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6938 emit_jump_insn (gen_bne_media (operands[0],
6939 sh_compare_op0, sh_compare_op1));
6943 from_compare (operands, EQ);
6946 (define_expand "bgt"
6948 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6949 (label_ref (match_operand 0 "" ""))
6956 enum machine_mode mode = GET_MODE (sh_compare_op0);
6958 if (mode != DImode && mode != SImode)
6960 rtx tmp = gen_reg_rtx (DImode);
6962 emit_insn (gen_sgt (tmp));
6963 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6967 if (sh_compare_op0 != const0_rtx)
6968 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6969 if (sh_compare_op1 != const0_rtx)
6970 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6971 emit_jump_insn (gen_bgt_media (operands[0],
6972 sh_compare_op0, sh_compare_op1));
6976 from_compare (operands, GT);
6979 (define_expand "blt"
6981 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6982 (label_ref (match_operand 0 "" ""))
6989 enum machine_mode mode = GET_MODE (sh_compare_op0);
6991 if (mode != DImode && mode != SImode)
6993 rtx tmp = gen_reg_rtx (DImode);
6995 emit_insn (gen_slt (tmp));
6996 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7000 if (sh_compare_op0 != const0_rtx)
7001 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7002 if (sh_compare_op1 != const0_rtx)
7003 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7004 emit_jump_insn (gen_bgt_media (operands[0],
7005 sh_compare_op1, sh_compare_op0));
7009 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7011 rtx tmp = sh_compare_op0;
7012 sh_compare_op0 = sh_compare_op1;
7013 sh_compare_op1 = tmp;
7014 emit_insn (gen_bgt (operands[0]));
7017 from_compare (operands, GE);
7020 (define_expand "ble"
7022 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7023 (label_ref (match_operand 0 "" ""))
7030 enum machine_mode mode = GET_MODE (sh_compare_op0);
7032 if (mode != DImode && mode != SImode)
7034 rtx tmp = gen_reg_rtx (DImode);
7036 emit_insn (gen_sle (tmp));
7037 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7041 if (sh_compare_op0 != const0_rtx)
7042 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7043 if (sh_compare_op1 != const0_rtx)
7044 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7045 emit_jump_insn (gen_bge_media (operands[0],
7046 sh_compare_op1, sh_compare_op0));
7052 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7054 rtx tmp = sh_compare_op0;
7055 sh_compare_op0 = sh_compare_op1;
7056 sh_compare_op1 = tmp;
7057 emit_insn (gen_bge (operands[0]));
7060 from_compare (operands, GT);
7063 (define_expand "bge"
7065 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7066 (label_ref (match_operand 0 "" ""))
7073 enum machine_mode mode = GET_MODE (sh_compare_op0);
7075 if (mode != DImode && mode != SImode)
7077 rtx tmp = gen_reg_rtx (DImode);
7079 emit_insn (gen_sge (tmp));
7080 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7084 if (sh_compare_op0 != const0_rtx)
7085 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7086 if (sh_compare_op1 != const0_rtx)
7087 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7088 emit_jump_insn (gen_bge_media (operands[0],
7089 sh_compare_op0, sh_compare_op1));
7095 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7097 rtx tmp = sh_compare_op0;
7098 sh_compare_op0 = sh_compare_op1;
7099 sh_compare_op1 = tmp;
7100 emit_insn (gen_ble (operands[0]));
7103 from_compare (operands, GE);
7106 (define_expand "bgtu"
7108 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7109 (label_ref (match_operand 0 "" ""))
7116 enum machine_mode mode = GET_MODE (sh_compare_op0);
7118 if (sh_compare_op0 != const0_rtx)
7119 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7120 if (sh_compare_op1 != const0_rtx)
7121 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7122 emit_jump_insn (gen_bgtu_media (operands[0],
7123 sh_compare_op0, sh_compare_op1));
7127 from_compare (operands, GTU);
7130 (define_expand "bltu"
7132 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7133 (label_ref (match_operand 0 "" ""))
7140 enum machine_mode mode = GET_MODE (sh_compare_op0);
7142 if (sh_compare_op0 != const0_rtx)
7143 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7144 if (sh_compare_op1 != const0_rtx)
7145 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7146 emit_jump_insn (gen_bgtu_media (operands[0],
7147 sh_compare_op1, sh_compare_op0));
7151 from_compare (operands, GEU);
7154 (define_expand "bgeu"
7156 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7157 (label_ref (match_operand 0 "" ""))
7164 enum machine_mode mode = GET_MODE (sh_compare_op0);
7166 if (sh_compare_op0 != const0_rtx)
7167 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7168 if (sh_compare_op1 != const0_rtx)
7169 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7170 emit_jump_insn (gen_bgeu_media (operands[0],
7171 sh_compare_op0, sh_compare_op1));
7175 from_compare (operands, GEU);
7178 (define_expand "bleu"
7180 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7181 (label_ref (match_operand 0 "" ""))
7188 enum machine_mode mode = GET_MODE (sh_compare_op0);
7190 if (sh_compare_op0 != const0_rtx)
7191 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7192 if (sh_compare_op1 != const0_rtx)
7193 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7194 emit_jump_insn (gen_bgeu_media (operands[0],
7195 sh_compare_op1, sh_compare_op0));
7199 from_compare (operands, GTU);
7202 (define_expand "bunordered"
7203 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7205 (if_then_else (ne (match_dup 1) (const_int 0))
7206 (match_operand 0 "" "")
7211 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7212 operands[1] = gen_reg_rtx (DImode);
7213 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7214 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7217 ;; combiner splitter for test-and-branch on single bit in register. This
7218 ;; is endian dependent because the non-paradoxical subreg looks different
7223 (match_operator 3 "equality_comparison_operator"
7224 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7225 "extend_reg_operand" "")
7229 "const_int_operand" "")) 0)
7231 (match_operand 0 "target_operand" "")
7233 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7234 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7235 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7236 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7240 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7241 operands[6] = (GET_CODE (operands[3]) == EQ
7242 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7243 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7246 ;; ------------------------------------------------------------------------
7247 ;; Jump and linkage insns
7248 ;; ------------------------------------------------------------------------
7250 (define_insn "jump_compact"
7252 (label_ref (match_operand 0 "" "")))]
7256 /* The length is 16 if the delay slot is unfilled. */
7257 if (get_attr_length(insn) > 4)
7258 return output_far_jump(insn, operands[0]);
7260 return \"bra %l0%#\";
7262 [(set_attr "type" "jump")
7263 (set_attr "needs_delay_slot" "yes")])
7265 ;; ??? It would be much saner to explicitly use the scratch register
7266 ;; in the jump insn, and have indirect_jump_scratch only set it,
7267 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7268 ;; from the target then, as it uses simplejump_p.
7269 ;;(define_insn "jump_compact_far"
7271 ;; (label_ref (match_operand 0 "" "")))
7272 ;; (use (match_operand 1 "register_operand" "r")]
7274 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7275 ;; [(set_attr "type" "jump")
7276 ;; (set_attr "needs_delay_slot" "yes")])
7278 (define_insn "jump_media"
7280 (match_operand 0 "target_operand" "b"))]
7283 [(set_attr "type" "jump_media")])
7285 (define_expand "jump"
7287 (label_ref (match_operand 0 "" "")))]
7292 emit_jump_insn (gen_jump_compact (operands[0]));
7293 else if (TARGET_SHMEDIA)
7295 if (reload_in_progress || reload_completed)
7297 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7303 (define_insn "force_mode_for_call"
7304 [(use (reg:PSI FPSCR_REG))]
7307 [(set_attr "length" "0")
7308 (set (attr "fp_mode")
7309 (if_then_else (eq_attr "fpu_single" "yes")
7310 (const_string "single") (const_string "double")))])
7312 (define_insn "calli"
7313 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7314 (match_operand 1 "" ""))
7315 (use (reg:PSI FPSCR_REG))
7316 (clobber (reg:SI PR_REG))]
7319 [(set_attr "type" "call")
7320 (set (attr "fp_mode")
7321 (if_then_else (eq_attr "fpu_single" "yes")
7322 (const_string "single") (const_string "double")))
7323 (set_attr "needs_delay_slot" "yes")
7324 (set_attr "fp_set" "unknown")])
7326 ;; This is a pc-rel call, using bsrf, for use with PIC.
7328 (define_insn "calli_pcrel"
7329 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7330 (match_operand 1 "" ""))
7331 (use (reg:PSI FPSCR_REG))
7332 (use (reg:SI PIC_REG))
7333 (use (match_operand 2 "" ""))
7334 (clobber (reg:SI PR_REG))]
7337 [(set_attr "type" "call")
7338 (set (attr "fp_mode")
7339 (if_then_else (eq_attr "fpu_single" "yes")
7340 (const_string "single") (const_string "double")))
7341 (set_attr "needs_delay_slot" "yes")
7342 (set_attr "fp_set" "unknown")])
7344 (define_insn_and_split "call_pcrel"
7345 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7346 (match_operand 1 "" ""))
7347 (use (reg:PSI FPSCR_REG))
7348 (use (reg:SI PIC_REG))
7349 (clobber (reg:SI PR_REG))
7350 (clobber (match_scratch:SI 2 "=r"))]
7357 rtx lab = PATTERN (gen_call_site ());
7359 if (SYMBOL_REF_LOCAL_P (operands[0]))
7360 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7362 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7363 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7366 [(set_attr "type" "call")
7367 (set (attr "fp_mode")
7368 (if_then_else (eq_attr "fpu_single" "yes")
7369 (const_string "single") (const_string "double")))
7370 (set_attr "needs_delay_slot" "yes")
7371 (set_attr "fp_set" "unknown")])
7373 (define_insn "call_compact"
7374 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7375 (match_operand 1 "" ""))
7376 (match_operand 2 "immediate_operand" "n")
7377 (use (reg:SI R0_REG))
7378 (use (reg:SI R1_REG))
7379 (use (reg:PSI FPSCR_REG))
7380 (clobber (reg:SI PR_REG))]
7381 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7383 [(set_attr "type" "call")
7384 (set (attr "fp_mode")
7385 (if_then_else (eq_attr "fpu_single" "yes")
7386 (const_string "single") (const_string "double")))
7387 (set_attr "needs_delay_slot" "yes")])
7389 (define_insn "call_compact_rettramp"
7390 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7391 (match_operand 1 "" ""))
7392 (match_operand 2 "immediate_operand" "n")
7393 (use (reg:SI R0_REG))
7394 (use (reg:SI R1_REG))
7395 (use (reg:PSI FPSCR_REG))
7396 (clobber (reg:SI R10_REG))
7397 (clobber (reg:SI PR_REG))]
7398 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7400 [(set_attr "type" "call")
7401 (set (attr "fp_mode")
7402 (if_then_else (eq_attr "fpu_single" "yes")
7403 (const_string "single") (const_string "double")))
7404 (set_attr "needs_delay_slot" "yes")])
7406 (define_insn "call_media"
7407 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7408 (match_operand 1 "" ""))
7409 (clobber (reg:DI PR_MEDIA_REG))]
7412 [(set_attr "type" "jump_media")])
7414 (define_insn "call_valuei"
7415 [(set (match_operand 0 "" "=rf")
7416 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7417 (match_operand 2 "" "")))
7418 (use (reg:PSI FPSCR_REG))
7419 (clobber (reg:SI PR_REG))]
7422 [(set_attr "type" "call")
7423 (set (attr "fp_mode")
7424 (if_then_else (eq_attr "fpu_single" "yes")
7425 (const_string "single") (const_string "double")))
7426 (set_attr "needs_delay_slot" "yes")
7427 (set_attr "fp_set" "unknown")])
7429 (define_insn "call_valuei_pcrel"
7430 [(set (match_operand 0 "" "=rf")
7431 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7432 (match_operand 2 "" "")))
7433 (use (reg:PSI FPSCR_REG))
7434 (use (reg:SI PIC_REG))
7435 (use (match_operand 3 "" ""))
7436 (clobber (reg:SI PR_REG))]
7439 [(set_attr "type" "call")
7440 (set (attr "fp_mode")
7441 (if_then_else (eq_attr "fpu_single" "yes")
7442 (const_string "single") (const_string "double")))
7443 (set_attr "needs_delay_slot" "yes")
7444 (set_attr "fp_set" "unknown")])
7446 (define_insn_and_split "call_value_pcrel"
7447 [(set (match_operand 0 "" "=rf")
7448 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7449 (match_operand 2 "" "")))
7450 (use (reg:PSI FPSCR_REG))
7451 (use (reg:SI PIC_REG))
7452 (clobber (reg:SI PR_REG))
7453 (clobber (match_scratch:SI 3 "=r"))]
7460 rtx lab = PATTERN (gen_call_site ());
7462 if (SYMBOL_REF_LOCAL_P (operands[1]))
7463 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7465 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7466 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7470 [(set_attr "type" "call")
7471 (set (attr "fp_mode")
7472 (if_then_else (eq_attr "fpu_single" "yes")
7473 (const_string "single") (const_string "double")))
7474 (set_attr "needs_delay_slot" "yes")
7475 (set_attr "fp_set" "unknown")])
7477 (define_insn "call_value_compact"
7478 [(set (match_operand 0 "" "=rf")
7479 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7480 (match_operand 2 "" "")))
7481 (match_operand 3 "immediate_operand" "n")
7482 (use (reg:SI R0_REG))
7483 (use (reg:SI R1_REG))
7484 (use (reg:PSI FPSCR_REG))
7485 (clobber (reg:SI PR_REG))]
7486 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7488 [(set_attr "type" "call")
7489 (set (attr "fp_mode")
7490 (if_then_else (eq_attr "fpu_single" "yes")
7491 (const_string "single") (const_string "double")))
7492 (set_attr "needs_delay_slot" "yes")])
7494 (define_insn "call_value_compact_rettramp"
7495 [(set (match_operand 0 "" "=rf")
7496 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7497 (match_operand 2 "" "")))
7498 (match_operand 3 "immediate_operand" "n")
7499 (use (reg:SI R0_REG))
7500 (use (reg:SI R1_REG))
7501 (use (reg:PSI FPSCR_REG))
7502 (clobber (reg:SI R10_REG))
7503 (clobber (reg:SI PR_REG))]
7504 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7506 [(set_attr "type" "call")
7507 (set (attr "fp_mode")
7508 (if_then_else (eq_attr "fpu_single" "yes")
7509 (const_string "single") (const_string "double")))
7510 (set_attr "needs_delay_slot" "yes")])
7512 (define_insn "call_value_media"
7513 [(set (match_operand 0 "" "=rf")
7514 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7515 (match_operand 2 "" "")))
7516 (clobber (reg:DI PR_MEDIA_REG))]
7519 [(set_attr "type" "jump_media")])
7521 (define_expand "call"
7522 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7523 (match_operand 1 "" ""))
7524 (match_operand 2 "" "")
7525 (use (reg:PSI FPSCR_REG))
7526 (clobber (reg:SI PR_REG))])]
7532 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7533 emit_call_insn (gen_call_media (operands[0], operands[1]));
7536 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7538 rtx cookie_rtx = operands[2];
7539 long cookie = INTVAL (cookie_rtx);
7540 rtx func = XEXP (operands[0], 0);
7545 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7547 rtx reg = gen_reg_rtx (Pmode);
7549 emit_insn (gen_symGOTPLT2reg (reg, func));
7553 func = legitimize_pic_address (func, Pmode, 0);
7556 r0 = gen_rtx_REG (SImode, R0_REG);
7557 r1 = gen_rtx_REG (SImode, R1_REG);
7559 /* Since such a call function may use all call-clobbered
7560 registers, we force a mode switch earlier, so that we don't
7561 run out of registers when adjusting fpscr for the call. */
7562 emit_insn (gen_force_mode_for_call ());
7565 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7567 operands[0] = force_reg (SImode, operands[0]);
7569 emit_move_insn (r0, func);
7570 emit_move_insn (r1, cookie_rtx);
7572 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7573 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7576 emit_call_insn (gen_call_compact (operands[0], operands[1],
7581 else if (TARGET_SHCOMPACT && flag_pic
7582 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7583 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7585 rtx reg = gen_reg_rtx (Pmode);
7587 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7588 XEXP (operands[0], 0) = reg;
7590 if (flag_pic && TARGET_SH2
7591 && GET_CODE (operands[0]) == MEM
7592 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7594 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7599 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7600 operands[1] = operands[2];
7603 emit_call_insn (gen_calli (operands[0], operands[1]));
7607 (define_insn "call_pop_compact"
7608 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7609 (match_operand 1 "" ""))
7610 (match_operand 2 "immediate_operand" "n")
7611 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7612 (match_operand 3 "immediate_operand" "n")))
7613 (use (reg:SI R0_REG))
7614 (use (reg:SI R1_REG))
7615 (use (reg:PSI FPSCR_REG))
7616 (clobber (reg:SI PR_REG))]
7617 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7619 [(set_attr "type" "call")
7620 (set (attr "fp_mode")
7621 (if_then_else (eq_attr "fpu_single" "yes")
7622 (const_string "single") (const_string "double")))
7623 (set_attr "needs_delay_slot" "yes")])
7625 (define_insn "call_pop_compact_rettramp"
7626 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7627 (match_operand 1 "" ""))
7628 (match_operand 2 "immediate_operand" "n")
7629 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7630 (match_operand 3 "immediate_operand" "n")))
7631 (use (reg:SI R0_REG))
7632 (use (reg:SI R1_REG))
7633 (use (reg:PSI FPSCR_REG))
7634 (clobber (reg:SI R10_REG))
7635 (clobber (reg:SI PR_REG))]
7636 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7638 [(set_attr "type" "call")
7639 (set (attr "fp_mode")
7640 (if_then_else (eq_attr "fpu_single" "yes")
7641 (const_string "single") (const_string "double")))
7642 (set_attr "needs_delay_slot" "yes")])
7644 (define_expand "call_pop"
7645 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7646 (match_operand 1 "" ""))
7647 (match_operand 2 "" "")
7648 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7649 (match_operand 3 "" "")))])]
7658 gcc_assert (operands[2] && INTVAL (operands[2]));
7659 cookie_rtx = operands[2];
7660 cookie = INTVAL (cookie_rtx);
7661 func = XEXP (operands[0], 0);
7665 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7667 rtx reg = gen_reg_rtx (Pmode);
7668 emit_insn (gen_symGOTPLT2reg (reg, func));
7672 func = legitimize_pic_address (func, Pmode, 0);
7675 r0 = gen_rtx_REG (SImode, R0_REG);
7676 r1 = gen_rtx_REG (SImode, R1_REG);
7678 /* Since such a call function may use all call-clobbered
7679 registers, we force a mode switch earlier, so that we don't
7680 run out of registers when adjusting fpscr for the call. */
7681 emit_insn (gen_force_mode_for_call ());
7683 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7685 operands[0] = force_reg (SImode, operands[0]);
7687 emit_move_insn (r0, func);
7688 emit_move_insn (r1, cookie_rtx);
7690 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7691 emit_call_insn (gen_call_pop_compact_rettramp
7692 (operands[0], operands[1], operands[2], operands[3]));
7694 emit_call_insn (gen_call_pop_compact
7695 (operands[0], operands[1], operands[2], operands[3]));
7700 (define_expand "call_value"
7701 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7702 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7703 (match_operand 2 "" "")))
7704 (match_operand 3 "" "")
7705 (use (reg:PSI FPSCR_REG))
7706 (clobber (reg:SI PR_REG))])]
7712 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7713 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7717 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7719 rtx cookie_rtx = operands[3];
7720 long cookie = INTVAL (cookie_rtx);
7721 rtx func = XEXP (operands[1], 0);
7726 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7728 rtx reg = gen_reg_rtx (Pmode);
7730 emit_insn (gen_symGOTPLT2reg (reg, func));
7734 func = legitimize_pic_address (func, Pmode, 0);
7737 r0 = gen_rtx_REG (SImode, R0_REG);
7738 r1 = gen_rtx_REG (SImode, R1_REG);
7740 /* Since such a call function may use all call-clobbered
7741 registers, we force a mode switch earlier, so that we don't
7742 run out of registers when adjusting fpscr for the call. */
7743 emit_insn (gen_force_mode_for_call ());
7746 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7748 operands[1] = force_reg (SImode, operands[1]);
7750 emit_move_insn (r0, func);
7751 emit_move_insn (r1, cookie_rtx);
7753 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7754 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7759 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7760 operands[2], operands[3]));
7764 else if (TARGET_SHCOMPACT && flag_pic
7765 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7766 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7768 rtx reg = gen_reg_rtx (Pmode);
7770 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7771 XEXP (operands[1], 0) = reg;
7773 if (flag_pic && TARGET_SH2
7774 && GET_CODE (operands[1]) == MEM
7775 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7777 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7782 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7784 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7788 (define_insn "sibcalli"
7789 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7790 (match_operand 1 "" ""))
7791 (use (reg:PSI FPSCR_REG))
7795 [(set_attr "needs_delay_slot" "yes")
7796 (set (attr "fp_mode")
7797 (if_then_else (eq_attr "fpu_single" "yes")
7798 (const_string "single") (const_string "double")))
7799 (set_attr "type" "jump_ind")])
7801 (define_insn "sibcalli_pcrel"
7802 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7803 (match_operand 1 "" ""))
7804 (use (match_operand 2 "" ""))
7805 (use (reg:PSI FPSCR_REG))
7809 [(set_attr "needs_delay_slot" "yes")
7810 (set (attr "fp_mode")
7811 (if_then_else (eq_attr "fpu_single" "yes")
7812 (const_string "single") (const_string "double")))
7813 (set_attr "type" "jump_ind")])
7815 ;; This uses an unspec to describe that the symbol_ref is very close.
7816 (define_insn "sibcalli_thunk"
7817 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7819 (match_operand 1 "" ""))
7820 (use (reg:PSI FPSCR_REG))
7824 [(set_attr "needs_delay_slot" "yes")
7825 (set (attr "fp_mode")
7826 (if_then_else (eq_attr "fpu_single" "yes")
7827 (const_string "single") (const_string "double")))
7828 (set_attr "type" "jump")
7829 (set_attr "length" "2")])
7831 (define_insn_and_split "sibcall_pcrel"
7832 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7833 (match_operand 1 "" ""))
7834 (use (reg:PSI FPSCR_REG))
7835 (clobber (match_scratch:SI 2 "=k"))
7843 rtx lab = PATTERN (gen_call_site ());
7846 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7847 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7849 SIBLING_CALL_P (call_insn) = 1;
7852 [(set_attr "needs_delay_slot" "yes")
7853 (set (attr "fp_mode")
7854 (if_then_else (eq_attr "fpu_single" "yes")
7855 (const_string "single") (const_string "double")))
7856 (set_attr "type" "jump_ind")])
7858 (define_insn "sibcall_compact"
7859 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7860 (match_operand 1 "" ""))
7862 (use (match_operand:SI 2 "register_operand" "z,x"))
7863 (use (reg:SI R1_REG))
7864 (use (reg:PSI FPSCR_REG))
7865 ;; We want to make sure the `x' above will only match MACH_REG
7866 ;; because sibcall_epilogue may clobber MACL_REG.
7867 (clobber (reg:SI MACL_REG))]
7871 jmp @%0\\n sts %2, r0"
7872 [(set_attr "needs_delay_slot" "yes,no")
7873 (set_attr "length" "2,4")
7874 (set (attr "fp_mode") (const_string "single"))
7875 (set_attr "type" "jump_ind")])
7877 (define_insn "sibcall_media"
7878 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7879 (match_operand 1 "" ""))
7880 (use (reg:SI PR_MEDIA_REG))
7884 [(set_attr "type" "jump_media")])
7886 (define_expand "sibcall"
7888 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7889 (match_operand 1 "" ""))
7890 (match_operand 2 "" "")
7891 (use (reg:PSI FPSCR_REG))
7898 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7899 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7902 else if (TARGET_SHCOMPACT && operands[2]
7903 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7905 rtx cookie_rtx = operands[2];
7906 long cookie = INTVAL (cookie_rtx);
7907 rtx func = XEXP (operands[0], 0);
7912 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7914 rtx reg = gen_reg_rtx (Pmode);
7916 emit_insn (gen_symGOT2reg (reg, func));
7920 func = legitimize_pic_address (func, Pmode, 0);
7923 /* FIXME: if we could tell whether all argument registers are
7924 already taken, we could decide whether to force the use of
7925 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7926 simple way to tell. We could use the CALL_COOKIE, but we
7927 can't currently tell a register used for regular argument
7928 passing from one that is unused. If we leave it up to reload
7929 to decide which register to use, it seems to always choose
7930 R0_REG, which leaves no available registers in SIBCALL_REGS
7931 to hold the address of the trampoline. */
7932 mach = gen_rtx_REG (SImode, MACH_REG);
7933 r1 = gen_rtx_REG (SImode, R1_REG);
7935 /* Since such a call function may use all call-clobbered
7936 registers, we force a mode switch earlier, so that we don't
7937 run out of registers when adjusting fpscr for the call. */
7938 emit_insn (gen_force_mode_for_call ());
7941 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7943 operands[0] = force_reg (SImode, operands[0]);
7945 /* We don't need a return trampoline, since the callee will
7946 return directly to the upper caller. */
7947 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7949 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7950 cookie_rtx = GEN_INT (cookie);
7953 emit_move_insn (mach, func);
7954 emit_move_insn (r1, cookie_rtx);
7956 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7959 else if (TARGET_SHCOMPACT && flag_pic
7960 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7961 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7963 rtx reg = gen_reg_rtx (Pmode);
7965 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7966 XEXP (operands[0], 0) = reg;
7968 if (flag_pic && TARGET_SH2
7969 && GET_CODE (operands[0]) == MEM
7970 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7971 /* The PLT needs the PIC register, but the epilogue would have
7972 to restore it, so we can only use PC-relative PIC calls for
7973 static functions. */
7974 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7976 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7980 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7982 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7986 (define_expand "sibcall_value"
7987 [(set (match_operand 0 "" "")
7988 (call (match_operand 1 "" "")
7989 (match_operand 2 "" "")))
7990 (match_operand 3 "" "")]
7994 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7998 (define_insn "call_value_pop_compact"
7999 [(set (match_operand 0 "" "=rf")
8000 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8001 (match_operand 2 "" "")))
8002 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8003 (match_operand 4 "immediate_operand" "n")))
8004 (match_operand 3 "immediate_operand" "n")
8005 (use (reg:SI R0_REG))
8006 (use (reg:SI R1_REG))
8007 (use (reg:PSI FPSCR_REG))
8008 (clobber (reg:SI PR_REG))]
8009 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8011 [(set_attr "type" "call")
8012 (set (attr "fp_mode")
8013 (if_then_else (eq_attr "fpu_single" "yes")
8014 (const_string "single") (const_string "double")))
8015 (set_attr "needs_delay_slot" "yes")])
8017 (define_insn "call_value_pop_compact_rettramp"
8018 [(set (match_operand 0 "" "=rf")
8019 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8020 (match_operand 2 "" "")))
8021 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8022 (match_operand 4 "immediate_operand" "n")))
8023 (match_operand 3 "immediate_operand" "n")
8024 (use (reg:SI R0_REG))
8025 (use (reg:SI R1_REG))
8026 (use (reg:PSI FPSCR_REG))
8027 (clobber (reg:SI R10_REG))
8028 (clobber (reg:SI PR_REG))]
8029 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8031 [(set_attr "type" "call")
8032 (set (attr "fp_mode")
8033 (if_then_else (eq_attr "fpu_single" "yes")
8034 (const_string "single") (const_string "double")))
8035 (set_attr "needs_delay_slot" "yes")])
8037 (define_expand "call_value_pop"
8038 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8039 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8040 (match_operand 2 "" "")))
8041 (match_operand 3 "" "")
8042 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8043 (match_operand 4 "" "")))])]
8052 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8053 cookie_rtx = operands[3];
8054 cookie = INTVAL (cookie_rtx);
8055 func = XEXP (operands[1], 0);
8059 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8061 rtx reg = gen_reg_rtx (Pmode);
8063 emit_insn (gen_symGOTPLT2reg (reg, func));
8067 func = legitimize_pic_address (func, Pmode, 0);
8070 r0 = gen_rtx_REG (SImode, R0_REG);
8071 r1 = gen_rtx_REG (SImode, R1_REG);
8073 /* Since such a call function may use all call-clobbered
8074 registers, we force a mode switch earlier, so that we don't
8075 run out of registers when adjusting fpscr for the call. */
8076 emit_insn (gen_force_mode_for_call ());
8078 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8080 operands[1] = force_reg (SImode, operands[1]);
8082 emit_move_insn (r0, func);
8083 emit_move_insn (r1, cookie_rtx);
8085 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8086 emit_call_insn (gen_call_value_pop_compact_rettramp
8087 (operands[0], operands[1], operands[2],
8088 operands[3], operands[4]));
8090 emit_call_insn (gen_call_value_pop_compact
8091 (operands[0], operands[1], operands[2],
8092 operands[3], operands[4]));
8097 (define_expand "sibcall_epilogue"
8102 sh_expand_epilogue (1);
8103 if (TARGET_SHCOMPACT)
8107 /* If epilogue clobbers r0, preserve it in macl. */
8108 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8109 if ((set = single_set (insn))
8110 && GET_CODE (SET_DEST (set)) == REG
8111 && REGNO (SET_DEST (set)) == R0_REG)
8113 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8114 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8117 /* We can't tell at this point whether the sibcall is a
8118 sibcall_compact and, if it is, whether it uses r0 or
8119 mach as operand 2, so let the instructions that
8120 preserve r0 be optimized away if r0 turns out to be
8122 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8123 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8125 i = emit_move_insn (r0, tmp);
8126 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8134 (define_insn "indirect_jump_compact"
8136 (match_operand:SI 0 "arith_reg_operand" "r"))]
8139 [(set_attr "needs_delay_slot" "yes")
8140 (set_attr "type" "jump_ind")])
8142 (define_expand "indirect_jump"
8144 (match_operand 0 "register_operand" ""))]
8148 if (GET_MODE (operands[0]) != Pmode)
8149 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8152 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8153 ;; which can be present in structured code from indirect jumps which can not
8154 ;; be present in structured code. This allows -fprofile-arcs to work.
8156 ;; For SH1 processors.
8157 (define_insn "casesi_jump_1"
8159 (match_operand:SI 0 "register_operand" "r"))
8160 (use (label_ref (match_operand 1 "" "")))]
8163 [(set_attr "needs_delay_slot" "yes")
8164 (set_attr "type" "jump_ind")])
8166 ;; For all later processors.
8167 (define_insn "casesi_jump_2"
8168 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8169 (label_ref (match_operand 1 "" ""))))
8170 (use (label_ref (match_operand 2 "" "")))]
8172 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8174 [(set_attr "needs_delay_slot" "yes")
8175 (set_attr "type" "jump_ind")])
8177 (define_insn "casesi_jump_media"
8178 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8179 (use (label_ref (match_operand 1 "" "")))]
8182 [(set_attr "type" "jump_media")])
8184 ;; Call subroutine returning any type.
8185 ;; ??? This probably doesn't work.
8187 (define_expand "untyped_call"
8188 [(parallel [(call (match_operand 0 "" "")
8190 (match_operand 1 "" "")
8191 (match_operand 2 "" "")])]
8192 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8197 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8199 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8201 rtx set = XVECEXP (operands[2], 0, i);
8202 emit_move_insn (SET_DEST (set), SET_SRC (set));
8205 /* The optimizer does not know that the call sets the function value
8206 registers we stored in the result block. We avoid problems by
8207 claiming that all hard registers are used and clobbered at this
8209 emit_insn (gen_blockage ());
8214 ;; ------------------------------------------------------------------------
8216 ;; ------------------------------------------------------------------------
8219 [(set (reg:SI T_REG)
8220 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8221 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8224 [(set_attr "type" "arith")])
8231 ;; Load address of a label. This is only generated by the casesi expand,
8232 ;; and by machine_dependent_reorg (fixing up fp moves).
8233 ;; This must use unspec, because this only works for labels that are
8237 [(set (reg:SI R0_REG)
8238 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8241 [(set_attr "in_delay_slot" "no")
8242 (set_attr "type" "arith")])
8244 ;; machine_dependent_reorg will make this a `mova'.
8245 (define_insn "mova_const"
8246 [(set (reg:SI R0_REG)
8247 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8250 [(set_attr "in_delay_slot" "no")
8251 (set_attr "type" "arith")])
8253 (define_expand "GOTaddr2picreg"
8254 [(set (reg:SI R0_REG)
8255 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8257 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8258 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8261 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8262 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8266 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8267 rtx pic = operands[0];
8268 rtx lab = PATTERN (gen_call_site ());
8271 equiv = operands[1];
8272 operands[1] = gen_rtx_MINUS (Pmode,
8276 gen_rtx_MINUS (Pmode,
8277 gen_rtx_CONST (Pmode,
8280 operands[1] = gen_sym2PIC (operands[1]);
8281 PUT_MODE (operands[1], Pmode);
8283 if (Pmode == SImode)
8285 emit_insn (gen_movsi_const (pic, operands[1]));
8286 emit_insn (gen_ptrel_si (tr, pic, lab));
8290 emit_insn (gen_movdi_const (pic, operands[1]));
8291 emit_insn (gen_ptrel_di (tr, pic, lab));
8294 insn = emit_move_insn (operands[0], tr);
8296 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8305 [(set (match_operand 0 "target_reg_operand" "=b")
8306 (const (unspec [(match_operand 1 "" "Csy")]
8307 UNSPEC_DATALABEL)))]
8308 "TARGET_SHMEDIA && flag_pic
8309 && EXTRA_CONSTRAINT_Csy (operands[1])"
8310 "ptb/u datalabel %1, %0"
8311 [(set_attr "type" "ptabs_media")
8312 (set_attr "length" "*")])
8314 (define_insn "ptrel_si"
8315 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8316 (plus:SI (match_operand:SI 1 "register_operand" "r")
8318 (match_operand:SI 2 "" "")]
8320 "%O2: ptrel/u %1, %0"
8321 [(set_attr "type" "ptabs_media")])
8323 (define_insn "ptrel_di"
8324 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8325 (plus:DI (match_operand:DI 1 "register_operand" "r")
8327 (match_operand:DI 2 "" "")]
8329 "%O2: ptrel/u %1, %0"
8330 [(set_attr "type" "ptabs_media")])
8332 (define_expand "builtin_setjmp_receiver"
8333 [(match_operand 0 "" "")]
8337 emit_insn (gen_GOTaddr2picreg ());
8341 (define_expand "call_site"
8342 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8346 static HOST_WIDE_INT i = 0;
8347 operands[0] = GEN_INT (i);
8351 (define_expand "sym_label2reg"
8352 [(set (match_operand:SI 0 "" "")
8355 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8358 (match_operand:SI 2 "" "")
8362 (define_expand "symGOT_load"
8363 [(set (match_dup 2) (match_operand 1 "" ""))
8364 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8365 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8371 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8372 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8376 rtx reg = operands[2];
8378 if (Pmode == DImode)
8381 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8383 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8388 emit_insn (gen_movsi_const (reg, operands[1]));
8390 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8394 emit_move_insn (operands[2], operands[1]);
8396 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8398 gen_rtx_REG (Pmode, PIC_REG)));
8400 /* N.B. This is not constant for a GOTPLT relocation. */
8401 mem = gen_rtx_MEM (Pmode, operands[3]);
8402 MEM_NOTRAP_P (mem) = 1;
8403 /* ??? Should we have a special alias set for the GOT? */
8404 insn = emit_move_insn (operands[0], mem);
8406 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8413 (define_expand "sym2GOT"
8414 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8418 (define_expand "symGOT2reg"
8419 [(match_operand 0 "" "") (match_operand 1 "" "")]
8425 gotsym = gen_sym2GOT (operands[1]);
8426 PUT_MODE (gotsym, Pmode);
8427 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8429 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8434 (define_expand "symGOTPLT2reg"
8435 [(match_operand 0 "" "") (match_operand 1 "" "")]
8439 rtx pltsym = gen_rtx_CONST (Pmode,
8440 gen_rtx_UNSPEC (Pmode,
8441 gen_rtvec (1, operands[1]),
8443 emit_insn (gen_symGOT_load (operands[0], pltsym));
8447 (define_expand "sym2GOTOFF"
8448 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8452 (define_expand "symGOTOFF2reg"
8453 [(match_operand 0 "" "") (match_operand 1 "" "")]
8457 rtx gotoffsym, insn;
8458 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8460 gotoffsym = gen_sym2GOTOFF (operands[1]);
8461 PUT_MODE (gotoffsym, Pmode);
8462 emit_move_insn (t, gotoffsym);
8463 insn = emit_move_insn (operands[0],
8464 gen_rtx_PLUS (Pmode, t,
8465 gen_rtx_REG (Pmode, PIC_REG)));
8467 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8473 (define_expand "symPLT_label2reg"
8474 [(set (match_operand:SI 0 "" "")
8477 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8481 (match_operand:SI 2 "" "")
8483 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8484 ;; Even though the PIC register is not really used by the call
8485 ;; sequence in which this is expanded, the PLT code assumes the PIC
8486 ;; register is set, so we must not skip its initialization. Since
8487 ;; we only use this expand as part of calling sequences, and never
8488 ;; to take the address of a function, this is the best point to
8489 ;; insert the (use). Using the PLT to take the address of a
8490 ;; function would be wrong, not only because the PLT entry could
8491 ;; then be called from a function that doesn't initialize the PIC
8492 ;; register to the proper GOT, but also because pointers to the
8493 ;; same function might not compare equal, should they be set by
8494 ;; different shared libraries.
8495 (use (reg:SI PIC_REG))]
8499 (define_expand "sym2PIC"
8500 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8504 ;; TLS code generation.
8505 ;; ??? this should be a define_insn_and_split
8506 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8507 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8510 (define_insn "tls_global_dynamic"
8511 [(set (match_operand:SI 0 "register_operand" "=&z")
8512 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8515 (use (reg:PSI FPSCR_REG))
8516 (use (reg:SI PIC_REG))
8517 (clobber (reg:SI PR_REG))
8518 (clobber (scratch:SI))]
8524 \\tmova\\t2f,r0\\n\\
8525 \\tmov.l\\t2f,r1\\n\\
8528 \\tadd\\tr12,r4\\n\\
8532 1:\\t.long\\t%a1@TLSGD\\n\\
8533 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8536 [(set_attr "type" "tls_load")
8537 (set_attr "length" "26")])
8539 (define_insn "tls_local_dynamic"
8540 [(set (match_operand:SI 0 "register_operand" "=&z")
8541 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8544 (use (reg:PSI FPSCR_REG))
8545 (use (reg:SI PIC_REG))
8546 (clobber (reg:SI PR_REG))
8547 (clobber (scratch:SI))]
8553 \\tmova\\t2f,r0\\n\\
8554 \\tmov.l\\t2f,r1\\n\\
8557 \\tadd\\tr12,r4\\n\\
8561 1:\\t.long\\t%a1@TLSLDM\\n\\
8562 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8565 [(set_attr "type" "tls_load")
8566 (set_attr "length" "26")])
8568 (define_expand "sym2DTPOFF"
8569 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8573 (define_expand "symDTPOFF2reg"
8574 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8578 rtx dtpoffsym, insn;
8579 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8581 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8582 PUT_MODE (dtpoffsym, Pmode);
8583 emit_move_insn (t, dtpoffsym);
8584 insn = emit_move_insn (operands[0],
8585 gen_rtx_PLUS (Pmode, t, operands[2]));
8589 (define_expand "sym2GOTTPOFF"
8590 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8594 (define_insn "tls_initial_exec"
8595 [(set (match_operand:SI 0 "register_operand" "=&r")
8596 (unspec:SI [(match_operand:SI 1 "" "")]
8598 (use (reg:SI GBR_REG))
8599 (use (reg:SI PIC_REG))
8600 (clobber (reg:SI R0_REG))]
8606 \\tstc\\tgbr,%0\\n\\
8607 \\tmov.l\\t@(r0,r12),r0\\n\\
8611 1:\\t.long\\t%a1\\n\\
8614 [(set_attr "type" "tls_load")
8615 (set_attr "length" "16")])
8617 (define_expand "sym2TPOFF"
8618 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8622 (define_expand "symTPOFF2reg"
8623 [(match_operand 0 "" "") (match_operand 1 "" "")]
8629 tpoffsym = gen_sym2TPOFF (operands[1]);
8630 PUT_MODE (tpoffsym, Pmode);
8631 insn = emit_move_insn (operands[0], tpoffsym);
8635 (define_insn "load_gbr"
8636 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8637 (use (reg:SI GBR_REG))]
8640 [(set_attr "type" "tls_load")])
8642 ;; case instruction for switch statements.
8644 ;; Operand 0 is index
8645 ;; operand 1 is the minimum bound
8646 ;; operand 2 is the maximum bound - minimum bound + 1
8647 ;; operand 3 is CODE_LABEL for the table;
8648 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8650 (define_expand "casesi"
8651 [(match_operand:SI 0 "arith_reg_operand" "")
8652 (match_operand:SI 1 "arith_reg_operand" "")
8653 (match_operand:SI 2 "arith_reg_operand" "")
8654 (match_operand 3 "" "") (match_operand 4 "" "")]
8658 rtx reg = gen_reg_rtx (SImode);
8659 rtx reg2 = gen_reg_rtx (SImode);
8662 rtx reg = gen_reg_rtx (DImode);
8663 rtx reg2 = gen_reg_rtx (DImode);
8664 rtx reg3 = gen_reg_rtx (Pmode);
8665 rtx reg4 = gen_reg_rtx (Pmode);
8666 rtx reg5 = gen_reg_rtx (Pmode);
8669 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8670 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8671 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8673 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8674 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8675 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8676 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8677 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8678 (Pmode, operands[3])));
8679 /* Messy: can we subreg to clean this up? */
8680 if (Pmode == DImode)
8681 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8683 load = gen_casesi_load_media (reg4,
8684 gen_rtx_SUBREG (DImode, reg3, 0),
8686 PUT_MODE (SET_SRC (load), Pmode);
8688 /* ??? The following add could be eliminated if we used ptrel. */
8689 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8690 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8694 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8695 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8696 /* If optimizing, casesi_worker depends on the mode of the instruction
8697 before label it 'uses' - operands[3]. */
8698 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8700 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8702 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8704 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8705 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8706 operands[3], but to lab. We will fix this up in
8707 machine_dependent_reorg. */
8712 (define_expand "casesi_0"
8713 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8714 (set (match_dup 4) (minus:SI (match_dup 4)
8715 (match_operand:SI 1 "arith_operand" "")))
8717 (gtu:SI (match_dup 4)
8718 (match_operand:SI 2 "arith_reg_operand" "")))
8720 (if_then_else (ne (reg:SI T_REG)
8722 (label_ref (match_operand 3 "" ""))
8727 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8728 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8729 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8731 (define_insn "casesi_worker_0"
8732 [(set (match_operand:SI 0 "register_operand" "=r,r")
8733 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8734 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8735 (clobber (match_scratch:SI 3 "=X,1"))
8736 (clobber (match_scratch:SI 4 "=&z,z"))]
8741 [(set (match_operand:SI 0 "register_operand" "")
8742 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8743 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8744 (clobber (match_scratch:SI 3 ""))
8745 (clobber (match_scratch:SI 4 ""))]
8746 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8747 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8748 (parallel [(set (match_dup 0)
8749 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8750 (label_ref (match_dup 2))] UNSPEC_CASESI))
8751 (clobber (match_dup 3))])
8752 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8753 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8756 [(set (match_operand:SI 0 "register_operand" "")
8757 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8758 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8759 (clobber (match_scratch:SI 3 ""))
8760 (clobber (match_scratch:SI 4 ""))]
8761 "TARGET_SH2 && reload_completed"
8762 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8763 (parallel [(set (match_dup 0)
8764 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8765 (label_ref (match_dup 2))] UNSPEC_CASESI))
8766 (clobber (match_dup 3))])]
8767 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8769 (define_insn "casesi_worker_1"
8770 [(set (match_operand:SI 0 "register_operand" "=r,r")
8771 (unspec:SI [(reg:SI R0_REG)
8772 (match_operand:SI 1 "register_operand" "0,r")
8773 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8774 (clobber (match_scratch:SI 3 "=X,1"))]
8778 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8780 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8782 switch (GET_MODE (diff_vec))
8785 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8787 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8789 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8790 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8791 return \"mov.b @(r0,%1),%0\";
8796 [(set_attr "length" "4")])
8798 (define_insn "casesi_worker_2"
8799 [(set (match_operand:SI 0 "register_operand" "=r,r")
8800 (unspec:SI [(reg:SI R0_REG)
8801 (match_operand:SI 1 "register_operand" "0,r")
8802 (label_ref (match_operand 2 "" ""))
8803 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8804 (clobber (match_operand:SI 4 "" "=X,1"))]
8805 "TARGET_SH2 && reload_completed && flag_pic"
8808 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8811 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8813 switch (GET_MODE (diff_vec))
8816 output_asm_insn (\"shll2 %1\", operands);
8817 load = \"mov.l @(r0,%1),%0\"; break;
8819 output_asm_insn (\"add %1,%1\", operands);
8820 load = \"mov.w @(r0,%1),%0\"; break;
8822 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8823 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8825 load = \"mov.b @(r0,%1),%0\";
8830 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8833 [(set_attr "length" "8")])
8835 (define_insn "casesi_shift_media"
8836 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8837 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8838 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8843 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8845 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8847 switch (GET_MODE (diff_vec))
8850 return \"shlli %1, 2, %0\";
8852 return \"shlli %1, 1, %0\";
8854 if (rtx_equal_p (operands[0], operands[1]))
8856 return \"add %1, r63, %0\";
8861 [(set_attr "type" "arith_media")])
8863 (define_insn "casesi_load_media"
8864 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8865 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8866 (match_operand:DI 2 "arith_reg_operand" "r")
8867 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8871 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8873 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8875 switch (GET_MODE (diff_vec))
8878 return \"ldx.l %1, %2, %0\";
8881 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8882 return \"ldx.uw %1, %2, %0\";
8884 return \"ldx.w %1, %2, %0\";
8886 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8887 return \"ldx.ub %1, %2, %0\";
8888 return \"ldx.b %1, %2, %0\";
8893 [(set_attr "type" "load_media")])
8895 (define_expand "return"
8897 "reload_completed && ! sh_need_epilogue ()"
8902 emit_jump_insn (gen_return_media ());
8906 if (TARGET_SHCOMPACT
8907 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8909 emit_jump_insn (gen_shcompact_return_tramp ());
8914 (define_insn "*return_i"
8916 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8917 && (current_function_args_info.call_cookie
8918 & CALL_COOKIE_RET_TRAMP (1)))
8920 && lookup_attribute (\"trap_exit\",
8921 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8923 [(set_attr "type" "return")
8924 (set_attr "needs_delay_slot" "yes")])
8926 ;; trapa has no delay slot.
8927 (define_insn "*return_trapa"
8929 "TARGET_SH1 && !TARGET_SHCOMPACT
8930 && reload_completed"
8932 [(set_attr "type" "return")])
8934 (define_expand "shcompact_return_tramp"
8937 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8940 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8942 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8943 emit_jump_insn (gen_shcompact_return_tramp_i ());
8947 (define_insn "shcompact_return_tramp_i"
8948 [(parallel [(return) (use (reg:SI R0_REG))])]
8950 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8952 [(set_attr "type" "jump_ind")
8953 (set_attr "needs_delay_slot" "yes")])
8955 (define_insn "return_media_i"
8956 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8957 "TARGET_SHMEDIA && reload_completed"
8959 [(set_attr "type" "jump_media")])
8961 (define_insn "return_media_rte"
8963 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8965 [(set_attr "type" "jump_media")])
8967 (define_expand "return_media"
8969 "TARGET_SHMEDIA && reload_completed"
8972 int tr_regno = sh_media_register_for_return ();
8975 if (current_function_interrupt)
8977 emit_jump_insn (gen_return_media_rte ());
8982 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8984 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8986 tr = gen_rtx_REG (Pmode, tr_regno);
8987 emit_move_insn (tr, r18);
8990 tr = gen_rtx_REG (Pmode, tr_regno);
8992 emit_jump_insn (gen_return_media_i (tr));
8996 (define_insn "shcompact_preserve_incoming_args"
8997 [(set (match_operand:SI 0 "register_operand" "+r")
8998 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9001 [(set_attr "length" "0")])
9003 (define_insn "shcompact_incoming_args"
9004 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9005 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9006 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9007 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9008 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9009 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9010 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9011 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9012 (set (mem:BLK (reg:SI MACL_REG))
9013 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9014 (use (reg:SI R0_REG))
9015 (clobber (reg:SI R0_REG))
9016 (clobber (reg:SI MACL_REG))
9017 (clobber (reg:SI MACH_REG))
9018 (clobber (reg:SI PR_REG))]
9021 [(set_attr "needs_delay_slot" "yes")])
9023 (define_insn "shmedia_save_restore_regs_compact"
9024 [(set (reg:SI SP_REG)
9025 (plus:SI (reg:SI SP_REG)
9026 (match_operand:SI 0 "immediate_operand" "i")))
9027 (use (reg:SI R0_REG))
9028 (clobber (reg:SI PR_REG))]
9030 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9031 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9033 [(set_attr "needs_delay_slot" "yes")])
9035 (define_expand "prologue"
9038 "sh_expand_prologue (); DONE;")
9040 (define_expand "epilogue"
9045 sh_expand_epilogue (0);
9046 emit_jump_insn (gen_return ());
9050 (define_expand "eh_return"
9051 [(use (match_operand 0 "register_operand" ""))]
9054 rtx ra = operands[0];
9056 if (TARGET_SHMEDIA64)
9057 emit_insn (gen_eh_set_ra_di (ra));
9059 emit_insn (gen_eh_set_ra_si (ra));
9064 ;; Clobber the return address on the stack. We can't expand this
9065 ;; until we know where it will be put in the stack frame.
9067 (define_insn "eh_set_ra_si"
9068 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9069 (clobber (match_scratch:SI 1 "=&r"))]
9070 "! TARGET_SHMEDIA64"
9073 (define_insn "eh_set_ra_di"
9074 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9075 (clobber (match_scratch:DI 1 "=&r"))]
9080 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9081 (clobber (match_scratch 1 ""))]
9086 sh_set_return_address (operands[0], operands[1]);
9090 (define_insn "blockage"
9091 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9094 [(set_attr "length" "0")])
9096 ;; ------------------------------------------------------------------------
9098 ;; ------------------------------------------------------------------------
9101 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9102 (eq:SI (reg:SI T_REG) (const_int 1)))]
9105 [(set_attr "type" "arith")])
9107 (define_expand "seq"
9108 [(set (match_operand:SI 0 "arith_reg_dest" "")
9115 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9116 if (sh_compare_op1 != const0_rtx)
9117 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9118 ? GET_MODE (sh_compare_op0)
9119 : GET_MODE (sh_compare_op1),
9121 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9123 if (GET_MODE (operands[0]) != SImode)
9124 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9126 switch (GET_MODE (sh_compare_op0))
9129 emit_insn (gen_cmpsieqsi_media (operands[0],
9130 sh_compare_op0, sh_compare_op1));
9134 emit_insn (gen_cmpsieqdi_media (operands[0],
9135 sh_compare_op0, sh_compare_op1));
9139 if (! TARGET_SHMEDIA_FPU)
9141 emit_insn (gen_cmpsieqsf_media (operands[0],
9142 sh_compare_op0, sh_compare_op1));
9146 if (! TARGET_SHMEDIA_FPU)
9148 emit_insn (gen_cmpsieqdf_media (operands[0],
9149 sh_compare_op0, sh_compare_op1));
9158 if (GET_MODE (operands[0]) != DImode)
9159 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9161 switch (GET_MODE (sh_compare_op0))
9164 emit_insn (gen_cmpeqsi_media (operands[0],
9165 sh_compare_op0, sh_compare_op1));
9169 emit_insn (gen_cmpeqdi_media (operands[0],
9170 sh_compare_op0, sh_compare_op1));
9174 if (! TARGET_SHMEDIA_FPU)
9176 emit_insn (gen_cmpeqsf_media (operands[0],
9177 sh_compare_op0, sh_compare_op1));
9181 if (! TARGET_SHMEDIA_FPU)
9183 emit_insn (gen_cmpeqdf_media (operands[0],
9184 sh_compare_op0, sh_compare_op1));
9192 if (sh_expand_t_scc (EQ, operands[0]))
9194 if (! currently_expanding_to_rtl)
9196 operands[1] = prepare_scc_operands (EQ);
9199 (define_expand "slt"
9200 [(set (match_operand:SI 0 "arith_reg_operand" "")
9207 if (GET_MODE (operands[0]) != DImode)
9208 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9209 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9210 if (sh_compare_op1 != const0_rtx)
9211 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9212 ? GET_MODE (sh_compare_op0)
9213 : GET_MODE (sh_compare_op1),
9216 switch (GET_MODE (sh_compare_op0))
9219 emit_insn (gen_cmpgtsi_media (operands[0],
9220 sh_compare_op1, sh_compare_op0));
9224 emit_insn (gen_cmpgtdi_media (operands[0],
9225 sh_compare_op1, sh_compare_op0));
9229 if (! TARGET_SHMEDIA_FPU)
9231 emit_insn (gen_cmpgtsf_media (operands[0],
9232 sh_compare_op1, sh_compare_op0));
9236 if (! TARGET_SHMEDIA_FPU)
9238 emit_insn (gen_cmpgtdf_media (operands[0],
9239 sh_compare_op1, sh_compare_op0));
9247 if (! currently_expanding_to_rtl)
9249 operands[1] = prepare_scc_operands (LT);
9252 (define_expand "sle"
9253 [(match_operand:SI 0 "arith_reg_operand" "")]
9257 rtx tmp = sh_compare_op0;
9261 if (GET_MODE (operands[0]) != DImode)
9262 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9263 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9264 if (sh_compare_op1 != const0_rtx)
9265 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9266 ? GET_MODE (sh_compare_op0)
9267 : GET_MODE (sh_compare_op1),
9270 switch (GET_MODE (sh_compare_op0))
9274 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9276 emit_insn (gen_cmpgtsi_media (tmp,
9277 sh_compare_op0, sh_compare_op1));
9278 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9284 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9286 emit_insn (gen_cmpgtdi_media (tmp,
9287 sh_compare_op0, sh_compare_op1));
9288 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9293 if (! TARGET_SHMEDIA_FPU)
9295 emit_insn (gen_cmpgesf_media (operands[0],
9296 sh_compare_op1, sh_compare_op0));
9300 if (! TARGET_SHMEDIA_FPU)
9302 emit_insn (gen_cmpgedf_media (operands[0],
9303 sh_compare_op1, sh_compare_op0));
9312 sh_compare_op0 = sh_compare_op1;
9313 sh_compare_op1 = tmp;
9314 emit_insn (gen_sge (operands[0]));
9318 (define_expand "sgt"
9319 [(set (match_operand:SI 0 "arith_reg_operand" "")
9326 if (GET_MODE (operands[0]) != DImode)
9327 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9328 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9329 if (sh_compare_op1 != const0_rtx)
9330 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9331 ? GET_MODE (sh_compare_op0)
9332 : GET_MODE (sh_compare_op1),
9335 switch (GET_MODE (sh_compare_op0))
9338 emit_insn (gen_cmpgtsi_media (operands[0],
9339 sh_compare_op0, sh_compare_op1));
9343 emit_insn (gen_cmpgtdi_media (operands[0],
9344 sh_compare_op0, sh_compare_op1));
9348 if (! TARGET_SHMEDIA_FPU)
9350 emit_insn (gen_cmpgtsf_media (operands[0],
9351 sh_compare_op0, sh_compare_op1));
9355 if (! TARGET_SHMEDIA_FPU)
9357 emit_insn (gen_cmpgtdf_media (operands[0],
9358 sh_compare_op0, sh_compare_op1));
9366 if (! currently_expanding_to_rtl)
9368 operands[1] = prepare_scc_operands (GT);
9371 (define_expand "sge"
9372 [(set (match_operand:SI 0 "arith_reg_operand" "")
9379 enum machine_mode mode = GET_MODE (sh_compare_op0);
9381 if ((mode) == VOIDmode)
9382 mode = GET_MODE (sh_compare_op1);
9383 if (GET_MODE (operands[0]) != DImode)
9384 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9385 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9386 if (sh_compare_op1 != const0_rtx)
9387 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9393 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9395 emit_insn (gen_cmpgtsi_media (tmp,
9396 sh_compare_op1, sh_compare_op0));
9397 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9403 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9405 emit_insn (gen_cmpgtdi_media (tmp,
9406 sh_compare_op1, sh_compare_op0));
9407 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9412 if (! TARGET_SHMEDIA_FPU)
9414 emit_insn (gen_cmpgesf_media (operands[0],
9415 sh_compare_op0, sh_compare_op1));
9419 if (! TARGET_SHMEDIA_FPU)
9421 emit_insn (gen_cmpgedf_media (operands[0],
9422 sh_compare_op0, sh_compare_op1));
9431 if (! currently_expanding_to_rtl)
9433 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9437 rtx lab = gen_label_rtx ();
9438 prepare_scc_operands (EQ);
9439 emit_jump_insn (gen_branch_true (lab));
9440 prepare_scc_operands (GT);
9442 emit_insn (gen_movt (operands[0]));
9445 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9448 operands[1] = prepare_scc_operands (GE);
9451 (define_expand "sgtu"
9452 [(set (match_operand:SI 0 "arith_reg_operand" "")
9459 if (GET_MODE (operands[0]) != DImode)
9460 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9461 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9462 if (sh_compare_op1 != const0_rtx)
9463 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9464 ? GET_MODE (sh_compare_op0)
9465 : GET_MODE (sh_compare_op1),
9468 emit_insn (gen_cmpgtudi_media (operands[0],
9469 sh_compare_op0, sh_compare_op1));
9472 if (! currently_expanding_to_rtl)
9474 operands[1] = prepare_scc_operands (GTU);
9477 (define_expand "sltu"
9478 [(set (match_operand:SI 0 "arith_reg_operand" "")
9485 if (GET_MODE (operands[0]) != DImode)
9486 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9487 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9488 if (sh_compare_op1 != const0_rtx)
9489 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9490 ? GET_MODE (sh_compare_op0)
9491 : GET_MODE (sh_compare_op1),
9494 emit_insn (gen_cmpgtudi_media (operands[0],
9495 sh_compare_op1, sh_compare_op0));
9498 if (! currently_expanding_to_rtl)
9500 operands[1] = prepare_scc_operands (LTU);
9503 (define_expand "sleu"
9504 [(set (match_operand:SI 0 "arith_reg_operand" "")
9513 if (GET_MODE (operands[0]) != DImode)
9514 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9515 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9516 if (sh_compare_op1 != const0_rtx)
9517 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9518 ? GET_MODE (sh_compare_op0)
9519 : GET_MODE (sh_compare_op1),
9522 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9524 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9525 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9529 if (! currently_expanding_to_rtl)
9531 operands[1] = prepare_scc_operands (LEU);
9534 (define_expand "sgeu"
9535 [(set (match_operand:SI 0 "arith_reg_operand" "")
9544 if (GET_MODE (operands[0]) != DImode)
9545 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9546 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9547 if (sh_compare_op1 != const0_rtx)
9548 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9549 ? GET_MODE (sh_compare_op0)
9550 : GET_MODE (sh_compare_op1),
9553 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9555 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9556 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9561 if (! currently_expanding_to_rtl)
9563 operands[1] = prepare_scc_operands (GEU);
9566 ;; sne moves the complement of the T reg to DEST like this:
9570 ;; This is better than xoring compare result with 1 because it does
9571 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9574 (define_expand "sne"
9575 [(set (match_dup 2) (const_int -1))
9576 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9577 (neg:SI (plus:SI (match_dup 1)
9580 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9589 if (GET_MODE (operands[0]) != DImode)
9590 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9592 if (! TARGET_SHMEDIA_FPU
9593 && GET_MODE (sh_compare_op0) != DImode
9594 && GET_MODE (sh_compare_op0) != SImode)
9597 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9598 if (sh_compare_op1 != const0_rtx)
9599 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9600 ? GET_MODE (sh_compare_op0)
9601 : GET_MODE (sh_compare_op1),
9604 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9606 emit_insn (gen_seq (tmp));
9607 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9612 if (sh_expand_t_scc (NE, operands[0]))
9614 if (! currently_expanding_to_rtl)
9616 operands[1] = prepare_scc_operands (EQ);
9617 operands[2] = gen_reg_rtx (SImode);
9620 (define_expand "sunordered"
9621 [(set (match_operand:DI 0 "arith_reg_operand" "")
9622 (unordered:DI (match_dup 1) (match_dup 2)))]
9623 "TARGET_SHMEDIA_FPU"
9626 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9627 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9630 ;; Use the same trick for FP sle / sge
9632 ;; Apart from the constant use and the T setting, this is like movt,
9633 ;; except that it uses the logically negated value of T, i.e.
9634 ;; operand[0] := T ? 0 : 1.
9635 (define_expand "movnegt"
9636 [(set (match_dup 2) (const_int -1))
9637 (parallel [(set (match_operand 0 "" "")
9638 (neg:SI (plus:SI (match_dup 1)
9641 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9644 "operands[2] = gen_reg_rtx (SImode);")
9646 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9647 ;; This prevents a regression that occurred when we switched from xor to
9651 [(set (match_operand:SI 0 "arith_reg_dest" "")
9652 (plus:SI (reg:SI T_REG)
9655 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9656 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9659 ;; -------------------------------------------------------------------------
9660 ;; Instructions to cope with inline literal tables
9661 ;; -------------------------------------------------------------------------
9663 ; 2 byte integer in line
9665 (define_insn "consttable_2"
9666 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9667 (match_operand 1 "" "")]
9672 if (operands[1] != const0_rtx)
9673 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9676 [(set_attr "length" "2")
9677 (set_attr "in_delay_slot" "no")])
9679 ; 4 byte integer in line
9681 (define_insn "consttable_4"
9682 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9683 (match_operand 1 "" "")]
9688 if (operands[1] != const0_rtx)
9689 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9692 [(set_attr "length" "4")
9693 (set_attr "in_delay_slot" "no")])
9695 ; 8 byte integer in line
9697 (define_insn "consttable_8"
9698 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9699 (match_operand 1 "" "")]
9704 if (operands[1] != const0_rtx)
9705 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9708 [(set_attr "length" "8")
9709 (set_attr "in_delay_slot" "no")])
9711 ; 4 byte floating point
9713 (define_insn "consttable_sf"
9714 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9715 (match_operand 1 "" "")]
9720 if (operands[1] != const0_rtx)
9723 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9724 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9728 [(set_attr "length" "4")
9729 (set_attr "in_delay_slot" "no")])
9731 ; 8 byte floating point
9733 (define_insn "consttable_df"
9734 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9735 (match_operand 1 "" "")]
9740 if (operands[1] != const0_rtx)
9743 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9744 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9748 [(set_attr "length" "8")
9749 (set_attr "in_delay_slot" "no")])
9751 ;; Alignment is needed for some constant tables; it may also be added for
9752 ;; Instructions at the start of loops, or after unconditional branches.
9753 ;; ??? We would get more accurate lengths if we did instruction
9754 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9755 ;; here is too conservative.
9757 ; align to a two byte boundary
9759 (define_expand "align_2"
9760 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9764 ; align to a four byte boundary
9765 ;; align_4 and align_log are instructions for the starts of loops, or
9766 ;; after unconditional branches, which may take up extra room.
9768 (define_expand "align_4"
9769 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9773 ; align to a cache line boundary
9775 (define_insn "align_log"
9776 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9779 [(set_attr "length" "0")
9780 (set_attr "in_delay_slot" "no")])
9782 ; emitted at the end of the literal table, used to emit the
9783 ; 32bit branch labels if needed.
9785 (define_insn "consttable_end"
9786 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9788 "* return output_jump_label_table ();"
9789 [(set_attr "in_delay_slot" "no")])
9791 ; emitted at the end of the window in the literal table.
9793 (define_insn "consttable_window_end"
9794 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9797 [(set_attr "length" "0")
9798 (set_attr "in_delay_slot" "no")])
9800 ;; -------------------------------------------------------------------------
9802 ;; -------------------------------------------------------------------------
9804 ;; String/block move insn.
9806 (define_expand "movmemsi"
9807 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9808 (mem:BLK (match_operand:BLK 1 "" "")))
9809 (use (match_operand:SI 2 "nonmemory_operand" ""))
9810 (use (match_operand:SI 3 "immediate_operand" ""))
9811 (clobber (reg:SI PR_REG))
9812 (clobber (reg:SI R4_REG))
9813 (clobber (reg:SI R5_REG))
9814 (clobber (reg:SI R0_REG))])]
9815 "TARGET_SH1 && ! TARGET_SH5"
9818 if(expand_block_move (operands))
9823 (define_insn "block_move_real"
9824 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9825 (mem:BLK (reg:SI R5_REG)))
9826 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9827 (clobber (reg:SI PR_REG))
9828 (clobber (reg:SI R0_REG))])]
9829 "TARGET_SH1 && ! TARGET_HARD_SH4"
9831 [(set_attr "type" "sfunc")
9832 (set_attr "needs_delay_slot" "yes")])
9834 (define_insn "block_lump_real"
9835 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9836 (mem:BLK (reg:SI R5_REG)))
9837 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9838 (use (reg:SI R6_REG))
9839 (clobber (reg:SI PR_REG))
9840 (clobber (reg:SI T_REG))
9841 (clobber (reg:SI R4_REG))
9842 (clobber (reg:SI R5_REG))
9843 (clobber (reg:SI R6_REG))
9844 (clobber (reg:SI R0_REG))])]
9845 "TARGET_SH1 && ! TARGET_HARD_SH4"
9847 [(set_attr "type" "sfunc")
9848 (set_attr "needs_delay_slot" "yes")])
9850 (define_insn "block_move_real_i4"
9851 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9852 (mem:BLK (reg:SI R5_REG)))
9853 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9854 (clobber (reg:SI PR_REG))
9855 (clobber (reg:SI R0_REG))
9856 (clobber (reg:SI R1_REG))
9857 (clobber (reg:SI R2_REG))])]
9860 [(set_attr "type" "sfunc")
9861 (set_attr "needs_delay_slot" "yes")])
9863 (define_insn "block_lump_real_i4"
9864 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9865 (mem:BLK (reg:SI R5_REG)))
9866 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9867 (use (reg:SI R6_REG))
9868 (clobber (reg:SI PR_REG))
9869 (clobber (reg:SI T_REG))
9870 (clobber (reg:SI R4_REG))
9871 (clobber (reg:SI R5_REG))
9872 (clobber (reg:SI R6_REG))
9873 (clobber (reg:SI R0_REG))
9874 (clobber (reg:SI R1_REG))
9875 (clobber (reg:SI R2_REG))
9876 (clobber (reg:SI R3_REG))])]
9879 [(set_attr "type" "sfunc")
9880 (set_attr "needs_delay_slot" "yes")])
9882 ;; -------------------------------------------------------------------------
9883 ;; Floating point instructions.
9884 ;; -------------------------------------------------------------------------
9886 ;; ??? All patterns should have a type attribute.
9888 (define_expand "movpsi"
9889 [(set (match_operand:PSI 0 "register_operand" "")
9890 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9891 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9894 ;; The c / m alternative is a fake to guide reload to load directly into
9895 ;; fpscr, since reload doesn't know how to use post-increment.
9896 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9897 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9898 ;; predicate after reload.
9899 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9900 ;; like a mac -> gpr move.
9901 (define_insn "fpu_switch"
9902 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9903 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9905 && (! reload_completed
9906 || true_regnum (operands[0]) != FPSCR_REG
9907 || GET_CODE (operands[1]) != MEM
9908 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9910 ! precision stays the same
9919 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9920 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9923 [(set (reg:PSI FPSCR_REG)
9924 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9925 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9928 rtx fpscr, mem, new_insn;
9930 fpscr = SET_DEST (PATTERN (curr_insn));
9931 mem = SET_SRC (PATTERN (curr_insn));
9932 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9934 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9935 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9940 [(set (reg:PSI FPSCR_REG)
9941 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9942 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9943 && (flag_peephole2 ? flow2_completed : reload_completed)"
9946 rtx fpscr, mem, new_insn;
9948 fpscr = SET_DEST (PATTERN (curr_insn));
9949 mem = SET_SRC (PATTERN (curr_insn));
9950 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9952 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9953 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9955 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9956 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9960 ;; ??? This uses the fp unit, but has no type indicating that.
9961 ;; If we did that, this would either give a bogus latency or introduce
9962 ;; a bogus FIFO constraint.
9963 ;; Since this insn is currently only used for prologues/epilogues,
9964 ;; it is probably best to claim no function unit, which matches the
9966 (define_insn "toggle_sz"
9967 [(set (reg:PSI FPSCR_REG)
9968 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9969 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9971 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9973 ;; There's no way we can use it today, since optimize mode switching
9974 ;; doesn't enable us to know from which mode we're switching to the
9975 ;; mode it requests, to tell whether we can use a relative mode switch
9976 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9978 (define_insn "toggle_pr"
9979 [(set (reg:PSI FPSCR_REG)
9980 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9981 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9983 [(set_attr "type" "fp")])
9985 (define_expand "addsf3"
9986 [(set (match_operand:SF 0 "arith_reg_operand" "")
9987 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9988 (match_operand:SF 2 "arith_reg_operand" "")))]
9989 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9994 expand_sf_binop (&gen_addsf3_i, operands);
9999 (define_insn "*addsf3_media"
10000 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10001 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10002 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10003 "TARGET_SHMEDIA_FPU"
10004 "fadd.s %1, %2, %0"
10005 [(set_attr "type" "fparith_media")])
10007 (define_insn_and_split "unary_sf_op"
10008 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10013 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10014 (match_operator:SF 2 "unary_float_operator"
10015 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10016 (parallel [(match_operand 4
10017 "const_int_operand" "n")]))]))
10018 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10019 "TARGET_SHMEDIA_FPU"
10021 "TARGET_SHMEDIA_FPU && reload_completed"
10022 [(set (match_dup 5) (match_dup 6))]
10025 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10026 rtx op1 = gen_rtx_REG (SFmode,
10027 (true_regnum (operands[1])
10028 + (INTVAL (operands[4]) ^ endian)));
10030 operands[7] = gen_rtx_REG (SFmode,
10031 (true_regnum (operands[0])
10032 + (INTVAL (operands[3]) ^ endian)));
10033 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10035 [(set_attr "type" "fparith_media")])
10037 (define_insn_and_split "binary_sf_op"
10038 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10043 (parallel [(match_operand 7 "const_int_operand" "n")]))
10044 (match_operator:SF 3 "binary_float_operator"
10045 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10046 (parallel [(match_operand 5
10047 "const_int_operand" "n")]))
10048 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10049 (parallel [(match_operand 6
10050 "const_int_operand" "n")]))]))
10051 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10052 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10054 "&& reload_completed"
10055 [(set (match_dup 8) (match_dup 9))]
10058 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10059 rtx op1 = gen_rtx_REG (SFmode,
10060 (true_regnum (operands[1])
10061 + (INTVAL (operands[5]) ^ endian)));
10062 rtx op2 = gen_rtx_REG (SFmode,
10063 (true_regnum (operands[2])
10064 + (INTVAL (operands[6]) ^ endian)));
10066 operands[8] = gen_rtx_REG (SFmode,
10067 (true_regnum (operands[0])
10068 + (INTVAL (operands[4]) ^ endian)));
10069 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10071 [(set_attr "type" "fparith_media")])
10073 (define_insn "addsf3_i"
10074 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10075 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10076 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10077 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10080 [(set_attr "type" "fp")
10081 (set_attr "fp_mode" "single")])
10083 (define_expand "subsf3"
10084 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10085 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10086 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10087 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10092 expand_sf_binop (&gen_subsf3_i, operands);
10097 (define_insn "*subsf3_media"
10098 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10099 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10100 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10101 "TARGET_SHMEDIA_FPU"
10102 "fsub.s %1, %2, %0"
10103 [(set_attr "type" "fparith_media")])
10105 (define_insn "subsf3_i"
10106 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10107 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10108 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10109 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10112 [(set_attr "type" "fp")
10113 (set_attr "fp_mode" "single")])
10115 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10116 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
10117 ;; mixed-precision SH4 targets. To allow it to be still generated for the
10118 ;; SH3E, we use a separate insn for SH3E mulsf3.
10120 (define_expand "mulsf3"
10121 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10122 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10123 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10124 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10127 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10128 expand_sf_binop (&gen_mulsf3_i4, operands);
10129 else if (TARGET_SH2E)
10130 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10131 if (! TARGET_SHMEDIA)
10135 (define_insn "*mulsf3_media"
10136 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10137 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10138 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10139 "TARGET_SHMEDIA_FPU"
10140 "fmul.s %1, %2, %0"
10141 [(set_attr "type" "fparith_media")])
10143 (define_insn "mulsf3_i4"
10144 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10145 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10146 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10147 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10150 [(set_attr "type" "fp")
10151 (set_attr "fp_mode" "single")])
10153 (define_insn "mulsf3_ie"
10154 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10155 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10156 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10157 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10159 [(set_attr "type" "fp")])
10161 (define_insn "mac_media"
10162 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10163 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10164 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10165 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10166 "TARGET_SHMEDIA_FPU"
10167 "fmac.s %1, %2, %0"
10168 [(set_attr "type" "fparith_media")])
10170 (define_insn "*macsf3"
10171 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10172 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10173 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10174 (match_operand:SF 3 "arith_reg_operand" "0")))
10175 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10176 "TARGET_SH2E && ! TARGET_SH4"
10178 [(set_attr "type" "fp")
10179 (set_attr "fp_mode" "single")])
10181 (define_expand "divsf3"
10182 [(set (match_operand:SF 0 "arith_reg_operand" "")
10183 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10184 (match_operand:SF 2 "arith_reg_operand" "")))]
10185 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10190 expand_sf_binop (&gen_divsf3_i, operands);
10195 (define_insn "*divsf3_media"
10196 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10197 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10198 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10199 "TARGET_SHMEDIA_FPU"
10200 "fdiv.s %1, %2, %0"
10201 [(set_attr "type" "fdiv_media")])
10203 (define_insn "divsf3_i"
10204 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10205 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10206 (match_operand:SF 2 "arith_reg_operand" "f")))
10207 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10210 [(set_attr "type" "fdiv")
10211 (set_attr "fp_mode" "single")])
10213 (define_insn "floatdisf2"
10214 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10215 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10216 "TARGET_SHMEDIA_FPU"
10218 [(set_attr "type" "fpconv_media")])
10220 (define_expand "floatsisf2"
10221 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10222 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10223 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10226 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10228 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10233 (define_insn "*floatsisf2_media"
10234 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10235 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10236 "TARGET_SHMEDIA_FPU"
10238 [(set_attr "type" "fpconv_media")])
10240 (define_insn "floatsisf2_i4"
10241 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10242 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10243 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10244 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10246 [(set_attr "type" "fp")
10247 (set_attr "fp_mode" "single")])
10249 (define_insn "*floatsisf2_ie"
10250 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10251 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10252 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10254 [(set_attr "type" "fp")])
10256 (define_insn "fix_truncsfdi2"
10257 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10258 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10259 "TARGET_SHMEDIA_FPU"
10261 [(set_attr "type" "fpconv_media")])
10263 (define_expand "fix_truncsfsi2"
10264 [(set (match_operand:SI 0 "fpul_operand" "=y")
10265 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10266 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10269 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10271 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10276 (define_insn "*fix_truncsfsi2_media"
10277 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10278 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10279 "TARGET_SHMEDIA_FPU"
10281 [(set_attr "type" "fpconv_media")])
10283 (define_insn "fix_truncsfsi2_i4"
10284 [(set (match_operand:SI 0 "fpul_operand" "=y")
10285 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10286 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10287 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10289 [(set_attr "type" "ftrc_s")
10290 (set_attr "fp_mode" "single")])
10292 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10293 ;; fix_truncsfsi2_i4.
10294 ;; (define_insn "fix_truncsfsi2_i4_2"
10295 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10296 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10297 ;; (use (reg:PSI FPSCR_REG))
10298 ;; (clobber (reg:SI FPUL_REG))]
10301 ;; [(set_attr "length" "4")
10302 ;; (set_attr "fp_mode" "single")])
10305 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10306 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10307 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10308 ;; (clobber (reg:SI FPUL_REG))]
10310 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10311 ;; (use (match_dup 2))])
10312 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10314 (define_insn "*fixsfsi"
10315 [(set (match_operand:SI 0 "fpul_operand" "=y")
10316 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10317 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10319 [(set_attr "type" "fp")])
10321 (define_insn "cmpgtsf_t"
10322 [(set (reg:SI T_REG)
10323 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10324 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10325 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10327 [(set_attr "type" "fp")
10328 (set_attr "fp_mode" "single")])
10330 (define_insn "cmpeqsf_t"
10331 [(set (reg:SI T_REG)
10332 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10333 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10334 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10336 [(set_attr "type" "fp")
10337 (set_attr "fp_mode" "single")])
10339 (define_insn "ieee_ccmpeqsf_t"
10340 [(set (reg:SI T_REG)
10341 (ior:SI (reg:SI T_REG)
10342 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10343 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10344 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10345 "* return output_ieee_ccmpeq (insn, operands);"
10346 [(set_attr "length" "4")])
10349 (define_insn "cmpgtsf_t_i4"
10350 [(set (reg:SI T_REG)
10351 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10352 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10353 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10354 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10356 [(set_attr "type" "fp")
10357 (set_attr "fp_mode" "single")])
10359 (define_insn "cmpeqsf_t_i4"
10360 [(set (reg:SI T_REG)
10361 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10362 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10363 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10364 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10366 [(set_attr "type" "fp")
10367 (set_attr "fp_mode" "single")])
10369 (define_insn "*ieee_ccmpeqsf_t_4"
10370 [(set (reg:SI T_REG)
10371 (ior:SI (reg:SI T_REG)
10372 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10373 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10374 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10375 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10376 "* return output_ieee_ccmpeq (insn, operands);"
10377 [(set_attr "length" "4")
10378 (set_attr "fp_mode" "single")])
10380 (define_insn "cmpeqsf_media"
10381 [(set (match_operand:DI 0 "register_operand" "=r")
10382 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10383 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10384 "TARGET_SHMEDIA_FPU"
10385 "fcmpeq.s %1, %2, %0"
10386 [(set_attr "type" "fcmp_media")])
10388 (define_insn "cmpsieqsf_media"
10389 [(set (match_operand:SI 0 "register_operand" "=r")
10390 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10391 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10392 "TARGET_SHMEDIA_FPU"
10393 "fcmpeq.s %1, %2, %0"
10394 [(set_attr "type" "fcmp_media")])
10396 (define_insn "cmpgtsf_media"
10397 [(set (match_operand:DI 0 "register_operand" "=r")
10398 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10399 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10400 "TARGET_SHMEDIA_FPU"
10401 "fcmpgt.s %1, %2, %0"
10402 [(set_attr "type" "fcmp_media")])
10404 (define_insn "cmpgesf_media"
10405 [(set (match_operand:DI 0 "register_operand" "=r")
10406 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10407 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10408 "TARGET_SHMEDIA_FPU"
10409 "fcmpge.s %1, %2, %0"
10410 [(set_attr "type" "fcmp_media")])
10412 (define_insn "cmpunsf_media"
10413 [(set (match_operand:DI 0 "register_operand" "=r")
10414 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10415 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10416 "TARGET_SHMEDIA_FPU"
10417 "fcmpun.s %1, %2, %0"
10418 [(set_attr "type" "fcmp_media")])
10420 (define_expand "cmpsf"
10421 [(set (reg:SI T_REG)
10422 (compare (match_operand:SF 0 "arith_operand" "")
10423 (match_operand:SF 1 "arith_operand" "")))]
10424 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10427 sh_compare_op0 = operands[0];
10428 sh_compare_op1 = operands[1];
10432 (define_expand "negsf2"
10433 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10434 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10435 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10440 expand_sf_unop (&gen_negsf2_i, operands);
10445 (define_insn "*negsf2_media"
10446 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10447 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10448 "TARGET_SHMEDIA_FPU"
10450 [(set_attr "type" "fmove_media")])
10452 (define_insn "negsf2_i"
10453 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10454 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10455 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10458 [(set_attr "type" "fmove")
10459 (set_attr "fp_mode" "single")])
10461 (define_expand "sqrtsf2"
10462 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10463 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10464 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10469 expand_sf_unop (&gen_sqrtsf2_i, operands);
10474 (define_insn "*sqrtsf2_media"
10475 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10476 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10477 "TARGET_SHMEDIA_FPU"
10479 [(set_attr "type" "fdiv_media")])
10481 (define_insn "sqrtsf2_i"
10482 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10483 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10484 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10487 [(set_attr "type" "fdiv")
10488 (set_attr "fp_mode" "single")])
10490 (define_insn "rsqrtsf2"
10491 [(set (match_operand:SF 0 "register_operand" "=f")
10492 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10493 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10494 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10495 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10496 && operands[1] == CONST1_RTX (SFmode)"
10498 [(set_attr "type" "fsrra")
10499 (set_attr "fp_mode" "single")])
10501 (define_insn "fsca"
10502 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10504 (unspec:SF [(mult:SF
10505 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10506 (match_operand:SF 2 "immediate_operand" "i"))
10508 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10510 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10511 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10512 && operands[2] == sh_fsca_int2sf ()"
10514 [(set_attr "type" "fsca")
10515 (set_attr "fp_mode" "single")])
10517 (define_expand "sinsf2"
10518 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10519 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10521 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10524 rtx scaled = gen_reg_rtx (SFmode);
10525 rtx truncated = gen_reg_rtx (SImode);
10526 rtx fsca = gen_reg_rtx (V2SFmode);
10527 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10529 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10530 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10531 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10532 get_fpscr_rtx ()));
10533 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10537 (define_expand "cossf2"
10538 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10539 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10541 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10544 rtx scaled = gen_reg_rtx (SFmode);
10545 rtx truncated = gen_reg_rtx (SImode);
10546 rtx fsca = gen_reg_rtx (V2SFmode);
10547 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10549 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10550 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10551 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10552 get_fpscr_rtx ()));
10553 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10557 (define_expand "sindf2"
10558 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10559 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10561 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10564 rtx scaled = gen_reg_rtx (DFmode);
10565 rtx truncated = gen_reg_rtx (SImode);
10566 rtx fsca = gen_reg_rtx (V2SFmode);
10567 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10568 rtx sfresult = gen_reg_rtx (SFmode);
10570 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10571 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10572 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10573 get_fpscr_rtx ()));
10574 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10575 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10579 (define_expand "cosdf2"
10580 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10581 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10583 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10586 rtx scaled = gen_reg_rtx (DFmode);
10587 rtx truncated = gen_reg_rtx (SImode);
10588 rtx fsca = gen_reg_rtx (V2SFmode);
10589 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10590 rtx sfresult = gen_reg_rtx (SFmode);
10592 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10593 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10594 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10595 get_fpscr_rtx ()));
10596 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10597 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10601 (define_expand "abssf2"
10602 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10603 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10604 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10609 expand_sf_unop (&gen_abssf2_i, operands);
10614 (define_insn "*abssf2_media"
10615 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10616 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10617 "TARGET_SHMEDIA_FPU"
10619 [(set_attr "type" "fmove_media")])
10621 (define_insn "abssf2_i"
10622 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10623 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10624 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10627 [(set_attr "type" "fmove")
10628 (set_attr "fp_mode" "single")])
10630 (define_expand "adddf3"
10631 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10632 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10633 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10634 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10637 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10639 expand_df_binop (&gen_adddf3_i, operands);
10644 (define_insn "*adddf3_media"
10645 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10646 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10647 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10648 "TARGET_SHMEDIA_FPU"
10649 "fadd.d %1, %2, %0"
10650 [(set_attr "type" "dfparith_media")])
10652 (define_insn "adddf3_i"
10653 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10654 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10655 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10656 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10657 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10659 [(set_attr "type" "dfp_arith")
10660 (set_attr "fp_mode" "double")])
10662 (define_expand "subdf3"
10663 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10664 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10665 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10666 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10669 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10671 expand_df_binop (&gen_subdf3_i, operands);
10676 (define_insn "*subdf3_media"
10677 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10678 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10679 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10680 "TARGET_SHMEDIA_FPU"
10681 "fsub.d %1, %2, %0"
10682 [(set_attr "type" "dfparith_media")])
10684 (define_insn "subdf3_i"
10685 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10686 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10687 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10688 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10689 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10691 [(set_attr "type" "dfp_arith")
10692 (set_attr "fp_mode" "double")])
10694 (define_expand "muldf3"
10695 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10696 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10697 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10698 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10701 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10703 expand_df_binop (&gen_muldf3_i, operands);
10708 (define_insn "*muldf3_media"
10709 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10710 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10711 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10712 "TARGET_SHMEDIA_FPU"
10713 "fmul.d %1, %2, %0"
10714 [(set_attr "type" "dfmul_media")])
10716 (define_insn "muldf3_i"
10717 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10718 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10719 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10720 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10721 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10723 [(set_attr "type" "dfp_arith")
10724 (set_attr "fp_mode" "double")])
10726 (define_expand "divdf3"
10727 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10728 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10729 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10730 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10733 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10735 expand_df_binop (&gen_divdf3_i, operands);
10740 (define_insn "*divdf3_media"
10741 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10742 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10743 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10744 "TARGET_SHMEDIA_FPU"
10745 "fdiv.d %1, %2, %0"
10746 [(set_attr "type" "dfdiv_media")])
10748 (define_insn "divdf3_i"
10749 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10750 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10751 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10752 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10753 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10755 [(set_attr "type" "dfdiv")
10756 (set_attr "fp_mode" "double")])
10758 (define_insn "floatdidf2"
10759 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10760 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10761 "TARGET_SHMEDIA_FPU"
10763 [(set_attr "type" "dfpconv_media")])
10765 (define_expand "floatsidf2"
10766 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10767 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10768 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10771 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10773 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10774 get_fpscr_rtx ()));
10779 (define_insn "*floatsidf2_media"
10780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10781 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10782 "TARGET_SHMEDIA_FPU"
10784 [(set_attr "type" "dfpconv_media")])
10786 (define_insn "floatsidf2_i"
10787 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10788 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10789 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10790 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10792 [(set_attr "type" "dfp_conv")
10793 (set_attr "fp_mode" "double")])
10795 (define_insn "fix_truncdfdi2"
10796 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10797 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10798 "TARGET_SHMEDIA_FPU"
10800 [(set_attr "type" "dfpconv_media")])
10802 (define_expand "fix_truncdfsi2"
10803 [(set (match_operand:SI 0 "fpul_operand" "")
10804 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10805 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10808 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10810 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10811 get_fpscr_rtx ()));
10816 (define_insn "*fix_truncdfsi2_media"
10817 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10818 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10819 "TARGET_SHMEDIA_FPU"
10821 [(set_attr "type" "dfpconv_media")])
10823 (define_insn "fix_truncdfsi2_i"
10824 [(set (match_operand:SI 0 "fpul_operand" "=y")
10825 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10826 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10827 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10829 [(set_attr "type" "dfp_conv")
10830 (set_attr "dfp_comp" "no")
10831 (set_attr "fp_mode" "double")])
10833 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10834 ;; fix_truncdfsi2_i.
10835 ;; (define_insn "fix_truncdfsi2_i4"
10836 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10837 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10838 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10839 ;; (clobber (reg:SI FPUL_REG))]
10842 ;; [(set_attr "length" "4")
10843 ;; (set_attr "fp_mode" "double")])
10846 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10847 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10848 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10849 ;; (clobber (reg:SI FPUL_REG))]
10851 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10852 ;; (use (match_dup 2))])
10853 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10855 (define_insn "cmpgtdf_t"
10856 [(set (reg:SI T_REG)
10857 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10858 (match_operand:DF 1 "arith_reg_operand" "f")))
10859 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10860 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10862 [(set_attr "type" "dfp_cmp")
10863 (set_attr "fp_mode" "double")])
10865 (define_insn "cmpeqdf_t"
10866 [(set (reg:SI T_REG)
10867 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10868 (match_operand:DF 1 "arith_reg_operand" "f")))
10869 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10870 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10872 [(set_attr "type" "dfp_cmp")
10873 (set_attr "fp_mode" "double")])
10875 (define_insn "*ieee_ccmpeqdf_t"
10876 [(set (reg:SI T_REG)
10877 (ior:SI (reg:SI T_REG)
10878 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10879 (match_operand:DF 1 "arith_reg_operand" "f"))))
10880 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10881 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10882 "* return output_ieee_ccmpeq (insn, operands);"
10883 [(set_attr "length" "4")
10884 (set_attr "fp_mode" "double")])
10886 (define_insn "cmpeqdf_media"
10887 [(set (match_operand:DI 0 "register_operand" "=r")
10888 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10889 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10890 "TARGET_SHMEDIA_FPU"
10891 "fcmpeq.d %1,%2,%0"
10892 [(set_attr "type" "fcmp_media")])
10894 (define_insn "cmpsieqdf_media"
10895 [(set (match_operand:SI 0 "register_operand" "=r")
10896 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10897 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10898 "TARGET_SHMEDIA_FPU"
10899 "fcmpeq.d %1,%2,%0"
10900 [(set_attr "type" "fcmp_media")])
10902 (define_insn "cmpgtdf_media"
10903 [(set (match_operand:DI 0 "register_operand" "=r")
10904 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10905 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10906 "TARGET_SHMEDIA_FPU"
10907 "fcmpgt.d %1,%2,%0"
10908 [(set_attr "type" "fcmp_media")])
10910 (define_insn "cmpgedf_media"
10911 [(set (match_operand:DI 0 "register_operand" "=r")
10912 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10913 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10914 "TARGET_SHMEDIA_FPU"
10915 "fcmpge.d %1,%2,%0"
10916 [(set_attr "type" "fcmp_media")])
10918 (define_insn "cmpundf_media"
10919 [(set (match_operand:DI 0 "register_operand" "=r")
10920 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10921 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10922 "TARGET_SHMEDIA_FPU"
10923 "fcmpun.d %1,%2,%0"
10924 [(set_attr "type" "fcmp_media")])
10926 (define_expand "cmpdf"
10927 [(set (reg:SI T_REG)
10928 (compare (match_operand:DF 0 "arith_operand" "")
10929 (match_operand:DF 1 "arith_operand" "")))]
10930 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10933 sh_compare_op0 = operands[0];
10934 sh_compare_op1 = operands[1];
10938 (define_expand "negdf2"
10939 [(set (match_operand:DF 0 "arith_reg_operand" "")
10940 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10941 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10944 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10946 expand_df_unop (&gen_negdf2_i, operands);
10951 (define_insn "*negdf2_media"
10952 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10953 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10954 "TARGET_SHMEDIA_FPU"
10956 [(set_attr "type" "fmove_media")])
10958 (define_insn "negdf2_i"
10959 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10960 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10961 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10962 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10964 [(set_attr "type" "fmove")
10965 (set_attr "fp_mode" "double")])
10967 (define_expand "sqrtdf2"
10968 [(set (match_operand:DF 0 "arith_reg_operand" "")
10969 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10970 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10973 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10975 expand_df_unop (&gen_sqrtdf2_i, operands);
10980 (define_insn "*sqrtdf2_media"
10981 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10982 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10983 "TARGET_SHMEDIA_FPU"
10985 [(set_attr "type" "dfdiv_media")])
10987 (define_insn "sqrtdf2_i"
10988 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10989 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10990 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10991 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10993 [(set_attr "type" "dfdiv")
10994 (set_attr "fp_mode" "double")])
10996 (define_expand "absdf2"
10997 [(set (match_operand:DF 0 "arith_reg_operand" "")
10998 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10999 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11002 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11004 expand_df_unop (&gen_absdf2_i, operands);
11009 (define_insn "*absdf2_media"
11010 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11011 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11012 "TARGET_SHMEDIA_FPU"
11014 [(set_attr "type" "fmove_media")])
11016 (define_insn "absdf2_i"
11017 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11018 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11019 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11020 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11022 [(set_attr "type" "fmove")
11023 (set_attr "fp_mode" "double")])
11025 (define_expand "extendsfdf2"
11026 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11027 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11028 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11031 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11033 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11034 get_fpscr_rtx ()));
11039 (define_insn "*extendsfdf2_media"
11040 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11041 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11042 "TARGET_SHMEDIA_FPU"
11044 [(set_attr "type" "dfpconv_media")])
11046 (define_insn "extendsfdf2_i4"
11047 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11048 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11049 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11050 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11052 [(set_attr "type" "fp")
11053 (set_attr "fp_mode" "double")])
11055 (define_expand "truncdfsf2"
11056 [(set (match_operand:SF 0 "fpul_operand" "")
11057 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11058 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11061 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11063 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11064 get_fpscr_rtx ()));
11069 (define_insn "*truncdfsf2_media"
11070 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11071 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11072 "TARGET_SHMEDIA_FPU"
11074 [(set_attr "type" "dfpconv_media")])
11076 (define_insn "truncdfsf2_i4"
11077 [(set (match_operand:SF 0 "fpul_operand" "=y")
11078 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11079 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11080 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11082 [(set_attr "type" "fp")
11083 (set_attr "fp_mode" "double")])
11085 ;; Bit field extract patterns. These give better code for packed bitfields,
11086 ;; because they allow auto-increment addresses to be generated.
11088 (define_expand "insv"
11089 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11090 (match_operand:SI 1 "immediate_operand" "")
11091 (match_operand:SI 2 "immediate_operand" ""))
11092 (match_operand:SI 3 "general_operand" ""))]
11093 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11096 rtx addr_target, orig_address, shift_reg, qi_val;
11097 HOST_WIDE_INT bitsize, size, v = 0;
11098 rtx x = operands[3];
11100 /* ??? expmed doesn't care for non-register predicates. */
11101 if (! memory_operand (operands[0], VOIDmode)
11102 || ! immediate_operand (operands[1], VOIDmode)
11103 || ! immediate_operand (operands[2], VOIDmode)
11104 || ! general_operand (x, VOIDmode))
11106 /* If this isn't a 16 / 24 / 32 bit field, or if
11107 it doesn't start on a byte boundary, then fail. */
11108 bitsize = INTVAL (operands[1]);
11109 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11110 || (INTVAL (operands[2]) % 8) != 0)
11113 size = bitsize / 8;
11114 orig_address = XEXP (operands[0], 0);
11115 shift_reg = gen_reg_rtx (SImode);
11116 if (GET_CODE (x) == CONST_INT)
11119 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11123 emit_insn (gen_movsi (shift_reg, operands[3]));
11124 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11126 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11128 operands[0] = replace_equiv_address (operands[0], addr_target);
11129 emit_insn (gen_movqi (operands[0], qi_val));
11133 if (GET_CODE (x) == CONST_INT)
11135 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11138 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11139 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11141 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11142 emit_insn (gen_movqi (operands[0], qi_val));
11148 (define_insn "movua"
11149 [(set (match_operand:SI 0 "register_operand" "=z")
11150 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11151 (const_int 32) (const_int 0)))]
11154 [(set_attr "type" "movua")])
11156 ;; We shouldn't need this, but cse replaces increments with references
11157 ;; to other regs before flow has a chance to create post_inc
11158 ;; addressing modes, and only postreload's cse_move2add brings the
11159 ;; increments back to a usable form.
11161 [(set (match_operand:SI 0 "register_operand" "")
11162 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11163 (const_int 32) (const_int 0)))
11164 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11165 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11166 [(set (match_operand:SI 0 "register_operand" "")
11167 (sign_extract:SI (mem:SI (post_inc:SI
11168 (match_operand:SI 1 "register_operand" "")))
11169 (const_int 32) (const_int 0)))]
11172 (define_expand "extv"
11173 [(set (match_operand:SI 0 "register_operand" "")
11174 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11175 (match_operand 2 "const_int_operand" "")
11176 (match_operand 3 "const_int_operand" "")))]
11179 if (TARGET_SH4A_ARCH
11180 && INTVAL (operands[2]) == 32
11181 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11182 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11184 emit_insn (gen_movua (operands[0],
11185 adjust_address (operands[1], SImode, 0)));
11192 (define_expand "extzv"
11193 [(set (match_operand:SI 0 "register_operand" "")
11194 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11195 (match_operand 2 "const_int_operand" "")
11196 (match_operand 3 "const_int_operand" "")))]
11199 if (TARGET_SH4A_ARCH
11200 && INTVAL (operands[2]) == 32
11201 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11202 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11204 emit_insn (gen_movua (operands[0],
11205 adjust_address (operands[1], SImode, 0)));
11213 ;; -------------------------------------------------------------------------
11215 ;; -------------------------------------------------------------------------
11217 ;; This matches cases where a stack pointer increment at the start of the
11218 ;; epilogue combines with a stack slot read loading the return value.
11221 [(set (match_operand:SI 0 "arith_reg_operand" "")
11222 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11223 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11224 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11227 ;; See the comment on the dt combiner pattern above.
11230 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11231 (plus:SI (match_dup 0)
11233 (set (reg:SI T_REG)
11234 (eq:SI (match_dup 0)
11239 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11240 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11241 ;; reload when the constant is too large for a reg+offset address.
11243 ;; ??? We would get much better code if this was done in reload. This would
11244 ;; require modifying find_reloads_address to recognize that if the constant
11245 ;; is out-of-range for an immediate add, then we get better code by reloading
11246 ;; the constant into a register than by reloading the sum into a register,
11247 ;; since the former is one instruction shorter if the address does not need
11248 ;; to be offsettable. Unfortunately this does not work, because there is
11249 ;; only one register, r0, that can be used as an index register. This register
11250 ;; is also the function return value register. So, if we try to force reload
11251 ;; to use double-reg addresses, then we end up with some instructions that
11252 ;; need to use r0 twice. The only way to fix this is to change the calling
11253 ;; convention so that r0 is not used to return values.
11256 [(set (match_operand:SI 0 "register_operand" "=r")
11257 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11258 (set (mem:SI (match_dup 0))
11259 (match_operand:SI 2 "general_movsrc_operand" ""))]
11260 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11261 "mov.l %2,@(%0,%1)")
11264 [(set (match_operand:SI 0 "register_operand" "=r")
11265 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11266 (set (match_operand:SI 2 "general_movdst_operand" "")
11267 (mem:SI (match_dup 0)))]
11268 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11269 "mov.l @(%0,%1),%2")
11272 [(set (match_operand:SI 0 "register_operand" "=r")
11273 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11274 (set (mem:HI (match_dup 0))
11275 (match_operand:HI 2 "general_movsrc_operand" ""))]
11276 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11277 "mov.w %2,@(%0,%1)")
11280 [(set (match_operand:SI 0 "register_operand" "=r")
11281 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11282 (set (match_operand:HI 2 "general_movdst_operand" "")
11283 (mem:HI (match_dup 0)))]
11284 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11285 "mov.w @(%0,%1),%2")
11288 [(set (match_operand:SI 0 "register_operand" "=r")
11289 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11290 (set (mem:QI (match_dup 0))
11291 (match_operand:QI 2 "general_movsrc_operand" ""))]
11292 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11293 "mov.b %2,@(%0,%1)")
11296 [(set (match_operand:SI 0 "register_operand" "=r")
11297 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11298 (set (match_operand:QI 2 "general_movdst_operand" "")
11299 (mem:QI (match_dup 0)))]
11300 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11301 "mov.b @(%0,%1),%2")
11304 [(set (match_operand:SI 0 "register_operand" "=r")
11305 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11306 (set (mem:SF (match_dup 0))
11307 (match_operand:SF 2 "general_movsrc_operand" ""))]
11308 "TARGET_SH1 && REGNO (operands[0]) == 0
11309 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11310 || (GET_CODE (operands[2]) == SUBREG
11311 && REGNO (SUBREG_REG (operands[2])) < 16))
11312 && reg_unused_after (operands[0], insn)"
11313 "mov.l %2,@(%0,%1)")
11316 [(set (match_operand:SI 0 "register_operand" "=r")
11317 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11318 (set (match_operand:SF 2 "general_movdst_operand" "")
11320 (mem:SF (match_dup 0)))]
11321 "TARGET_SH1 && REGNO (operands[0]) == 0
11322 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11323 || (GET_CODE (operands[2]) == SUBREG
11324 && REGNO (SUBREG_REG (operands[2])) < 16))
11325 && reg_unused_after (operands[0], insn)"
11326 "mov.l @(%0,%1),%2")
11329 [(set (match_operand:SI 0 "register_operand" "=r")
11330 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11331 (set (mem:SF (match_dup 0))
11332 (match_operand:SF 2 "general_movsrc_operand" ""))]
11333 "TARGET_SH2E && REGNO (operands[0]) == 0
11334 && ((GET_CODE (operands[2]) == REG
11335 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11336 || (GET_CODE (operands[2]) == SUBREG
11337 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11338 && reg_unused_after (operands[0], insn)"
11339 "fmov{.s|} %2,@(%0,%1)")
11342 [(set (match_operand:SI 0 "register_operand" "=r")
11343 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11344 (set (match_operand:SF 2 "general_movdst_operand" "")
11346 (mem:SF (match_dup 0)))]
11347 "TARGET_SH2E && REGNO (operands[0]) == 0
11348 && ((GET_CODE (operands[2]) == REG
11349 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11350 || (GET_CODE (operands[2]) == SUBREG
11351 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11352 && reg_unused_after (operands[0], insn)"
11353 "fmov{.s|} @(%0,%1),%2")
11355 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11356 (define_insn "sp_switch_1"
11357 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11361 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11362 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11363 return \"mov r0,r15\";
11365 [(set_attr "length" "10")])
11367 ;; Switch back to the original stack for interrupt functions with the
11368 ;; sp_switch attribute. */
11369 (define_insn "sp_switch_2"
11372 "mov.l @r15+,r15\;mov.l @r15+,r0"
11373 [(set_attr "length" "4")])
11375 ;; Integer vector moves
11377 (define_expand "movv8qi"
11378 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11379 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11381 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11383 (define_insn "movv8qi_i"
11384 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11385 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11387 && (register_operand (operands[0], V8QImode)
11388 || sh_register_operand (operands[1], V8QImode))"
11395 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11396 (set_attr "length" "4,4,16,4,4")])
11399 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11400 (subreg:V8QI (const_int 0) 0))]
11402 [(set (match_dup 0)
11403 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11404 (const_int 0) (const_int 0) (const_int 0)
11405 (const_int 0) (const_int 0)]))])
11408 [(set (match_operand 0 "arith_reg_dest" "")
11409 (match_operand 1 "sh_rep_vec" ""))]
11410 "TARGET_SHMEDIA && reload_completed
11411 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11412 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11413 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11414 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11415 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11416 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11417 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11418 [(set (match_dup 0) (match_dup 1))
11422 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11423 rtx elt1 = XVECEXP (operands[1], 0, 1);
11426 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11430 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11431 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11433 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11434 operands[1] = XVECEXP (operands[1], 0, 0);
11437 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11439 = GEN_INT (TARGET_LITTLE_ENDIAN
11440 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11441 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11444 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11446 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11452 [(set (match_operand 0 "arith_reg_dest" "")
11453 (match_operand 1 "sh_const_vec" ""))]
11454 "TARGET_SHMEDIA && reload_completed
11455 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11456 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11457 [(set (match_dup 0) (match_dup 1))]
11460 rtx v = operands[1];
11461 enum machine_mode new_mode
11462 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11464 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11466 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11469 (define_expand "movv2hi"
11470 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11471 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11473 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11475 (define_insn "movv2hi_i"
11476 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11477 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11479 && (register_operand (operands[0], V2HImode)
11480 || sh_register_operand (operands[1], V2HImode))"
11487 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11488 (set_attr "length" "4,4,16,4,4")
11489 (set (attr "highpart")
11490 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11491 (const_string "user")]
11492 (const_string "ignore")))])
11494 (define_expand "movv4hi"
11495 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11496 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11498 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11500 (define_insn "movv4hi_i"
11501 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11502 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11504 && (register_operand (operands[0], V4HImode)
11505 || sh_register_operand (operands[1], V4HImode))"
11512 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11513 (set_attr "length" "4,4,16,4,4")
11514 (set_attr "highpart" "depend")])
11516 (define_expand "movv2si"
11517 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11518 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11520 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11522 (define_insn "movv2si_i"
11523 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11524 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11526 && (register_operand (operands[0], V2SImode)
11527 || sh_register_operand (operands[1], V2SImode))"
11534 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11535 (set_attr "length" "4,4,16,4,4")
11536 (set_attr "highpart" "depend")])
11538 ;; Multimedia Intrinsics
11540 (define_insn "absv2si2"
11541 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11542 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11545 [(set_attr "type" "mcmp_media")
11546 (set_attr "highpart" "depend")])
11548 (define_insn "absv4hi2"
11549 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11550 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11553 [(set_attr "type" "mcmp_media")
11554 (set_attr "highpart" "depend")])
11556 (define_insn "addv2si3"
11557 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11558 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11559 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11561 "madd.l %1, %2, %0"
11562 [(set_attr "type" "arith_media")
11563 (set_attr "highpart" "depend")])
11565 (define_insn "addv4hi3"
11566 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11567 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11568 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11570 "madd.w %1, %2, %0"
11571 [(set_attr "type" "arith_media")
11572 (set_attr "highpart" "depend")])
11574 (define_insn_and_split "addv2hi3"
11575 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11576 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11577 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11584 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11585 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11586 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11587 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11588 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11590 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11591 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11594 [(set_attr "highpart" "must_split")])
11596 (define_insn "ssaddv2si3"
11597 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11598 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11599 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11601 "madds.l %1, %2, %0"
11602 [(set_attr "type" "mcmp_media")
11603 (set_attr "highpart" "depend")])
11605 (define_insn "usaddv8qi3"
11606 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11607 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11608 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11610 "madds.ub %1, %2, %0"
11611 [(set_attr "type" "mcmp_media")
11612 (set_attr "highpart" "depend")])
11614 (define_insn "ssaddv4hi3"
11615 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11616 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11617 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11619 "madds.w %1, %2, %0"
11620 [(set_attr "type" "mcmp_media")
11621 (set_attr "highpart" "depend")])
11623 (define_insn "negcmpeqv8qi"
11624 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11625 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11626 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11628 "mcmpeq.b %N1, %N2, %0"
11629 [(set_attr "type" "mcmp_media")
11630 (set_attr "highpart" "depend")])
11632 (define_insn "negcmpeqv2si"
11633 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11634 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11635 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11637 "mcmpeq.l %N1, %N2, %0"
11638 [(set_attr "type" "mcmp_media")
11639 (set_attr "highpart" "depend")])
11641 (define_insn "negcmpeqv4hi"
11642 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11643 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11644 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11646 "mcmpeq.w %N1, %N2, %0"
11647 [(set_attr "type" "mcmp_media")
11648 (set_attr "highpart" "depend")])
11650 (define_insn "negcmpgtuv8qi"
11651 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11652 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11653 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11655 "mcmpgt.ub %N1, %N2, %0"
11656 [(set_attr "type" "mcmp_media")
11657 (set_attr "highpart" "depend")])
11659 (define_insn "negcmpgtv2si"
11660 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11661 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11662 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11664 "mcmpgt.l %N1, %N2, %0"
11665 [(set_attr "type" "mcmp_media")
11666 (set_attr "highpart" "depend")])
11668 (define_insn "negcmpgtv4hi"
11669 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11670 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11671 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11673 "mcmpgt.w %N1, %N2, %0"
11674 [(set_attr "type" "mcmp_media")
11675 (set_attr "highpart" "depend")])
11677 (define_insn "mcmv"
11678 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11679 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11680 (match_operand:DI 2 "arith_reg_operand" "r"))
11681 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11682 (not:DI (match_dup 2)))))]
11685 [(set_attr "type" "arith_media")
11686 (set_attr "highpart" "depend")])
11688 (define_insn "mcnvs_lw"
11689 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11691 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11692 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11694 "mcnvs.lw %N1, %N2, %0"
11695 [(set_attr "type" "mcmp_media")])
11697 (define_insn "mcnvs_wb"
11698 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11700 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11701 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11703 "mcnvs.wb %N1, %N2, %0"
11704 [(set_attr "type" "mcmp_media")])
11706 (define_insn "mcnvs_wub"
11707 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11709 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11710 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11712 "mcnvs.wub %N1, %N2, %0"
11713 [(set_attr "type" "mcmp_media")])
11715 (define_insn "mextr_rl"
11716 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11717 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11718 (match_operand:HI 3 "mextr_bit_offset" "i"))
11719 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11720 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11721 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11724 static char templ[21];
11726 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11727 (int) INTVAL (operands[3]) >> 3);
11730 [(set_attr "type" "arith_media")])
11732 (define_insn "*mextr_lr"
11733 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11734 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11735 (match_operand:HI 3 "mextr_bit_offset" "i"))
11736 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11737 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11738 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11741 static char templ[21];
11743 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11744 (int) INTVAL (operands[4]) >> 3);
11747 [(set_attr "type" "arith_media")])
11749 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11750 ; vector then varies depending on endianness.
11751 (define_expand "mextr1"
11752 [(match_operand:DI 0 "arith_reg_dest" "")
11753 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11754 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11758 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11759 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11763 (define_expand "mextr2"
11764 [(match_operand:DI 0 "arith_reg_dest" "")
11765 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11766 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11770 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11771 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11775 (define_expand "mextr3"
11776 [(match_operand:DI 0 "arith_reg_dest" "")
11777 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11778 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11782 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11783 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11787 (define_expand "mextr4"
11788 [(match_operand:DI 0 "arith_reg_dest" "")
11789 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11790 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11794 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11795 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11799 (define_expand "mextr5"
11800 [(match_operand:DI 0 "arith_reg_dest" "")
11801 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11802 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11806 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11807 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11811 (define_expand "mextr6"
11812 [(match_operand:DI 0 "arith_reg_dest" "")
11813 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11814 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11818 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11819 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11823 (define_expand "mextr7"
11824 [(match_operand:DI 0 "arith_reg_dest" "")
11825 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11826 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11830 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11831 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11835 (define_expand "mmacfx_wl"
11836 [(match_operand:V2SI 0 "arith_reg_dest" "")
11837 (match_operand:V2HI 1 "extend_reg_operand" "")
11838 (match_operand:V2HI 2 "extend_reg_operand" "")
11839 (match_operand:V2SI 3 "arith_reg_operand" "")]
11843 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11844 operands[1], operands[2]));
11848 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11850 (define_insn "mmacfx_wl_i"
11851 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11853 (match_operand:V2SI 1 "arith_reg_operand" "0")
11858 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11859 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11862 "mmacfx.wl %2, %3, %0"
11863 [(set_attr "type" "mac_media")
11864 (set_attr "highpart" "depend")])
11866 (define_expand "mmacnfx_wl"
11867 [(match_operand:V2SI 0 "arith_reg_dest" "")
11868 (match_operand:V2HI 1 "extend_reg_operand" "")
11869 (match_operand:V2HI 2 "extend_reg_operand" "")
11870 (match_operand:V2SI 3 "arith_reg_operand" "")]
11874 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11875 operands[1], operands[2]));
11879 (define_insn "mmacnfx_wl_i"
11880 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11882 (match_operand:V2SI 1 "arith_reg_operand" "0")
11887 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11888 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11891 "mmacnfx.wl %2, %3, %0"
11892 [(set_attr "type" "mac_media")
11893 (set_attr "highpart" "depend")])
11895 (define_insn "mulv2si3"
11896 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11897 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11898 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11900 "mmul.l %1, %2, %0"
11901 [(set_attr "type" "d2mpy_media")
11902 (set_attr "highpart" "depend")])
11904 (define_insn "mulv4hi3"
11905 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11906 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11907 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11909 "mmul.w %1, %2, %0"
11910 [(set_attr "type" "dmpy_media")
11911 (set_attr "highpart" "depend")])
11913 (define_insn "mmulfx_l"
11914 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11918 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11919 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11922 "mmulfx.l %1, %2, %0"
11923 [(set_attr "type" "d2mpy_media")
11924 (set_attr "highpart" "depend")])
11926 (define_insn "mmulfx_w"
11927 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11931 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11932 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11935 "mmulfx.w %1, %2, %0"
11936 [(set_attr "type" "dmpy_media")
11937 (set_attr "highpart" "depend")])
11939 (define_insn "mmulfxrp_w"
11940 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11945 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11946 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11950 "mmulfxrp.w %1, %2, %0"
11951 [(set_attr "type" "dmpy_media")
11952 (set_attr "highpart" "depend")])
11955 (define_expand "mmulhi_wl"
11956 [(match_operand:V2SI 0 "arith_reg_dest" "")
11957 (match_operand:V4HI 1 "arith_reg_operand" "")
11958 (match_operand:V4HI 2 "arith_reg_operand" "")]
11962 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11963 (operands[0], operands[1], operands[2]));
11967 (define_expand "mmullo_wl"
11968 [(match_operand:V2SI 0 "arith_reg_dest" "")
11969 (match_operand:V4HI 1 "arith_reg_operand" "")
11970 (match_operand:V4HI 2 "arith_reg_operand" "")]
11974 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11975 (operands[0], operands[1], operands[2]));
11979 (define_insn "mmul23_wl"
11980 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11983 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11984 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11985 (parallel [(const_int 2) (const_int 3)])))]
11987 "* return (TARGET_LITTLE_ENDIAN
11988 ? \"mmulhi.wl %1, %2, %0\"
11989 : \"mmullo.wl %1, %2, %0\");"
11990 [(set_attr "type" "dmpy_media")
11991 (set (attr "highpart")
11992 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11993 (const_string "user")))])
11995 (define_insn "mmul01_wl"
11996 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11999 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12000 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12001 (parallel [(const_int 0) (const_int 1)])))]
12003 "* return (TARGET_LITTLE_ENDIAN
12004 ? \"mmullo.wl %1, %2, %0\"
12005 : \"mmulhi.wl %1, %2, %0\");"
12006 [(set_attr "type" "dmpy_media")
12007 (set (attr "highpart")
12008 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12009 (const_string "user")))])
12012 (define_expand "mmulsum_wq"
12013 [(match_operand:DI 0 "arith_reg_dest" "")
12014 (match_operand:V4HI 1 "arith_reg_operand" "")
12015 (match_operand:V4HI 2 "arith_reg_operand" "")
12016 (match_operand:DI 3 "arith_reg_operand" "")]
12020 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12021 operands[1], operands[2]));
12025 (define_insn "mmulsum_wq_i"
12026 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12027 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12032 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12033 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12034 (parallel [(const_int 0)]))
12035 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12036 (sign_extend:V4DI (match_dup 3)))
12037 (parallel [(const_int 1)])))
12039 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12040 (sign_extend:V4DI (match_dup 3)))
12041 (parallel [(const_int 2)]))
12042 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12043 (sign_extend:V4DI (match_dup 3)))
12044 (parallel [(const_int 3)]))))))]
12046 "mmulsum.wq %2, %3, %0"
12047 [(set_attr "type" "mac_media")])
12049 (define_expand "mperm_w"
12050 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12051 (match_operand:V4HI 1 "arith_reg_operand" "r")
12052 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12056 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12057 (operands[0], operands[1], operands[2]));
12061 ; This use of vec_select isn't exactly correct according to rtl.texi
12062 ; (because not constant), but it seems a straightforward extension.
12063 (define_insn "mperm_w_little"
12064 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12066 (match_operand:V4HI 1 "arith_reg_operand" "r")
12068 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12069 (const_int 2) (const_int 0))
12070 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12071 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12072 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12073 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12074 "mperm.w %1, %N2, %0"
12075 [(set_attr "type" "arith_media")])
12077 (define_insn "mperm_w_big"
12078 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12080 (match_operand:V4HI 1 "arith_reg_operand" "r")
12082 [(zero_extract:QI (not:QI (match_operand:QI 2
12083 "extend_reg_or_0_operand" "rZ"))
12084 (const_int 2) (const_int 0))
12085 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12086 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12087 (zero_extract:QI (not:QI (match_dup 2))
12088 (const_int 2) (const_int 6))])))]
12089 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12090 "mperm.w %1, %N2, %0"
12091 [(set_attr "type" "arith_media")])
12093 (define_insn "mperm_w0"
12094 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12095 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12096 "trunc_hi_operand" "r"))))]
12098 "mperm.w %1, r63, %0"
12099 [(set_attr "type" "arith_media")
12100 (set_attr "highpart" "ignore")])
12102 (define_expand "msad_ubq"
12103 [(match_operand:DI 0 "arith_reg_dest" "")
12104 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12105 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12106 (match_operand:DI 3 "arith_reg_operand" "")]
12110 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12111 operands[1], operands[2]));
12115 (define_insn "msad_ubq_i"
12116 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12121 (match_operand:DI 1 "arith_reg_operand" "0")
12122 (abs:DI (vec_select:DI
12125 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12127 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12128 (parallel [(const_int 0)]))))
12129 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12130 (zero_extend:V8DI (match_dup 3)))
12131 (parallel [(const_int 1)]))))
12133 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12134 (zero_extend:V8DI (match_dup 3)))
12135 (parallel [(const_int 2)])))
12136 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12137 (zero_extend:V8DI (match_dup 3)))
12138 (parallel [(const_int 3)])))))
12141 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12142 (zero_extend:V8DI (match_dup 3)))
12143 (parallel [(const_int 4)])))
12144 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12145 (zero_extend:V8DI (match_dup 3)))
12146 (parallel [(const_int 5)]))))
12148 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12149 (zero_extend:V8DI (match_dup 3)))
12150 (parallel [(const_int 6)])))
12151 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12152 (zero_extend:V8DI (match_dup 3)))
12153 (parallel [(const_int 7)])))))))]
12155 "msad.ubq %N2, %N3, %0"
12156 [(set_attr "type" "mac_media")])
12158 (define_insn "mshalds_l"
12159 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12162 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12163 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12164 (const_int 31)))))]
12166 "mshalds.l %1, %2, %0"
12167 [(set_attr "type" "mcmp_media")
12168 (set_attr "highpart" "depend")])
12170 (define_insn "mshalds_w"
12171 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12174 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12175 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12176 (const_int 15)))))]
12178 "mshalds.w %1, %2, %0"
12179 [(set_attr "type" "mcmp_media")
12180 (set_attr "highpart" "depend")])
12182 (define_insn "ashrv2si3"
12183 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12184 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12185 (match_operand:DI 2 "arith_reg_operand" "r")))]
12187 "mshard.l %1, %2, %0"
12188 [(set_attr "type" "arith_media")
12189 (set_attr "highpart" "depend")])
12191 (define_insn "ashrv4hi3"
12192 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12193 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12194 (match_operand:DI 2 "arith_reg_operand" "r")))]
12196 "mshard.w %1, %2, %0"
12197 [(set_attr "type" "arith_media")
12198 (set_attr "highpart" "depend")])
12200 (define_insn "mshards_q"
12201 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12203 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12204 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12206 "mshards.q %1, %N2, %0"
12207 [(set_attr "type" "mcmp_media")])
12209 (define_expand "mshfhi_b"
12210 [(match_operand:V8QI 0 "arith_reg_dest" "")
12211 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12212 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12216 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12217 (operands[0], operands[1], operands[2]));
12221 (define_expand "mshflo_b"
12222 [(match_operand:V8QI 0 "arith_reg_dest" "")
12223 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12224 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12228 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12229 (operands[0], operands[1], operands[2]));
12233 (define_insn "mshf4_b"
12235 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12237 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12238 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12239 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12240 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12242 "* return (TARGET_LITTLE_ENDIAN
12243 ? \"mshfhi.b %N1, %N2, %0\"
12244 : \"mshflo.b %N1, %N2, %0\");"
12245 [(set_attr "type" "arith_media")
12246 (set (attr "highpart")
12247 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12248 (const_string "user")))])
12250 (define_insn "mshf0_b"
12252 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12254 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12255 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12256 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12257 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12259 "* return (TARGET_LITTLE_ENDIAN
12260 ? \"mshflo.b %N1, %N2, %0\"
12261 : \"mshfhi.b %N1, %N2, %0\");"
12262 [(set_attr "type" "arith_media")
12263 (set (attr "highpart")
12264 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12265 (const_string "user")))])
12267 (define_expand "mshfhi_l"
12268 [(match_operand:V2SI 0 "arith_reg_dest" "")
12269 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12270 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12274 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12275 (operands[0], operands[1], operands[2]));
12279 (define_expand "mshflo_l"
12280 [(match_operand:V2SI 0 "arith_reg_dest" "")
12281 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12282 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12286 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12287 (operands[0], operands[1], operands[2]));
12291 (define_insn "mshf4_l"
12292 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12294 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12295 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12296 (parallel [(const_int 1) (const_int 3)])))]
12298 "* return (TARGET_LITTLE_ENDIAN
12299 ? \"mshfhi.l %N1, %N2, %0\"
12300 : \"mshflo.l %N1, %N2, %0\");"
12301 [(set_attr "type" "arith_media")
12302 (set (attr "highpart")
12303 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12304 (const_string "user")))])
12306 (define_insn "mshf0_l"
12307 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12309 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12310 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12311 (parallel [(const_int 0) (const_int 2)])))]
12313 "* return (TARGET_LITTLE_ENDIAN
12314 ? \"mshflo.l %N1, %N2, %0\"
12315 : \"mshfhi.l %N1, %N2, %0\");"
12316 [(set_attr "type" "arith_media")
12317 (set (attr "highpart")
12318 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12319 (const_string "user")))])
12321 (define_expand "mshfhi_w"
12322 [(match_operand:V4HI 0 "arith_reg_dest" "")
12323 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12324 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12328 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12329 (operands[0], operands[1], operands[2]));
12333 (define_expand "mshflo_w"
12334 [(match_operand:V4HI 0 "arith_reg_dest" "")
12335 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12336 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12340 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12341 (operands[0], operands[1], operands[2]));
12345 (define_insn "mshf4_w"
12346 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12348 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12349 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12350 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12352 "* return (TARGET_LITTLE_ENDIAN
12353 ? \"mshfhi.w %N1, %N2, %0\"
12354 : \"mshflo.w %N1, %N2, %0\");"
12355 [(set_attr "type" "arith_media")
12356 (set (attr "highpart")
12357 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12358 (const_string "user")))])
12360 (define_insn "mshf0_w"
12361 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12363 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12364 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12365 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12367 "* return (TARGET_LITTLE_ENDIAN
12368 ? \"mshflo.w %N1, %N2, %0\"
12369 : \"mshfhi.w %N1, %N2, %0\");"
12370 [(set_attr "type" "arith_media")
12371 (set (attr "highpart")
12372 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12373 (const_string "user")))])
12375 (define_insn "mshflo_w_x"
12376 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12378 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12379 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12380 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12382 "mshflo.w %N1, %N2, %0"
12383 [(set_attr "type" "arith_media")
12384 (set_attr "highpart" "ignore")])
12386 /* These are useful to expand ANDs and as combiner patterns. */
12387 (define_insn_and_split "mshfhi_l_di"
12388 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12389 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12391 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12392 (const_int -4294967296))))]
12395 mshfhi.l %N1, %N2, %0
12397 "TARGET_SHMEDIA && reload_completed
12398 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12399 [(set (match_dup 3) (match_dup 4))
12400 (set (match_dup 5) (match_dup 6))]
12403 operands[3] = gen_lowpart (SImode, operands[0]);
12404 operands[4] = gen_highpart (SImode, operands[1]);
12405 operands[5] = gen_highpart (SImode, operands[0]);
12406 operands[6] = gen_highpart (SImode, operands[2]);
12408 [(set_attr "type" "arith_media")])
12410 (define_insn "*mshfhi_l_di_rev"
12411 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12412 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12413 (const_int -4294967296))
12414 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12417 "mshfhi.l %N2, %N1, %0"
12418 [(set_attr "type" "arith_media")])
12421 [(set (match_operand:DI 0 "arith_reg_dest" "")
12422 (ior:DI (zero_extend:DI (match_operand:SI 1
12423 "extend_reg_or_0_operand" ""))
12424 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12425 (const_int -4294967296))))
12426 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12431 emit_insn (gen_ashldi3_media (operands[3],
12432 simplify_gen_subreg (DImode, operands[1],
12435 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12439 (define_insn "mshflo_l_di"
12440 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12441 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12442 (const_int 4294967295))
12443 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12447 "mshflo.l %N1, %N2, %0"
12448 [(set_attr "type" "arith_media")
12449 (set_attr "highpart" "ignore")])
12451 (define_insn "*mshflo_l_di_rev"
12452 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12453 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12455 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12456 (const_int 4294967295))))]
12459 "mshflo.l %N2, %N1, %0"
12460 [(set_attr "type" "arith_media")
12461 (set_attr "highpart" "ignore")])
12463 ;; Combiner pattern for trampoline initialization.
12464 (define_insn_and_split "*double_shori"
12465 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12466 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12468 (match_operand:DI 2 "const_int_operand" "n")))]
12470 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12472 "rtx_equal_p (operands[0], operands[1])"
12476 HOST_WIDE_INT v = INTVAL (operands[2]);
12478 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12479 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12482 [(set_attr "highpart" "ignore")])
12485 (define_insn "*mshflo_l_di_x"
12486 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12487 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12489 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12493 "mshflo.l %N1, %N2, %0"
12494 [(set_attr "type" "arith_media")
12495 (set_attr "highpart" "ignore")])
12497 (define_insn_and_split "concat_v2sf"
12498 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12499 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12500 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12501 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12505 mshflo.l %N1, %N2, %0
12508 "TARGET_SHMEDIA && reload_completed
12509 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12510 [(set (match_dup 3) (match_dup 1))
12511 (set (match_dup 4) (match_dup 2))]
12514 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12515 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12517 [(set_attr "type" "arith_media")
12518 (set_attr "highpart" "ignore")])
12520 (define_insn "*mshflo_l_di_x_rev"
12521 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12522 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12524 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12527 "mshflo.l %N2, %N1, %0"
12528 [(set_attr "type" "arith_media")
12529 (set_attr "highpart" "ignore")])
12531 (define_insn "ashlv2si3"
12532 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12533 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12534 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12536 "mshlld.l %1, %2, %0"
12537 [(set_attr "type" "arith_media")
12538 (set_attr "highpart" "depend")])
12541 [(set (match_operand 0 "any_register_operand" "")
12542 (match_operator 3 "shift_operator"
12543 [(match_operand 1 "any_register_operand" "")
12544 (match_operand 2 "shift_count_reg_operand" "")]))]
12545 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12546 [(set (match_dup 0) (match_dup 3))]
12549 rtx count = operands[2];
12550 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12552 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12553 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12554 || GET_CODE (count) == TRUNCATE)
12555 count = XEXP (count, 0);
12556 inner_mode = GET_MODE (count);
12557 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12558 subreg_lowpart_offset (outer_mode, inner_mode));
12559 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12560 operands[1], count);
12563 (define_insn "ashlv4hi3"
12564 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12565 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12566 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12568 "mshlld.w %1, %2, %0"
12569 [(set_attr "type" "arith_media")
12570 (set_attr "highpart" "depend")])
12572 (define_insn "lshrv2si3"
12573 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12574 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12575 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12577 "mshlrd.l %1, %2, %0"
12578 [(set_attr "type" "arith_media")
12579 (set_attr "highpart" "depend")])
12581 (define_insn "lshrv4hi3"
12582 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12583 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12584 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12586 "mshlrd.w %1, %2, %0"
12587 [(set_attr "type" "arith_media")
12588 (set_attr "highpart" "depend")])
12590 (define_insn "subv2si3"
12591 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12592 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12593 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12595 "msub.l %N1, %2, %0"
12596 [(set_attr "type" "arith_media")
12597 (set_attr "highpart" "depend")])
12599 (define_insn "subv4hi3"
12600 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12601 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12602 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12604 "msub.w %N1, %2, %0"
12605 [(set_attr "type" "arith_media")
12606 (set_attr "highpart" "depend")])
12608 (define_insn_and_split "subv2hi3"
12609 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12610 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12611 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12618 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12619 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12620 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12621 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12622 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12624 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12625 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12628 [(set_attr "highpart" "must_split")])
12630 (define_insn "sssubv2si3"
12631 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12632 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12633 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12635 "msubs.l %N1, %2, %0"
12636 [(set_attr "type" "mcmp_media")
12637 (set_attr "highpart" "depend")])
12639 (define_insn "ussubv8qi3"
12640 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12641 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12642 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12644 "msubs.ub %N1, %2, %0"
12645 [(set_attr "type" "mcmp_media")
12646 (set_attr "highpart" "depend")])
12648 (define_insn "sssubv4hi3"
12649 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12650 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12651 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12653 "msubs.w %N1, %2, %0"
12654 [(set_attr "type" "mcmp_media")
12655 (set_attr "highpart" "depend")])
12657 ;; Floating Point Intrinsics
12659 (define_insn "fcosa_s"
12660 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12661 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12665 [(set_attr "type" "atrans_media")])
12667 (define_insn "fsina_s"
12668 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12669 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12673 [(set_attr "type" "atrans_media")])
12675 (define_insn "fipr"
12676 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12677 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12678 "fp_arith_reg_operand" "f")
12679 (match_operand:V4SF 2
12680 "fp_arith_reg_operand" "f"))
12681 (parallel [(const_int 0)]))
12682 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12683 (parallel [(const_int 1)])))
12684 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12685 (parallel [(const_int 2)]))
12686 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12687 (parallel [(const_int 3)])))))]
12689 "fipr.s %1, %2, %0"
12690 [(set_attr "type" "fparith_media")])
12692 (define_insn "fsrra_s"
12693 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12694 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12698 [(set_attr "type" "atrans_media")])
12700 (define_insn "ftrv"
12701 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12705 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12706 (parallel [(const_int 0) (const_int 5)
12707 (const_int 10) (const_int 15)]))
12708 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12710 (vec_select:V4SF (match_dup 1)
12711 (parallel [(const_int 4) (const_int 9)
12712 (const_int 14) (const_int 3)]))
12713 (vec_select:V4SF (match_dup 2)
12714 (parallel [(const_int 1) (const_int 2)
12715 (const_int 3) (const_int 0)]))))
12718 (vec_select:V4SF (match_dup 1)
12719 (parallel [(const_int 8) (const_int 13)
12720 (const_int 2) (const_int 7)]))
12721 (vec_select:V4SF (match_dup 2)
12722 (parallel [(const_int 2) (const_int 3)
12723 (const_int 0) (const_int 1)])))
12725 (vec_select:V4SF (match_dup 1)
12726 (parallel [(const_int 12) (const_int 1)
12727 (const_int 6) (const_int 11)]))
12728 (vec_select:V4SF (match_dup 2)
12729 (parallel [(const_int 3) (const_int 0)
12730 (const_int 1) (const_int 2)]))))))]
12732 "ftrv.s %1, %2, %0"
12733 [(set_attr "type" "fparith_media")])
12735 (define_insn "ldhi_l"
12736 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12738 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12741 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12745 [(set_attr "type" "load_media")])
12747 (define_insn "ldhi_q"
12748 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12750 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12753 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12757 [(set_attr "type" "load_media")])
12759 (define_insn_and_split "*ldhi_q_comb0"
12760 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12762 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12763 "register_operand" "r")
12764 (match_operand:SI 2
12765 "ua_offset" "I06"))
12768 (plus:SI (and:SI (match_dup 1) (const_int 7))
12771 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12775 "emit_insn (gen_ldhi_q (operands[0],
12776 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12780 (define_insn_and_split "*ldhi_q_comb1"
12781 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12783 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12784 "register_operand" "r")
12785 (match_operand:SI 2
12786 "ua_offset" "I06"))
12789 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12790 "ua_offset" "I06"))
12794 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12795 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12799 "emit_insn (gen_ldhi_q (operands[0],
12800 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12804 (define_insn "ldlo_l"
12805 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12807 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12809 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12810 (and:SI (match_dup 1) (const_int 3))))]
12813 [(set_attr "type" "load_media")])
12815 (define_insn "ldlo_q"
12816 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12818 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12820 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12821 (and:SI (match_dup 1) (const_int 7))))]
12824 [(set_attr "type" "load_media")])
12826 (define_insn_and_split "*ldlo_q_comb0"
12827 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12829 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12830 (match_operand:SI 2 "ua_offset" "I06"))
12832 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12833 (and:SI (match_dup 1) (const_int 7))))]
12834 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12838 "emit_insn (gen_ldlo_q (operands[0],
12839 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12842 (define_insn_and_split "*ldlo_q_comb1"
12843 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12845 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12846 (match_operand:SI 2 "ua_offset" "I06"))
12848 (minus:SI (const_int 8)
12849 (and:SI (plus:SI (match_dup 1)
12850 (match_operand:SI 3 "ua_offset" "I06"))
12852 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12853 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12854 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12858 "emit_insn (gen_ldlo_q (operands[0],
12859 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12862 (define_insn "sthi_l"
12863 [(set (zero_extract:SI
12864 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12867 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12869 (match_operand:SI 1 "arith_reg_operand" "r"))]
12872 [(set_attr "type" "ustore_media")])
12874 ;; All unaligned stores are considered to be 'narrow' because they typically
12875 ;; operate on less that a quadword, and when they operate on a full quadword,
12876 ;; the vanilla store high / store low sequence will cause a stall if not
12877 ;; scheduled apart.
12878 (define_insn "sthi_q"
12879 [(set (zero_extract:DI
12880 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12883 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12885 (match_operand:DI 1 "arith_reg_operand" "r"))]
12888 [(set_attr "type" "ustore_media")])
12890 (define_insn_and_split "*sthi_q_comb0"
12891 [(set (zero_extract:DI
12892 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12893 "register_operand" "r")
12894 (match_operand:SI 1 "ua_offset"
12898 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12900 (match_operand:DI 2 "arith_reg_operand" "r"))]
12901 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12905 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12909 (define_insn_and_split "*sthi_q_comb1"
12910 [(set (zero_extract:DI
12911 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12912 "register_operand" "r")
12913 (match_operand:SI 1 "ua_offset"
12917 (plus:SI (and:SI (plus:SI (match_dup 0)
12918 (match_operand:SI 2 "ua_offset" "I06"))
12922 (match_operand:DI 3 "arith_reg_operand" "r"))]
12923 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12924 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12928 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12932 ;; This is highpart user because the address is used as full 64 bit.
12933 (define_insn "stlo_l"
12934 [(set (zero_extract:SI
12935 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12937 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12938 (and:SI (match_dup 0) (const_int 3)))
12939 (match_operand:SI 1 "arith_reg_operand" "r"))]
12942 [(set_attr "type" "ustore_media")])
12944 (define_insn "stlo_q"
12945 [(set (zero_extract:DI
12946 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12948 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12949 (and:SI (match_dup 0) (const_int 7)))
12950 (match_operand:DI 1 "arith_reg_operand" "r"))]
12953 [(set_attr "type" "ustore_media")])
12955 (define_insn_and_split "*stlo_q_comb0"
12956 [(set (zero_extract:DI
12957 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12958 (match_operand:SI 1 "ua_offset" "I06"))
12960 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12961 (and:SI (match_dup 0) (const_int 7)))
12962 (match_operand:DI 2 "arith_reg_operand" "r"))]
12963 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12967 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12971 (define_insn_and_split "*stlo_q_comb1"
12972 [(set (zero_extract:DI
12973 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12974 (match_operand:SI 1 "ua_offset" "I06"))
12976 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12977 (match_operand:SI 2
12978 "ua_offset" "I06"))
12980 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12981 (match_operand:DI 3 "arith_reg_operand" "r"))]
12982 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12986 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12990 (define_insn "ldhi_l64"
12991 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12993 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12996 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13000 [(set_attr "type" "load_media")])
13002 (define_insn "ldhi_q64"
13003 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13005 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13008 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13012 [(set_attr "type" "load_media")])
13014 (define_insn "ldlo_l64"
13015 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13017 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13019 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13020 (and:DI (match_dup 1) (const_int 3))))]
13023 [(set_attr "type" "load_media")])
13025 (define_insn "ldlo_q64"
13026 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13028 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13030 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13031 (and:DI (match_dup 1) (const_int 7))))]
13034 [(set_attr "type" "load_media")])
13036 (define_insn "sthi_l64"
13037 [(set (zero_extract:SI
13038 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13041 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13043 (match_operand:SI 1 "arith_reg_operand" "r"))]
13046 [(set_attr "type" "ustore_media")])
13048 (define_insn "sthi_q64"
13049 [(set (zero_extract:DI
13050 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13053 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13055 (match_operand:DI 1 "arith_reg_operand" "r"))]
13058 [(set_attr "type" "ustore_media")])
13060 (define_insn "stlo_l64"
13061 [(set (zero_extract:SI
13062 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13064 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13065 (and:DI (match_dup 0) (const_int 3)))
13066 (match_operand:SI 1 "arith_reg_operand" "r"))]
13069 [(set_attr "type" "ustore_media")])
13071 (define_insn "stlo_q64"
13072 [(set (zero_extract:DI
13073 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13075 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13076 (and:DI (match_dup 0) (const_int 7)))
13077 (match_operand:DI 1 "arith_reg_operand" "r"))]
13080 [(set_attr "type" "ustore_media")])
13083 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13084 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13088 [(set_attr "type" "arith_media")])
13090 (define_insn "nsbsi"
13091 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13093 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13097 [(set_attr "type" "arith_media")])
13099 (define_insn "nsbdi"
13100 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13102 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13106 [(set_attr "type" "arith_media")])
13108 (define_expand "ffsdi2"
13109 [(set (match_operand:DI 0 "arith_reg_dest" "")
13110 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13114 rtx scratch = gen_reg_rtx (DImode);
13117 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13118 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13119 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13120 emit_insn (gen_nsbdi (scratch, scratch));
13121 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13122 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13123 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13125 = gen_rtx_EXPR_LIST (REG_EQUAL,
13126 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13130 (define_expand "ffssi2"
13131 [(set (match_operand:SI 0 "arith_reg_dest" "")
13132 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13136 rtx scratch = gen_reg_rtx (SImode);
13137 rtx discratch = gen_reg_rtx (DImode);
13140 emit_insn (gen_adddi3 (discratch,
13141 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13143 emit_insn (gen_andcdi3 (discratch,
13144 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13146 emit_insn (gen_nsbsi (scratch, discratch));
13147 last = emit_insn (gen_subsi3 (operands[0],
13148 force_reg (SImode, GEN_INT (63)), scratch));
13150 = gen_rtx_EXPR_LIST (REG_EQUAL,
13151 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13155 (define_insn "byterev"
13156 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13157 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13158 (parallel [(const_int 7) (const_int 6) (const_int 5)
13159 (const_int 4) (const_int 3) (const_int 2)
13160 (const_int 1) (const_int 0)])))]
13163 [(set_attr "type" "arith_media")])
13165 (define_insn "*prefetch_media"
13166 [(prefetch (match_operand:QI 0 "address_operand" "p")
13167 (match_operand:SI 1 "const_int_operand" "n")
13168 (match_operand:SI 2 "const_int_operand" "n"))]
13172 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13173 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13176 [(set_attr "type" "other")])
13178 (define_insn "*prefetch_i4"
13179 [(prefetch (match_operand:SI 0 "register_operand" "r")
13180 (match_operand:SI 1 "const_int_operand" "n")
13181 (match_operand:SI 2 "const_int_operand" "n"))]
13182 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13185 return \"pref @%0\";
13187 [(set_attr "type" "other")])
13189 (define_expand "prefetch"
13190 [(prefetch (match_operand 0 "address_operand" "p")
13191 (match_operand:SI 1 "const_int_operand" "n")
13192 (match_operand:SI 2 "const_int_operand" "n"))]
13193 "TARGET_HARD_SH4 || TARGET_SH5"
13196 if (GET_MODE (operands[0]) != Pmode
13197 || GET_CODE (operands[1]) != CONST_INT
13198 || GET_CODE (operands[2]) != CONST_INT)
13200 if (! TARGET_SHMEDIA)
13201 operands[0] = force_reg (Pmode, operands[0]);
13204 (define_insn "alloco_i"
13205 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13206 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13212 if (GET_CODE (operands[0]) == PLUS)
13214 xops[0] = XEXP (operands[0], 0);
13215 xops[1] = XEXP (operands[0], 1);
13219 xops[0] = operands[0];
13220 xops[1] = const0_rtx;
13222 output_asm_insn (\"alloco %0, %1\", xops);
13225 [(set_attr "type" "other")])
13228 [(set (match_operand 0 "any_register_operand" "")
13229 (match_operand 1 "" ""))]
13230 "TARGET_SHMEDIA && reload_completed"
13231 [(set (match_dup 0) (match_dup 1))]
13236 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13241 ; Stack Protector Patterns
13243 (define_expand "stack_protect_set"
13244 [(set (match_operand 0 "memory_operand" "")
13245 (match_operand 1 "memory_operand" ""))]
13248 if (TARGET_SHMEDIA)
13250 if (TARGET_SHMEDIA64)
13251 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13253 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13256 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13261 (define_insn "stack_protect_set_si"
13262 [(set (match_operand:SI 0 "memory_operand" "=m")
13263 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13264 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13266 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13267 [(set_attr "type" "other")
13268 (set_attr "length" "6")])
13270 (define_insn "stack_protect_set_si_media"
13271 [(set (match_operand:SI 0 "memory_operand" "=m")
13272 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13273 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13275 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13276 [(set_attr "type" "other")
13277 (set_attr "length" "12")])
13279 (define_insn "stack_protect_set_di_media"
13280 [(set (match_operand:DI 0 "memory_operand" "=m")
13281 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13282 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13284 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13285 [(set_attr "type" "other")
13286 (set_attr "length" "12")])
13288 (define_expand "stack_protect_test"
13289 [(match_operand 0 "memory_operand" "")
13290 (match_operand 1 "memory_operand" "")
13291 (match_operand 2 "" "")]
13294 if (TARGET_SHMEDIA)
13296 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13298 if (TARGET_SHMEDIA64)
13299 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13302 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13305 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13309 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13310 emit_jump_insn (gen_branch_true (operands[2]));
13316 (define_insn "stack_protect_test_si"
13317 [(set (reg:SI T_REG)
13318 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13319 (match_operand:SI 1 "memory_operand" "m")]
13321 (set (match_scratch:SI 2 "=&r") (const_int 0))
13322 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13324 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13325 [(set_attr "type" "other")
13326 (set_attr "length" "10")])
13328 (define_insn "stack_protect_test_si_media"
13329 [(set (match_operand:SI 0 "register_operand" "=&r")
13330 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13331 (match_operand:SI 2 "memory_operand" "m")]
13333 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13335 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13336 [(set_attr "type" "other")
13337 (set_attr "length" "16")])
13339 (define_insn "stack_protect_test_di_media"
13340 [(set (match_operand:DI 0 "register_operand" "=&r")
13341 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13342 (match_operand:DI 2 "memory_operand" "m")]
13344 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13346 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13347 [(set_attr "type" "other")
13348 (set_attr "length" "16")])