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)
156 ;; These are used with unspec_volatile.
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
166 ;; -------------------------------------------------------------------------
168 ;; -------------------------------------------------------------------------
173 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174 (const (symbol_ref "sh_cpu_attr")))
176 (define_attr "endian" "big,little"
177 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178 (const_string "little") (const_string "big"))))
180 ;; Indicate if the default fpu mode is single precision.
181 (define_attr "fpu_single" "yes,no"
182 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183 (const_string "yes") (const_string "no"))))
185 (define_attr "fmovd" "yes,no"
186 (const (if_then_else (symbol_ref "TARGET_FMOVD")
187 (const_string "yes") (const_string "no"))))
189 (define_attr "pipe_model" "sh1,sh4,sh5media"
191 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193 (const_string "sh1"))))
195 ;; cbranch conditional branch instructions
196 ;; jump unconditional jumps
197 ;; arith ordinary arithmetic
198 ;; arith3 a compound insn that behaves similarly to a sequence of
199 ;; three insns of type arith
200 ;; arith3b like above, but might end with a redirected branch
202 ;; load_si Likewise, SImode variant for general register.
203 ;; fload Likewise, but load to fp register.
205 ;; move general purpose register to register
206 ;; mt_group other sh4 mt instructions
207 ;; fmove register to register, floating point
208 ;; smpy word precision integer multiply
209 ;; dmpy longword or doublelongword precision integer multiply
211 ;; pload load of pr reg, which can't be put into delay slot of rts
212 ;; prset copy register to pr reg, ditto
213 ;; pstore store of pr reg, which can't be put into delay slot of jsr
214 ;; prget copy pr to register, ditto
215 ;; pcload pc relative load of constant value
216 ;; pcfload Likewise, but load to fp register.
217 ;; pcload_si Likewise, SImode variant for general register.
218 ;; rte return from exception
219 ;; sfunc special function call with known used registers
220 ;; call function call
222 ;; fdiv floating point divide (or square root)
223 ;; gp_fpul move from general purpose register to fpul
224 ;; fpul_gp move from fpul to general purpose register
225 ;; mac_gp move from mac[lh] to general purpose register
226 ;; dfp_arith, dfp_cmp,dfp_conv
227 ;; ftrc_s fix_truncsfsi2_i4
228 ;; dfdiv double precision floating point divide (or square root)
229 ;; cwb ic_invalidate_line_i
230 ;; movua SH4a unaligned load
231 ;; fsrra square root reciprocal approximate
232 ;; fsca sine and cosine approximate
233 ;; tls_load load TLS related address
234 ;; arith_media SHmedia arithmetic, logical, and shift instructions
235 ;; cbranch_media SHmedia conditional branch instructions
236 ;; cmp_media SHmedia compare instructions
237 ;; dfdiv_media SHmedia double precision divide and square root
238 ;; dfmul_media SHmedia double precision multiply instruction
239 ;; dfparith_media SHmedia double precision floating point arithmetic
240 ;; dfpconv_media SHmedia double precision floating point conversions
241 ;; dmpy_media SHmedia longword multiply
242 ;; fcmp_media SHmedia floating point compare instructions
243 ;; fdiv_media SHmedia single precision divide and square root
244 ;; fload_media SHmedia floating point register load instructions
245 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
246 ;; fparith_media SHmedia single precision floating point arithmetic
247 ;; fpconv_media SHmedia single precision floating point conversions
248 ;; fstore_media SHmedia floating point register store instructions
249 ;; gettr_media SHmedia gettr instruction
250 ;; invalidate_line_media SHmedia invalidate_line sequence
251 ;; jump_media SHmedia unconditional branch instructions
252 ;; load_media SHmedia general register load instructions
253 ;; pt_media SHmedia pt instruction (expanded by assembler)
254 ;; ptabs_media SHmedia ptabs instruction
255 ;; store_media SHmedia general register store instructions
256 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
257 ;; mac_media SHmedia mac-style fixed point operations
258 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
259 ;; atrans_media SHmedia approximate transcendental functions
260 ;; ustore_media SHmedia unaligned stores
261 ;; nil no-op move, will be deleted.
264 "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"
265 (const_string "other"))
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
270 ;; mt_group SH4 "mt" group instructions.
272 ;; ex_group SH4 "ex" group instructions.
274 ;; ls_group SH4 "ls" group instructions.
277 (define_attr "insn_class"
278 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282 (eq_attr "type" "cbranch,jump") (const_string "br_group")
283 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284 (const_string "fe_group")
285 (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")]
286 (const_string "none")))
287 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288 ;; so these do not belong in an insn group, although they are modeled
289 ;; with their own define_insn_reservations.
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
295 ;; Indicate if the fpu mode is set by this instruction
296 ;; "unknown" must have the value as "none" in fp_mode, and means
297 ;; that the instruction/abi has left the processor in an unknown
299 ;; "none" means that nothing has changed and no mode is set.
300 ;; This attribute is only used for the Renesas ABI.
301 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
303 ; If a conditional branch destination is within -252..258 bytes away
304 ; from the instruction it can be 2 bytes long. Something in the
305 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
306 ; branches are initially assumed to be 16 bytes long.
307 ; In machine_dependent_reorg, we split all branches that are longer than
310 ;; The maximum range used for SImode constant pool entries is 1018. A final
311 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
313 ;; instruction around the pool table, 2 bytes of alignment before the table,
314 ;; and 30 bytes of alignment after the table. That gives a maximum total
315 ;; pool size of 1058 bytes.
316 ;; Worst case code/pool content size ratio is 1:2 (using asms).
317 ;; Thus, in the worst case, there is one instruction in front of a maximum
318 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
320 ;; If we have a forward branch, the initial table will be put after the
321 ;; unconditional branch.
323 ;; ??? We could do much better by keeping track of the actual pcloads within
324 ;; the branch range and in the pcload range in front of the branch range.
326 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
328 (define_attr "short_cbranch_p" "no,yes"
329 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
331 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
333 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
335 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
337 ] (const_string "no")))
339 (define_attr "med_branch_p" "no,yes"
340 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
343 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
345 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
348 ] (const_string "no")))
350 (define_attr "med_cbranch_p" "no,yes"
351 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
354 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
359 ] (const_string "no")))
361 (define_attr "braf_branch_p" "no,yes"
362 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
367 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
372 ] (const_string "no")))
374 (define_attr "braf_cbranch_p" "no,yes"
375 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
380 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
382 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
385 ] (const_string "no")))
387 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
388 ; For wider ranges, we need a combination of a code and a data part.
389 ; If we can get a scratch register for a long range jump, the code
390 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
392 ; long; otherwise, it must be 6 bytes long.
394 ; All other instructions are two bytes long by default.
396 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397 ;; but getattrtab doesn't understand this.
398 (define_attr "length" ""
399 (cond [(eq_attr "type" "cbranch")
400 (cond [(eq_attr "short_cbranch_p" "yes")
402 (eq_attr "med_cbranch_p" "yes")
404 (eq_attr "braf_cbranch_p" "yes")
406 ;; ??? using pc is not computed transitively.
407 (ne (match_dup 0) (match_dup 0))
409 (ne (symbol_ref ("flag_pic")) (const_int 0))
412 (eq_attr "type" "jump")
413 (cond [(eq_attr "med_branch_p" "yes")
415 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
417 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
418 (symbol_ref "code_for_indirect_jump_scratch")))
419 (cond [(eq_attr "braf_branch_p" "yes")
421 (eq (symbol_ref "flag_pic") (const_int 0))
423 (ne (symbol_ref "TARGET_SH2") (const_int 0))
424 (const_int 10)] (const_int 18))
425 (eq_attr "braf_branch_p" "yes")
427 ;; ??? using pc is not computed transitively.
428 (ne (match_dup 0) (match_dup 0))
430 (ne (symbol_ref ("flag_pic")) (const_int 0))
433 (eq_attr "type" "pt_media")
434 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
435 (const_int 20) (const_int 12))
436 (and (eq_attr "type" "jump_media")
437 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
439 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
443 ;; DFA descriptions for the pipelines
446 (include "shmedia.md")
449 (include "predicates.md")
451 ;; Definitions for filling delay slots
453 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
455 ;; ??? This should be (nil) instead of (const_int 0)
456 (define_attr "hit_stack" "yes,no"
457 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
460 (const_string "yes")))
462 (define_attr "interrupt_function" "no,yes"
463 (const (symbol_ref "current_function_interrupt")))
465 (define_attr "in_delay_slot" "yes,no"
466 (cond [(eq_attr "type" "cbranch") (const_string "no")
467 (eq_attr "type" "pcload,pcload_si") (const_string "no")
468 (eq_attr "needs_delay_slot" "yes") (const_string "no")
469 (eq_attr "length" "2") (const_string "yes")
470 ] (const_string "no")))
472 (define_attr "cond_delay_slot" "yes,no"
473 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474 ] (const_string "no")))
476 (define_attr "is_sfunc" ""
477 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
479 (define_attr "is_mac_media" ""
480 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
482 (define_attr "branch_zero" "yes,no"
483 (cond [(eq_attr "type" "!cbranch") (const_string "no")
484 (ne (symbol_ref "(next_active_insn (insn)\
485 == (prev_active_insn\
486 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
487 && get_attr_length (next_active_insn (insn)) == 2")
489 (const_string "yes")]
490 (const_string "no")))
492 ;; SH4 Double-precision computation with double-precision result -
493 ;; the two halves are ready at different times.
494 (define_attr "dfp_comp" "yes,no"
495 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
496 (const_string "no")))
498 ;; Insns for which the latency of a preceding fp insn is decreased by one.
499 (define_attr "late_fp_use" "yes,no" (const_string "no"))
500 ;; And feeding insns for which this relevant.
501 (define_attr "any_fp_comp" "yes,no"
502 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
503 (const_string "yes")]
504 (const_string "no")))
506 (define_attr "any_int_load" "yes,no"
507 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
508 (const_string "yes")]
509 (const_string "no")))
511 (define_attr "highpart" "user, ignore, extend, depend, must_split"
512 (const_string "user"))
515 (eq_attr "needs_delay_slot" "yes")
516 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
518 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
519 ;; and thus we can't put a pop instruction in its delay slot.
520 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
521 ;; instruction can go in the delay slot.
523 ;; Since a normal return (rts) implicitly uses the PR register,
524 ;; we can't allow PR register loads in an rts delay slot.
527 (eq_attr "type" "return")
528 [(and (eq_attr "in_delay_slot" "yes")
529 (ior (and (eq_attr "interrupt_function" "no")
530 (eq_attr "type" "!pload,prset"))
531 (and (eq_attr "interrupt_function" "yes")
533 (ne (symbol_ref "TARGET_SH3") (const_int 0))
534 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
536 ;; Since a call implicitly uses the PR register, we can't allow
537 ;; a PR register store in a jsr delay slot.
540 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
541 [(and (eq_attr "in_delay_slot" "yes")
542 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
544 ;; Say that we have annulled true branches, since this gives smaller and
545 ;; faster code when branches are predicted as not taken.
547 ;; ??? The non-annulled condition should really be "in_delay_slot",
548 ;; but insns that can be filled in non-annulled get priority over insns
549 ;; that can only be filled in anulled.
552 (and (eq_attr "type" "cbranch")
553 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
554 ;; SH2e has a hardware bug that pretty much prohibits the use of
555 ;; annuled delay slots.
556 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
557 (not (eq_attr "cpu" "sh2e"))) (nil)])
559 ;; -------------------------------------------------------------------------
560 ;; SImode signed integer comparisons
561 ;; -------------------------------------------------------------------------
565 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
566 (match_operand:SI 1 "arith_operand" "K08,r"))
570 [(set_attr "type" "mt_group")])
572 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
573 ;; That would still allow reload to create cmpi instructions, but would
574 ;; perhaps allow forcing the constant into a register when that is better.
575 ;; Probably should use r0 for mem/imm compares, but force constant into a
576 ;; register for pseudo/imm compares.
578 (define_insn "cmpeqsi_t"
580 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
581 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
587 [(set_attr "type" "mt_group")])
589 (define_insn "cmpgtsi_t"
591 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
592 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
597 [(set_attr "type" "mt_group")])
599 (define_insn "cmpgesi_t"
601 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
602 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
607 [(set_attr "type" "mt_group")])
609 ;; -------------------------------------------------------------------------
610 ;; SImode unsigned integer comparisons
611 ;; -------------------------------------------------------------------------
613 (define_insn "cmpgeusi_t"
615 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
616 (match_operand:SI 1 "arith_reg_operand" "r")))]
619 [(set_attr "type" "mt_group")])
621 (define_insn "cmpgtusi_t"
623 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
624 (match_operand:SI 1 "arith_reg_operand" "r")))]
627 [(set_attr "type" "mt_group")])
629 ;; We save the compare operands in the cmpxx patterns and use them when
630 ;; we generate the branch.
632 (define_expand "cmpsi"
634 (compare (match_operand:SI 0 "cmpsi_operand" "")
635 (match_operand:SI 1 "arith_operand" "")))]
636 "TARGET_SH1 || TARGET_SHMEDIA"
639 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
640 && GET_CODE (operands[1]) != CONST_INT)
641 operands[0] = copy_to_mode_reg (SImode, operands[0]);
642 sh_compare_op0 = operands[0];
643 sh_compare_op1 = operands[1];
647 ;; -------------------------------------------------------------------------
648 ;; DImode signed integer comparisons
649 ;; -------------------------------------------------------------------------
651 ;; ??? Could get better scheduling by splitting the initial test from the
652 ;; rest of the insn after reload. However, the gain would hardly justify
653 ;; the sh.md size increase necessary to do that.
657 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
658 (match_operand:DI 1 "arith_operand" "r"))
661 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
663 [(set_attr "length" "6")
664 (set_attr "type" "arith3b")])
666 (define_insn "cmpeqdi_t"
668 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
669 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
672 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
673 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
674 [(set_attr "length" "6")
675 (set_attr "type" "arith3b")])
679 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
680 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
681 ;; If we applied this split when not optimizing, it would only be
682 ;; applied during the machine-dependent reorg, when no new basic blocks
684 "TARGET_SH1 && reload_completed && optimize"
685 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
686 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
687 (label_ref (match_dup 6))
689 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
694 = gen_rtx_REG (SImode,
695 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
697 = (operands[1] == const0_rtx
699 : gen_rtx_REG (SImode,
700 true_regnum (operands[1])
701 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
702 operands[4] = gen_lowpart (SImode, operands[0]);
703 operands[5] = gen_lowpart (SImode, operands[1]);
704 operands[6] = gen_label_rtx ();
707 (define_insn "cmpgtdi_t"
709 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
710 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
713 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
714 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
715 [(set_attr "length" "8")
716 (set_attr "type" "arith3")])
718 (define_insn "cmpgedi_t"
720 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
724 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
726 [(set_attr "length" "8,2")
727 (set_attr "type" "arith3,mt_group")])
729 ;; -------------------------------------------------------------------------
730 ;; DImode unsigned integer comparisons
731 ;; -------------------------------------------------------------------------
733 (define_insn "cmpgeudi_t"
735 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
736 (match_operand:DI 1 "arith_reg_operand" "r")))]
738 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
739 [(set_attr "length" "8")
740 (set_attr "type" "arith3")])
742 (define_insn "cmpgtudi_t"
744 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
745 (match_operand:DI 1 "arith_reg_operand" "r")))]
747 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
748 [(set_attr "length" "8")
749 (set_attr "type" "arith3")])
751 (define_insn "cmpeqsi_media"
752 [(set (match_operand:DI 0 "register_operand" "=r")
753 (eq:DI (match_operand:SI 1 "logical_operand" "%r")
754 (match_operand:SI 2 "cmp_operand" "Nr")))]
757 [(set_attr "type" "cmp_media")])
759 (define_insn "cmpeqdi_media"
760 [(set (match_operand:DI 0 "register_operand" "=r")
761 (eq:DI (match_operand:DI 1 "register_operand" "%r")
762 (match_operand:DI 2 "cmp_operand" "Nr")))]
765 [(set_attr "type" "cmp_media")])
767 (define_insn "cmpgtsi_media"
768 [(set (match_operand:DI 0 "register_operand" "=r")
769 (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
770 (match_operand:SI 2 "cmp_operand" "rN")))]
773 [(set_attr "type" "cmp_media")])
775 (define_insn "cmpgtdi_media"
776 [(set (match_operand:DI 0 "register_operand" "=r")
777 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
778 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
781 [(set_attr "type" "cmp_media")])
783 (define_insn "cmpgtusi_media"
784 [(set (match_operand:DI 0 "register_operand" "=r")
785 (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
786 (match_operand:SI 2 "cmp_operand" "rN")))]
788 "cmpgtu %N1, %N2, %0"
789 [(set_attr "type" "cmp_media")])
791 (define_insn "cmpgtudi_media"
792 [(set (match_operand:DI 0 "register_operand" "=r")
793 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
794 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
796 "cmpgtu %N1, %N2, %0"
797 [(set_attr "type" "cmp_media")])
799 (define_insn "cmpsieqsi_media"
800 [(set (match_operand:SI 0 "register_operand" "=r")
801 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
802 (match_operand:SI 2 "cmp_operand" "Nr")))]
805 [(set_attr "type" "cmp_media")])
807 (define_insn "cmpsieqdi_media"
808 [(set (match_operand:SI 0 "register_operand" "=r")
809 (eq:SI (match_operand:DI 1 "register_operand" "%r")
810 (match_operand:DI 2 "cmp_operand" "Nr")))]
813 [(set_attr "type" "cmp_media")])
815 (define_insn "cmpsigtsi_media"
816 [(set (match_operand:SI 0 "register_operand" "=r")
817 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
818 (match_operand:SI 2 "cmp_operand" "rN")))]
821 [(set_attr "type" "cmp_media")])
823 (define_insn "cmpsigtdi_media"
824 [(set (match_operand:SI 0 "register_operand" "=r")
825 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
826 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
829 [(set_attr "type" "cmp_media")])
831 (define_insn "cmpsigtusi_media"
832 [(set (match_operand:SI 0 "register_operand" "=r")
833 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
834 (match_operand:SI 2 "cmp_operand" "rN")))]
836 "cmpgtu %N1, %N2, %0"
837 [(set_attr "type" "cmp_media")])
839 (define_insn "cmpsigtudi_media"
840 [(set (match_operand:SI 0 "register_operand" "=r")
841 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
842 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
844 "cmpgtu %N1, %N2, %0"
845 [(set_attr "type" "cmp_media")])
847 ; These two patterns are for combine.
848 (define_insn "*cmpne0si_media"
849 [(set (match_operand:DI 0 "register_operand" "=r")
850 (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
853 [(set_attr "type" "cmp_media")])
855 (define_insn "*cmpne0sisi_media"
856 [(set (match_operand:SI 0 "register_operand" "=r")
857 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
860 [(set_attr "type" "cmp_media")])
862 ;; We save the compare operands in the cmpxx patterns and use them when
863 ;; we generate the branch.
865 (define_expand "cmpdi"
867 (compare (match_operand:DI 0 "arith_operand" "")
868 (match_operand:DI 1 "arith_operand" "")))]
869 "TARGET_SH2 || TARGET_SHMEDIA"
872 sh_compare_op0 = operands[0];
873 sh_compare_op1 = operands[1];
876 ;; -------------------------------------------------------------------------
877 ;; Conditional move instructions
878 ;; -------------------------------------------------------------------------
880 ;; The insn names may seem reversed, but note that cmveq performs the move
881 ;; if op1 == 0, and cmvne does it if op1 != 0.
883 (define_insn "movdicc_false"
884 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
885 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
887 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
888 (match_operand:DI 3 "arith_reg_operand" "0")))]
891 [(set_attr "type" "arith_media")])
893 (define_insn "movdicc_true"
894 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
895 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
897 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
898 (match_operand:DI 3 "arith_reg_operand" "0")))]
901 [(set_attr "type" "arith_media")])
904 [(set (match_operand:DI 0 "arith_reg_dest" "")
905 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
906 [(match_operand:DI 1 "arith_reg_operand" "")
908 (match_operand:DI 2 "arith_reg_dest" "")
910 (set (match_dup 2) (match_dup 0))]
911 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
913 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
916 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917 VOIDmode, operands[1], CONST0_RTX (DImode));
921 [(set (match_operand:DI 0 "general_movdst_operand" "")
922 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
923 (set (match_operand:DI 2 "arith_reg_dest" "")
924 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
925 [(match_operand:DI 3 "arith_reg_operand" "")
929 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
931 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
934 (define_expand "movdicc"
935 [(set (match_operand:DI 0 "register_operand" "")
936 (if_then_else:DI (match_operand 1 "comparison_operator" "")
937 (match_operand:DI 2 "register_operand" "")
938 (match_operand:DI 3 "register_operand" "")))]
942 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
943 && GET_MODE (sh_compare_op0) == DImode
944 && sh_compare_op1 == const0_rtx)
945 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
946 sh_compare_op0, sh_compare_op1);
954 tmp = gen_reg_rtx (DImode);
956 switch (GET_CODE (operands[1]))
959 emit_insn (gen_seq (tmp));
960 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
964 emit_insn (gen_seq (tmp));
965 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
969 emit_insn (gen_sgt (tmp));
970 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
974 emit_insn (gen_slt (tmp));
975 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
979 emit_insn (gen_slt (tmp));
980 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
984 emit_insn (gen_sgt (tmp));
985 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
989 emit_insn (gen_sgtu (tmp));
990 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
994 emit_insn (gen_sltu (tmp));
995 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
999 emit_insn (gen_sltu (tmp));
1000 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1004 emit_insn (gen_sgtu (tmp));
1005 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1009 emit_insn (gen_sunordered (tmp));
1010 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1014 emit_insn (gen_sunordered (tmp));
1015 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1032 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1033 ;; SImode to DImode.
1034 (define_insn "movsicc_false"
1035 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1036 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1038 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1039 (match_operand:SI 3 "arith_reg_operand" "0")))]
1042 [(set_attr "type" "arith_media")])
1044 (define_insn "movsicc_true"
1045 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1046 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1048 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1049 (match_operand:SI 3 "arith_reg_operand" "0")))]
1052 [(set_attr "type" "arith_media")])
1055 [(set (match_operand:SI 0 "arith_reg_dest" "")
1056 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1057 [(match_operand:SI 1 "arith_reg_operand" "")
1059 (match_operand:SI 2 "arith_reg_dest" "")
1061 (set (match_dup 2) (match_dup 0))]
1062 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1064 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1067 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068 VOIDmode, operands[1], CONST0_RTX (SImode));
1072 [(set (match_operand:SI 0 "general_movdst_operand" "")
1073 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1074 (set (match_operand:SI 2 "arith_reg_dest" "")
1075 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1076 [(match_operand:SI 3 "arith_reg_operand" "")
1080 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1081 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1083 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1086 replace_rtx (operands[4], operands[0], operands[1]);
1090 [(set (match_operand 0 "any_register_operand" "")
1091 (match_operand 1 "any_register_operand" ""))
1092 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1093 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1094 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1095 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1096 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1097 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1098 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1099 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1100 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1101 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1102 && (REGNO_REG_CLASS (REGNO (operands[0]))
1103 == REGNO_REG_CLASS (REGNO (operands[2])))
1104 && (REGNO_REG_CLASS (REGNO (operands[1]))
1105 == REGNO_REG_CLASS (REGNO (operands[0])))"
1106 [(set (match_dup 0) (match_dup 3))
1107 (set (match_dup 4) (match_dup 5))]
1111 rtx replacements[4];
1113 /* We want to replace occurrences of operands[0] with operands[1] and
1114 operands[2] with operands[0] in operands[4]/operands[5].
1115 Doing just two replace_rtx calls naively would result in the second
1116 replacement undoing all that the first did if operands[1] and operands[2]
1117 are identical, so we must do this simultaneously. */
1118 replacements[0] = operands[0];
1119 replacements[1] = operands[1];
1120 replacements[2] = operands[2];
1121 replacements[3] = operands[0];
1122 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1123 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1124 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1127 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1128 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1129 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1130 /* The operands array is aliased to recog_data.operand, which gets
1131 clobbered by extract_insn, so finish with it now. */
1132 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1133 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1134 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1135 always uses emit_insn. */
1136 /* Check that we don't violate matching constraints or earlyclobbers. */
1137 extract_insn (emit_insn (set1));
1138 if (! constrain_operands (1))
1140 extract_insn (emit (set2));
1141 if (! constrain_operands (1))
1145 tmp = replacements[0];
1146 replacements[0] = replacements[1];
1147 replacements[1] = tmp;
1148 tmp = replacements[2];
1149 replacements[2] = replacements[3];
1150 replacements[3] = tmp;
1151 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1152 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1153 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1159 ;; The register allocator is rather clumsy in handling multi-way conditional
1160 ;; moves, so allow the combiner to make them, and we split them up after
1162 (define_insn_and_split "*movsicc_umin"
1163 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1164 (umin:SI (if_then_else:SI
1165 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1167 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1168 (match_operand:SI 3 "register_operand" "0"))
1169 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1170 (clobber (match_scratch:SI 5 "=&r"))]
1171 "TARGET_SHMEDIA && no_new_pseudos"
1173 "TARGET_SHMEDIA && reload_completed"
1177 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1179 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1180 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1185 (define_insn "*movsicc_t_false"
1186 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1187 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1188 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1189 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1190 "TARGET_PRETEND_CMOVE
1191 && (arith_reg_operand (operands[1], SImode)
1192 || (immediate_operand (operands[1], SImode)
1193 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1194 "bt 0f\;mov %1,%0\\n0:"
1195 [(set_attr "type" "mt_group,arith") ;; poor approximation
1196 (set_attr "length" "4")])
1198 (define_insn "*movsicc_t_true"
1199 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1200 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1201 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1202 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1203 "TARGET_PRETEND_CMOVE
1204 && (arith_reg_operand (operands[1], SImode)
1205 || (immediate_operand (operands[1], SImode)
1206 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1207 "bf 0f\;mov %1,%0\\n0:"
1208 [(set_attr "type" "mt_group,arith") ;; poor approximation
1209 (set_attr "length" "4")])
1211 (define_expand "movsicc"
1212 [(set (match_operand:SI 0 "arith_reg_dest" "")
1213 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1214 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1215 (match_operand:SI 3 "arith_reg_operand" "")))]
1216 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1219 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1220 && GET_MODE (sh_compare_op0) == SImode
1222 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1223 && sh_compare_op1 == const0_rtx)
1224 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1225 sh_compare_op0, sh_compare_op1);
1226 else if (TARGET_PRETEND_CMOVE)
1228 enum rtx_code code = GET_CODE (operands[1]);
1229 enum rtx_code new_code = code;
1232 if (! currently_expanding_to_rtl)
1236 case LT: case LE: case LEU: case LTU:
1237 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1240 new_code = reverse_condition (code);
1242 case EQ: case GT: case GE: case GEU: case GTU:
1247 tmp = prepare_scc_operands (new_code);
1248 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1258 tmp = gen_reg_rtx (SImode);
1260 switch (GET_CODE (operands[1]))
1263 emit_insn (gen_seq (tmp));
1264 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1268 emit_insn (gen_seq (tmp));
1269 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1273 emit_insn (gen_sgt (tmp));
1274 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1278 emit_insn (gen_slt (tmp));
1279 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1283 emit_insn (gen_slt (tmp));
1284 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1288 emit_insn (gen_sgt (tmp));
1289 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1293 emit_insn (gen_sgtu (tmp));
1294 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1298 emit_insn (gen_sltu (tmp));
1299 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1303 emit_insn (gen_sltu (tmp));
1304 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1308 emit_insn (gen_sgtu (tmp));
1309 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1313 emit_insn (gen_sunordered (tmp));
1314 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1318 emit_insn (gen_sunordered (tmp));
1319 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1336 (define_expand "movqicc"
1337 [(set (match_operand:QI 0 "register_operand" "")
1338 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1339 (match_operand:QI 2 "register_operand" "")
1340 (match_operand:QI 3 "register_operand" "")))]
1344 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1345 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1346 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1347 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1351 ;; -------------------------------------------------------------------------
1352 ;; Addition instructions
1353 ;; -------------------------------------------------------------------------
1355 (define_expand "adddi3"
1356 [(set (match_operand:DI 0 "arith_reg_operand" "")
1357 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1358 (match_operand:DI 2 "arith_operand" "")))]
1364 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1366 operands[2] = force_reg (DImode, operands[2]);
1367 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1372 (define_insn "*adddi3_media"
1373 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1374 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1375 (match_operand:DI 2 "arith_operand" "r,I10")))]
1380 [(set_attr "type" "arith_media")])
1382 (define_insn "*adddisi3_media"
1383 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1384 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1385 (match_operand:DI 2 "arith_operand" "r,I10")))]
1390 [(set_attr "type" "arith_media")
1391 (set_attr "highpart" "ignore")])
1393 (define_insn "adddi3z_media"
1394 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1396 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1397 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1399 "addz.l %1, %N2, %0"
1400 [(set_attr "type" "arith_media")
1401 (set_attr "highpart" "ignore")])
1403 (define_insn "adddi3_compact"
1404 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1405 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1406 (match_operand:DI 2 "arith_reg_operand" "r")))
1407 (clobber (reg:SI T_REG))]
1410 [(set_attr "length" "6")])
1413 [(set (match_operand:DI 0 "arith_reg_dest" "")
1414 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1415 (match_operand:DI 2 "arith_reg_operand" "")))
1416 (clobber (reg:SI T_REG))]
1417 "TARGET_SH1 && reload_completed"
1421 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1422 high0 = gen_rtx_REG (SImode,
1423 true_regnum (operands[0])
1424 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1425 high2 = gen_rtx_REG (SImode,
1426 true_regnum (operands[2])
1427 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1428 emit_insn (gen_clrt ());
1429 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1430 emit_insn (gen_addc1 (high0, high0, high2));
1435 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1436 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1437 (match_operand:SI 2 "arith_reg_operand" "r"))
1440 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1443 [(set_attr "type" "arith")])
1445 (define_insn "addc1"
1446 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1447 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1448 (match_operand:SI 2 "arith_reg_operand" "r"))
1450 (clobber (reg:SI T_REG))]
1453 [(set_attr "type" "arith")])
1455 (define_expand "addsi3"
1456 [(set (match_operand:SI 0 "arith_reg_operand" "")
1457 (plus:SI (match_operand:SI 1 "arith_operand" "")
1458 (match_operand:SI 2 "arith_operand" "")))]
1463 operands[1] = force_reg (SImode, operands[1]);
1466 (define_insn "addsi3_media"
1467 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1468 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1469 (match_operand:SI 2 "arith_operand" "r,I10")))]
1474 [(set_attr "type" "arith_media")
1475 (set_attr "highpart" "ignore")])
1477 (define_insn "addsidi3_media"
1478 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1479 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1481 (match_operand:SI 2 "arith_operand"
1487 [(set_attr "type" "arith_media")
1488 (set_attr "highpart" "ignore")])
1490 (define_insn "*addsi3_compact"
1491 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1492 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1493 (match_operand:SI 2 "arith_operand" "rI08")))]
1496 [(set_attr "type" "arith")])
1498 ;; -------------------------------------------------------------------------
1499 ;; Subtraction instructions
1500 ;; -------------------------------------------------------------------------
1502 (define_expand "subdi3"
1503 [(set (match_operand:DI 0 "arith_reg_operand" "")
1504 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1505 (match_operand:DI 2 "arith_reg_operand" "")))]
1511 operands[1] = force_reg (DImode, operands[1]);
1512 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1517 (define_insn "*subdi3_media"
1518 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1519 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1520 (match_operand:DI 2 "arith_reg_operand" "r")))]
1523 [(set_attr "type" "arith_media")])
1525 (define_insn "subdisi3_media"
1526 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1527 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1528 (match_operand:DI 2 "arith_reg_operand" "r")))]
1531 [(set_attr "type" "arith_media")
1532 (set_attr "highpart" "ignore")])
1534 (define_insn "subdi3_compact"
1535 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1536 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1537 (match_operand:DI 2 "arith_reg_operand" "r")))
1538 (clobber (reg:SI T_REG))]
1541 [(set_attr "length" "6")])
1544 [(set (match_operand:DI 0 "arith_reg_dest" "")
1545 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1546 (match_operand:DI 2 "arith_reg_operand" "")))
1547 (clobber (reg:SI T_REG))]
1548 "TARGET_SH1 && reload_completed"
1552 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1553 high0 = gen_rtx_REG (SImode,
1554 true_regnum (operands[0])
1555 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1556 high2 = gen_rtx_REG (SImode,
1557 true_regnum (operands[2])
1558 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1559 emit_insn (gen_clrt ());
1560 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1561 emit_insn (gen_subc1 (high0, high0, high2));
1566 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1567 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1568 (match_operand:SI 2 "arith_reg_operand" "r"))
1571 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1576 [(set_attr "type" "arith")])
1578 (define_insn "subc1"
1579 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1580 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1581 (match_operand:SI 2 "arith_reg_operand" "r"))
1583 (clobber (reg:SI T_REG))]
1586 [(set_attr "type" "arith")])
1588 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1589 ;; pattern for this case. This helps multimedia applications that compute
1590 ;; the sum of absolute differences.
1591 (define_insn "mov_neg_si_t"
1592 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1595 [(set_attr "type" "arith")])
1597 (define_insn "*subsi3_internal"
1598 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1599 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1600 (match_operand:SI 2 "arith_reg_operand" "r")))]
1603 [(set_attr "type" "arith")])
1605 (define_insn_and_split "*subsi3_media"
1606 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1607 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1608 (match_operand:SI 2 "extend_reg_operand" "r")))]
1610 && (operands[1] != constm1_rtx
1611 || (GET_CODE (operands[2]) != TRUNCATE
1612 && GET_CODE (operands[2]) != SUBREG))"
1614 "operands[1] == constm1_rtx"
1615 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1617 [(set_attr "type" "arith_media")
1618 (set_attr "highpart" "ignore")])
1621 [(set (match_operand:SI 0 "arith_reg_dest" "")
1622 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1623 "general_extend_operand"
1625 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1626 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1627 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1631 [(set (match_operand:SI 0 "arith_reg_dest" "")
1632 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1633 "general_extend_operand"
1635 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1636 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1637 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1639 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1640 ;; will sometimes save one instruction. Otherwise we might get
1641 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1644 (define_expand "subsi3"
1645 [(set (match_operand:SI 0 "arith_reg_operand" "")
1646 (minus:SI (match_operand:SI 1 "arith_operand" "")
1647 (match_operand:SI 2 "arith_reg_operand" "")))]
1651 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1653 emit_insn (gen_negsi2 (operands[0], operands[2]));
1654 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1659 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1661 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1662 operands[1] = force_reg (SImode, operands[1]);
1666 ;; -------------------------------------------------------------------------
1667 ;; Division instructions
1668 ;; -------------------------------------------------------------------------
1670 ;; We take advantage of the library routines which don't clobber as many
1671 ;; registers as a normal function call would.
1673 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1674 ;; also has an effect on the register that holds the address of the sfunc.
1675 ;; To make this work, we have an extra dummy insn that shows the use
1676 ;; of this register for reorg.
1678 (define_insn "use_sfunc_addr"
1679 [(set (reg:SI PR_REG)
1680 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1681 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1683 [(set_attr "length" "0")])
1685 (define_insn "udivsi3_sh2a"
1686 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1687 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1688 (match_operand:SI 2 "arith_reg_operand" "z")))]
1691 [(set_attr "type" "arith")
1692 (set_attr "in_delay_slot" "no")])
1694 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1695 ;; hard register 0. If we used hard register 0, then the next instruction
1696 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1697 ;; gets allocated to a stack slot that needs its address reloaded, then
1698 ;; there is nothing to prevent reload from using r0 to reload the address.
1699 ;; This reload would clobber the value in r0 we are trying to store.
1700 ;; If we let reload allocate r0, then this problem can never happen.
1702 (define_insn "udivsi3_i1"
1703 [(set (match_operand:SI 0 "register_operand" "=z")
1704 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1705 (clobber (reg:SI T_REG))
1706 (clobber (reg:SI PR_REG))
1707 (clobber (reg:SI R4_REG))
1708 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1709 "TARGET_SH1 && ! TARGET_SH4"
1711 [(set_attr "type" "sfunc")
1712 (set_attr "needs_delay_slot" "yes")])
1714 ; Since shmedia-nofpu code could be linked against shcompact code, and
1715 ; the udivsi3 libcall has the same name, we must consider all registers
1716 ; clobbered that are in the union of the registers clobbered by the
1717 ; shmedia and the shcompact implementation. Note, if the shcompact
1718 ; implementation actually used shcompact code, we'd need to clobber
1719 ; also r23 and fr23.
1720 (define_insn "udivsi3_i1_media"
1721 [(set (match_operand:SI 0 "register_operand" "=z")
1722 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1723 (clobber (reg:SI T_MEDIA_REG))
1724 (clobber (reg:SI PR_MEDIA_REG))
1725 (clobber (reg:SI R20_REG))
1726 (clobber (reg:SI R21_REG))
1727 (clobber (reg:SI R22_REG))
1728 (clobber (reg:DI TR0_REG))
1729 (clobber (reg:DI TR1_REG))
1730 (clobber (reg:DI TR2_REG))
1731 (use (match_operand 1 "target_operand" "b"))]
1732 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1734 [(set_attr "type" "sfunc")
1735 (set_attr "needs_delay_slot" "yes")])
1737 (define_expand "udivsi3_i4_media"
1739 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1741 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1742 (set (match_dup 5) (float:DF (match_dup 3)))
1743 (set (match_dup 6) (float:DF (match_dup 4)))
1744 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1745 (set (match_dup 8) (fix:DI (match_dup 7)))
1746 (set (match_operand:SI 0 "register_operand" "")
1747 (truncate:SI (match_dup 8)))]
1748 "TARGET_SHMEDIA_FPU"
1751 operands[3] = gen_reg_rtx (DImode);
1752 operands[4] = gen_reg_rtx (DImode);
1753 operands[5] = gen_reg_rtx (DFmode);
1754 operands[6] = gen_reg_rtx (DFmode);
1755 operands[7] = gen_reg_rtx (DFmode);
1756 operands[8] = gen_reg_rtx (DImode);
1759 (define_insn "udivsi3_i4"
1760 [(set (match_operand:SI 0 "register_operand" "=y")
1761 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1762 (clobber (reg:SI T_REG))
1763 (clobber (reg:SI PR_REG))
1764 (clobber (reg:DF DR0_REG))
1765 (clobber (reg:DF DR2_REG))
1766 (clobber (reg:DF DR4_REG))
1767 (clobber (reg:SI R0_REG))
1768 (clobber (reg:SI R1_REG))
1769 (clobber (reg:SI R4_REG))
1770 (clobber (reg:SI R5_REG))
1771 (use (reg:PSI FPSCR_REG))
1772 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1773 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1775 [(set_attr "type" "sfunc")
1776 (set_attr "fp_mode" "double")
1777 (set_attr "needs_delay_slot" "yes")])
1779 (define_insn "udivsi3_i4_single"
1780 [(set (match_operand:SI 0 "register_operand" "=y")
1781 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1782 (clobber (reg:SI T_REG))
1783 (clobber (reg:SI PR_REG))
1784 (clobber (reg:DF DR0_REG))
1785 (clobber (reg:DF DR2_REG))
1786 (clobber (reg:DF DR4_REG))
1787 (clobber (reg:SI R0_REG))
1788 (clobber (reg:SI R1_REG))
1789 (clobber (reg:SI R4_REG))
1790 (clobber (reg:SI R5_REG))
1791 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1792 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1794 [(set_attr "type" "sfunc")
1795 (set_attr "needs_delay_slot" "yes")])
1797 (define_insn "udivsi3_i4_int"
1798 [(set (match_operand:SI 0 "register_operand" "=z")
1799 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1800 (clobber (reg:SI T_REG))
1801 (clobber (reg:SI R1_REG))
1802 (clobber (reg:SI PR_REG))
1803 (clobber (reg:SI MACH_REG))
1804 (clobber (reg:SI MACL_REG))
1805 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1808 [(set_attr "type" "sfunc")
1809 (set_attr "needs_delay_slot" "yes")])
1812 (define_expand "udivsi3"
1813 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1814 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1815 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1816 (parallel [(set (match_operand:SI 0 "register_operand" "")
1817 (udiv:SI (reg:SI R4_REG)
1819 (clobber (reg:SI T_REG))
1820 (clobber (reg:SI PR_REG))
1821 (clobber (reg:SI R4_REG))
1822 (use (match_dup 3))])]
1828 operands[3] = gen_reg_rtx (Pmode);
1829 /* Emit the move of the address to a pseudo outside of the libcall. */
1830 if (TARGET_DIVIDE_CALL_TABLE)
1832 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1833 that causes problems when the divide code is supposed to come from a
1834 separate library. Division by zero is undefined, so dividing 1 can be
1835 implemented by comparing with the divisor. */
1836 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1838 emit_insn (gen_cmpsi (operands[1], operands[2]));
1839 emit_insn (gen_sgeu (operands[0]));
1842 else if (operands[2] == const0_rtx)
1844 emit_move_insn (operands[0], operands[2]);
1847 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1848 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1850 else if (TARGET_DIVIDE_CALL_FP)
1852 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1853 if (TARGET_FPU_SINGLE)
1854 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1856 last = gen_udivsi3_i4 (operands[0], operands[3]);
1858 else if (TARGET_SHMEDIA_FPU)
1860 operands[1] = force_reg (SImode, operands[1]);
1861 operands[2] = force_reg (SImode, operands[2]);
1862 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1865 else if (TARGET_SH2A)
1867 operands[1] = force_reg (SImode, operands[1]);
1868 operands[2] = force_reg (SImode, operands[2]);
1869 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1872 else if (TARGET_SH5)
1874 function_symbol (operands[3],
1875 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1879 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1880 else if (TARGET_FPU_ANY)
1881 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1883 last = gen_udivsi3_i1 (operands[0], operands[3]);
1887 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1888 last = gen_udivsi3_i1 (operands[0], operands[3]);
1890 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1891 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1892 last = emit_insn (last);
1893 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1894 invariant code motion can move it. */
1895 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1896 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1900 (define_insn "divsi3_sh2a"
1901 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1902 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1903 (match_operand:SI 2 "arith_reg_operand" "z")))]
1906 [(set_attr "type" "arith")
1907 (set_attr "in_delay_slot" "no")])
1909 (define_insn "divsi3_i1"
1910 [(set (match_operand:SI 0 "register_operand" "=z")
1911 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1912 (clobber (reg:SI T_REG))
1913 (clobber (reg:SI PR_REG))
1914 (clobber (reg:SI R1_REG))
1915 (clobber (reg:SI R2_REG))
1916 (clobber (reg:SI R3_REG))
1917 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1918 "TARGET_SH1 && ! TARGET_SH4"
1920 [(set_attr "type" "sfunc")
1921 (set_attr "needs_delay_slot" "yes")])
1923 (define_insn "divsi3_i1_media"
1924 [(set (match_operand:SI 0 "register_operand" "=z")
1925 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1926 (clobber (reg:SI T_MEDIA_REG))
1927 (clobber (reg:SI PR_MEDIA_REG))
1928 (clobber (reg:SI R1_REG))
1929 (clobber (reg:SI R20_REG))
1930 (clobber (reg:SI R21_REG))
1931 (clobber (reg:SI TR0_REG))
1932 (use (match_operand 1 "target_operand" "b"))]
1933 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1935 [(set_attr "type" "sfunc")])
1937 (define_insn "divsi3_media_2"
1938 [(set (match_operand:SI 0 "register_operand" "=z")
1939 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1940 (clobber (reg:SI T_MEDIA_REG))
1941 (clobber (reg:SI PR_MEDIA_REG))
1942 (clobber (reg:SI R1_REG))
1943 (clobber (reg:SI R21_REG))
1944 (clobber (reg:SI TR0_REG))
1945 (use (reg:SI R20_REG))
1946 (use (match_operand 1 "target_operand" "b"))]
1947 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1949 [(set_attr "type" "sfunc")])
1951 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1952 ;; hard reg clobbers and data dependencies that we need when we want
1953 ;; to rematerialize the division into a call.
1954 (define_insn_and_split "divsi_inv_call"
1955 [(set (match_operand:SI 0 "register_operand" "=r")
1956 (div:SI (match_operand:SI 1 "register_operand" "r")
1957 (match_operand:SI 2 "register_operand" "r")))
1958 (clobber (reg:SI R4_REG))
1959 (clobber (reg:SI R5_REG))
1960 (clobber (reg:SI T_MEDIA_REG))
1961 (clobber (reg:SI PR_MEDIA_REG))
1962 (clobber (reg:SI R1_REG))
1963 (clobber (reg:SI R21_REG))
1964 (clobber (reg:SI TR0_REG))
1965 (clobber (reg:SI R20_REG))
1966 (use (match_operand:SI 3 "register_operand" "r"))]
1969 "&& (high_life_started || reload_completed)"
1970 [(set (match_dup 0) (match_dup 3))]
1972 [(set_attr "highpart" "must_split")])
1974 ;; This is the combiner pattern for -mdiv=inv:call .
1975 (define_insn_and_split "*divsi_inv_call_combine"
1976 [(set (match_operand:SI 0 "register_operand" "=z")
1977 (div:SI (match_operand:SI 1 "register_operand" "r")
1978 (match_operand:SI 2 "register_operand" "r")))
1979 (clobber (reg:SI R4_REG))
1980 (clobber (reg:SI R5_REG))
1981 (clobber (reg:SI T_MEDIA_REG))
1982 (clobber (reg:SI PR_MEDIA_REG))
1983 (clobber (reg:SI R1_REG))
1984 (clobber (reg:SI R21_REG))
1985 (clobber (reg:SI TR0_REG))
1986 (clobber (reg:SI R20_REG))
1987 (use (unspec:SI [(match_dup 1)
1988 (match_operand:SI 3 "" "")
1989 (unspec:SI [(match_operand:SI 4 "" "")
1991 (match_operand:DI 5 "" "")]
1993 (match_operand:DI 6 "" "")
1996 UNSPEC_DIV_INV_M3))]
1999 "&& (high_life_started || reload_completed)"
2003 const char *name = sh_divsi3_libfunc;
2004 enum sh_function_kind kind = SFUNC_GOT;
2007 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2008 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2009 while (TARGET_DIVIDE_INV_CALL2)
2011 rtx x = operands[3];
2013 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2015 x = XVECEXP (x, 0, 0);
2016 name = \"__sdivsi3_2\";
2017 kind = SFUNC_STATIC;
2018 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2021 sym = function_symbol (NULL, name, kind);
2022 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2025 [(set_attr "highpart" "must_split")])
2027 (define_expand "divsi3_i4_media"
2028 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2029 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2030 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2031 (set (match_operand:SI 0 "register_operand" "=r")
2032 (fix:SI (match_dup 5)))]
2033 "TARGET_SHMEDIA_FPU"
2036 operands[3] = gen_reg_rtx (DFmode);
2037 operands[4] = gen_reg_rtx (DFmode);
2038 operands[5] = gen_reg_rtx (DFmode);
2041 (define_insn "divsi3_i4"
2042 [(set (match_operand:SI 0 "register_operand" "=y")
2043 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2044 (clobber (reg:SI PR_REG))
2045 (clobber (reg:DF DR0_REG))
2046 (clobber (reg:DF DR2_REG))
2047 (use (reg:PSI FPSCR_REG))
2048 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2049 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2051 [(set_attr "type" "sfunc")
2052 (set_attr "fp_mode" "double")
2053 (set_attr "needs_delay_slot" "yes")])
2055 (define_insn "divsi3_i4_single"
2056 [(set (match_operand:SI 0 "register_operand" "=y")
2057 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2058 (clobber (reg:SI PR_REG))
2059 (clobber (reg:DF DR0_REG))
2060 (clobber (reg:DF DR2_REG))
2061 (clobber (reg:SI R2_REG))
2062 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2063 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2065 [(set_attr "type" "sfunc")
2066 (set_attr "needs_delay_slot" "yes")])
2068 (define_insn "divsi3_i4_int"
2069 [(set (match_operand:SI 0 "register_operand" "=z")
2070 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2071 (clobber (reg:SI T_REG))
2072 (clobber (reg:SI PR_REG))
2073 (clobber (reg:SI R1_REG))
2074 (clobber (reg:SI MACH_REG))
2075 (clobber (reg:SI MACL_REG))
2076 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2079 [(set_attr "type" "sfunc")
2080 (set_attr "needs_delay_slot" "yes")])
2082 (define_expand "divsi3"
2083 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2084 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2085 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2086 (parallel [(set (match_operand:SI 0 "register_operand" "")
2087 (div:SI (reg:SI R4_REG)
2089 (clobber (reg:SI T_REG))
2090 (clobber (reg:SI PR_REG))
2091 (clobber (reg:SI R1_REG))
2092 (clobber (reg:SI R2_REG))
2093 (clobber (reg:SI R3_REG))
2094 (use (match_dup 3))])]
2100 operands[3] = gen_reg_rtx (Pmode);
2101 /* Emit the move of the address to a pseudo outside of the libcall. */
2102 if (TARGET_DIVIDE_CALL_TABLE)
2104 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2105 last = gen_divsi3_i4_int (operands[0], operands[3]);
2107 else if (TARGET_DIVIDE_CALL_FP)
2109 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2110 if (TARGET_FPU_SINGLE)
2111 last = gen_divsi3_i4_single (operands[0], operands[3]);
2113 last = gen_divsi3_i4 (operands[0], operands[3]);
2115 else if (TARGET_SH2A)
2117 operands[1] = force_reg (SImode, operands[1]);
2118 operands[2] = force_reg (SImode, operands[2]);
2119 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2122 else if (TARGET_DIVIDE_INV)
2124 rtx dividend = operands[1];
2125 rtx divisor = operands[2];
2127 rtx nsb_res = gen_reg_rtx (DImode);
2128 rtx norm64 = gen_reg_rtx (DImode);
2129 rtx tab_ix = gen_reg_rtx (DImode);
2130 rtx norm32 = gen_reg_rtx (SImode);
2131 rtx i92 = force_reg (DImode, GEN_INT (92));
2132 rtx scratch0a = gen_reg_rtx (DImode);
2133 rtx scratch0b = gen_reg_rtx (DImode);
2134 rtx inv0 = gen_reg_rtx (SImode);
2135 rtx scratch1a = gen_reg_rtx (DImode);
2136 rtx scratch1b = gen_reg_rtx (DImode);
2137 rtx shift = gen_reg_rtx (DImode);
2139 rtx inv1 = gen_reg_rtx (SImode);
2140 rtx scratch2a = gen_reg_rtx (DImode);
2141 rtx scratch2b = gen_reg_rtx (SImode);
2142 rtx inv2 = gen_reg_rtx (SImode);
2143 rtx scratch3a = gen_reg_rtx (DImode);
2144 rtx scratch3b = gen_reg_rtx (DImode);
2145 rtx scratch3c = gen_reg_rtx (DImode);
2146 rtx scratch3d = gen_reg_rtx (SImode);
2147 rtx scratch3e = gen_reg_rtx (DImode);
2148 rtx result = gen_reg_rtx (SImode);
2150 if (! arith_reg_or_0_operand (dividend, SImode))
2151 dividend = force_reg (SImode, dividend);
2152 if (! arith_reg_operand (divisor, SImode))
2153 divisor = force_reg (SImode, divisor);
2154 if (flag_pic && Pmode != DImode)
2156 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2157 tab_base = gen_datalabel_ref (tab_base);
2158 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2162 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2163 tab_base = gen_datalabel_ref (tab_base);
2164 tab_base = force_reg (DImode, tab_base);
2166 if (TARGET_DIVIDE_INV20U)
2167 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2169 i2p27 = GEN_INT (0);
2170 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2171 i43 = force_reg (DImode, GEN_INT (43));
2174 emit_insn (gen_nsbdi (nsb_res,
2175 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2176 emit_insn (gen_ashldi3_media (norm64,
2177 gen_rtx_SUBREG (DImode, divisor, 0),
2179 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2180 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2181 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2182 inv0, scratch0a, scratch0b,
2183 scratch1a, scratch1b));
2184 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2185 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2187 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2189 scratch3a, scratch3b, scratch3c,
2190 scratch2a, scratch2b, scratch3d, scratch3e));
2191 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2192 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2193 else if (TARGET_DIVIDE_INV_FP)
2194 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2195 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2196 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2197 gen_reg_rtx (DFmode)));
2199 emit_move_insn (operands[0], result);
2202 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2204 operands[1] = force_reg (SImode, operands[1]);
2205 operands[2] = force_reg (SImode, operands[2]);
2206 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2209 else if (TARGET_SH5)
2211 if (TARGET_DIVIDE_CALL2)
2213 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2214 tab_base = gen_datalabel_ref (tab_base);
2215 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2217 if (TARGET_FPU_ANY && TARGET_SH1)
2218 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2219 else if (TARGET_DIVIDE_CALL2)
2220 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2222 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2225 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2226 (operands[0], operands[3]));
2227 else if (TARGET_FPU_ANY)
2228 last = gen_divsi3_i4_single (operands[0], operands[3]);
2230 last = gen_divsi3_i1 (operands[0], operands[3]);
2234 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2235 last = gen_divsi3_i1 (operands[0], operands[3]);
2237 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2238 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2239 last = emit_insn (last);
2240 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2241 invariant code motion can move it. */
2242 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2243 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2247 ;; operands: inv0, tab_base, tab_ix, norm32
2248 ;; scratch equiv in sdivsi3_2: r19, r21
2249 (define_expand "divsi_inv_m0"
2250 [(set (match_operand:SI 0 "register_operand" "=r")
2251 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2252 (match_operand:DI 2 "register_operand" "r")
2253 (match_operand:SI 3 "register_operand" "r")]
2255 (clobber (match_operand:DI 4 "register_operand" "=r"))
2256 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2264 ldx.ub r20, r21, r19 // u0.8
2266 muls.l r25, r19, r19 // s2.38
2267 ldx.w r20, r21, r21 // s2.14
2268 shari r19, 24, r19 // truncate to s2.14
2269 sub r21, r19, r19 // some 11 bit inverse in s1.14
2272 rtx inv0 = operands[0];
2273 rtx tab_base = operands[1];
2274 rtx tab_ix = operands[2];
2275 rtx norm32 = operands[3];
2276 rtx scratch0 = operands[4];
2277 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2278 rtx scratch1 = operands[5];
2281 mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2282 emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2283 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2284 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2285 mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2286 emit_insn (gen_extendhidi2 (scratch1, mem));
2287 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2288 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2292 ;; operands: inv1, tab_base, tab_ix, norm32
2293 (define_insn_and_split "divsi_inv_m1"
2294 [(set (match_operand:SI 0 "register_operand" "=r")
2295 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2296 (match_operand:DI 2 "register_operand" "r")
2297 (match_operand:SI 3 "register_operand" "r")]
2299 (clobber (match_operand:SI 4 "register_operand" "=r"))
2300 (clobber (match_operand:DI 5 "register_operand" "=r"))
2301 (clobber (match_operand:DI 6 "register_operand" "=r"))
2302 (clobber (match_operand:DI 7 "register_operand" "=r"))
2303 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2311 muls.l r19, r19, r18 // u0.28
2312 muls.l r25, r18, r18 // s2.58
2313 shlli r19, 45, r0 // multiply by two and convert to s2.58
2315 shari r18, 28, r18 // some 18 bit inverse in s1.30
2318 rtx inv1 = operands[0];
2319 rtx tab_base = operands[1];
2320 rtx tab_ix = operands[2];
2321 rtx norm32 = operands[3];
2322 rtx inv0 = operands[4];
2323 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2324 rtx scratch0a = operands[5];
2325 rtx scratch0b = operands[6];
2326 rtx scratch0 = operands[7];
2327 rtx scratch1 = operands[8];
2328 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2330 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2331 scratch0a, scratch0b));
2332 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2333 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2334 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2335 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2336 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2340 ;; operands: inv2, norm32, inv1, i92
2341 (define_insn_and_split "divsi_inv_m2"
2342 [(set (match_operand:SI 0 "register_operand" "=r")
2343 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2344 (match_operand:SI 2 "register_operand" "r")
2345 (match_operand:DI 3 "register_operand" "r")]
2347 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2355 muls.l r18, r25, r0 // s2.60
2356 shari r0, 16, r0 // s-16.44
2358 muls.l r0, r18, r19 // s-16.74
2359 shari r19, 30, r19 // s-16.44
2361 rtx inv2 = operands[0];
2362 rtx norm32 = operands[1];
2363 rtx inv1 = operands[2];
2364 rtx i92 = operands[3];
2365 rtx scratch0 = operands[4];
2366 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2368 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2369 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2370 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2371 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2372 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2376 (define_insn_and_split "divsi_inv_m3"
2377 [(set (match_operand:SI 0 "register_operand" "=r")
2378 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2379 (match_operand:SI 2 "register_operand" "r")
2380 (match_operand:SI 3 "register_operand" "r")
2381 (match_operand:DI 4 "register_operand" "r")
2382 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2383 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2385 (clobber (match_operand:DI 7 "register_operand" "=r"))
2386 (clobber (match_operand:DI 8 "register_operand" "=r"))
2387 (clobber (match_operand:DI 9 "register_operand" "=r"))
2388 (clobber (match_operand:DI 10 "register_operand" "=r"))
2389 (clobber (match_operand:SI 11 "register_operand" "=r"))
2390 (clobber (match_operand:SI 12 "register_operand" "=r"))
2391 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2399 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2400 r0: scratch0 r19: scratch1 r21: scratch2
2402 muls.l r18, r4, r25 // s32.30
2403 muls.l r19, r4, r19 // s15.30
2405 shari r19, 14, r19 // s18.-14
2411 rtx result = operands[0];
2412 rtx dividend = operands[1];
2413 rtx inv1 = operands[2];
2414 rtx inv2 = operands[3];
2415 rtx shift = operands[4];
2416 rtx scratch0 = operands[7];
2417 rtx scratch1 = operands[8];
2418 rtx scratch2 = operands[9];
2420 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2421 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2422 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2423 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2424 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2425 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2426 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2430 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2431 ;; inv1: tab_base, tab_ix, norm32
2432 ;; inv2: norm32, inv1, i92
2433 (define_insn_and_split "divsi_inv_m1_3"
2434 [(set (match_operand:SI 0 "register_operand" "=r")
2435 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2436 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2437 (match_operand:DI 3 "register_operand" "r")
2438 (match_operand:SI 4 "register_operand" "r")]
2440 (unspec:SI [(match_dup 4)
2441 (unspec:SI [(match_dup 2)
2443 (match_dup 4)] UNSPEC_DIV_INV_M1)
2444 (match_operand:SI 5 "" "")]
2446 (match_operand:DI 6 "register_operand" "r")
2447 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2448 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2450 (clobber (match_operand:DI 9 "register_operand" "=r"))
2451 (clobber (match_operand:DI 10 "register_operand" "=r"))
2452 (clobber (match_operand:DI 11 "register_operand" "=r"))
2453 (clobber (match_operand:DI 12 "register_operand" "=r"))
2454 (clobber (match_operand:SI 13 "register_operand" "=r"))
2455 (clobber (match_operand:SI 14 "register_operand" "=r"))
2456 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2458 && (TARGET_DIVIDE_INV_MINLAT
2459 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2465 rtx result = operands[0];
2466 rtx dividend = operands[1];
2467 rtx tab_base = operands[2];
2468 rtx tab_ix = operands[3];
2469 rtx norm32 = operands[4];
2470 /* rtx i92 = operands[5]; */
2471 rtx shift = operands[6];
2472 rtx i2p27 = operands[7];
2473 rtx i43 = operands[8];
2474 rtx scratch0 = operands[9];
2475 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2476 rtx scratch1 = operands[10];
2477 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2478 rtx scratch2 = operands[11];
2479 rtx scratch3 = operands[12];
2480 rtx scratch4 = operands[13];
2481 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2482 rtx scratch5 = operands[14];
2483 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2484 rtx scratch6 = operands[15];
2486 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2487 scratch0, scratch1));
2488 /* inv0 == scratch4 */
2489 if (! TARGET_DIVIDE_INV20U)
2491 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2493 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2497 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2498 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2500 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2501 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2502 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2503 /* inv1 == scratch4 */
2505 if (TARGET_DIVIDE_INV_MINLAT)
2507 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2508 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2509 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2510 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2511 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2512 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2513 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2514 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2515 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2516 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2517 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2521 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2522 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2523 emit_insn (gen_nsbdi (scratch6,
2524 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2525 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2526 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2527 emit_insn (gen_divsi_inv20 (scratch2,
2528 norm32, scratch4, dividend,
2529 scratch6, scratch3, i43,
2530 /* scratch0 may be shared with i2p27. */
2531 scratch0, scratch1, scratch5,
2532 label, label, i2p27));
2534 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2535 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2539 (define_insn "divsi_inv20"
2540 [(set (match_operand:DI 0 "register_operand" "=&r")
2541 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2542 (match_operand:SI 2 "register_operand" "r")
2543 (match_operand:SI 3 "register_operand" "r")
2544 (match_operand:DI 4 "register_operand" "r")
2545 (match_operand:DI 5 "register_operand" "r")
2546 (match_operand:DI 6 "register_operand" "r")
2547 (match_operand:DI 12 "register_operand" "r")
2548 (match_operand 10 "target_operand" "b")
2549 (match_operand 11 "immediate_operand" "i")]
2551 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2552 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2553 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2555 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2558 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2559 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2560 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2561 %10 label (tr), %11 label (imm)
2563 muls.l inv1, norm32, scratch0 // s2.60
2564 muls.l inv1, dividend, result // s32.30
2565 xor i2p27, result_sign, round_scratch
2566 bge/u dividend_nsb, i43, tr.. (label)
2567 shari scratch0, 16, scratch0 // s-16.44
2568 muls.l sratch0_si, inv1, scratch0 // s-16.74
2569 sub result, round_scratch, result
2570 shari dividend, 14, scratch1 // s19.-14
2571 shari scratch0, 30, scratch0 // s-16.44
2572 muls.l scratch0, scratch1, round_scratch // s15.30
2574 sub result, round_scratch, result */
2576 int likely = TARGET_DIVIDE_INV20L;
2578 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2579 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2580 output_asm_insn (likely
2581 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2582 : \"bge/u\t%4, %6, %10\", operands);
2583 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2584 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2585 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2587 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2588 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2591 (define_insn_and_split "divsi_inv_fp"
2592 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2593 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2594 (match_operand:SI 2 "register_operand" "rf")))
2595 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2596 (clobber (match_operand:SI 4 "register_operand" "=r"))
2597 (clobber (match_operand:SI 5 "register_operand" "=r"))
2598 (clobber (match_operand:DF 6 "register_operand" "=r"))
2599 (clobber (match_operand:DF 7 "register_operand" "=r"))
2600 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2601 "TARGET_SHMEDIA_FPU"
2603 "&& (high_life_started || reload_completed)"
2604 [(set (match_dup 0) (match_dup 3))]
2606 [(set_attr "highpart" "must_split")])
2608 ;; If a matching group of divide-by-inverse instructions is in the same
2609 ;; basic block after gcse & loop optimizations, we want to transform them
2610 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2611 (define_insn_and_split "*divsi_inv_fp_combine"
2612 [(set (match_operand:SI 0 "register_operand" "=f")
2613 (div:SI (match_operand:SI 1 "register_operand" "f")
2614 (match_operand:SI 2 "register_operand" "f")))
2615 (use (unspec:SI [(match_dup 1)
2616 (match_operand:SI 3 "" "")
2617 (unspec:SI [(match_operand:SI 4 "" "")
2619 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2620 (match_operand:DI 6 "" "")
2622 (const_int 0)] UNSPEC_DIV_INV_M3))
2623 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2624 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2625 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2626 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2627 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2628 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2631 [(set (match_dup 9) (float:DF (match_dup 1)))
2632 (set (match_dup 10) (float:DF (match_dup 2)))
2633 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2635 (fix:SI (match_dup 11)))
2636 (set (match_dup 0) (match_dup 8))]
2639 if (! fp_arith_reg_operand (operands[1], SImode))
2641 emit_move_insn (operands[7], operands[1]);
2642 operands[1] = operands[7];
2644 if (! fp_arith_reg_operand (operands[2], SImode))
2646 emit_move_insn (operands[8], operands[2]);
2647 operands[2] = operands[8];
2650 [(set_attr "highpart" "must_split")])
2652 ;; -------------------------------------------------------------------------
2653 ;; Multiplication instructions
2654 ;; -------------------------------------------------------------------------
2656 (define_insn "umulhisi3_i"
2657 [(set (reg:SI MACL_REG)
2658 (mult:SI (zero_extend:SI
2659 (match_operand:HI 0 "arith_reg_operand" "r"))
2661 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2664 [(set_attr "type" "smpy")])
2666 (define_insn "mulhisi3_i"
2667 [(set (reg:SI MACL_REG)
2668 (mult:SI (sign_extend:SI
2669 (match_operand:HI 0 "arith_reg_operand" "r"))
2671 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2674 [(set_attr "type" "smpy")])
2676 (define_expand "mulhisi3"
2677 [(set (reg:SI MACL_REG)
2678 (mult:SI (sign_extend:SI
2679 (match_operand:HI 1 "arith_reg_operand" ""))
2681 (match_operand:HI 2 "arith_reg_operand" ""))))
2682 (set (match_operand:SI 0 "arith_reg_operand" "")
2689 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2690 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2691 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2692 invariant code motion can move it. */
2693 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2694 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2695 /* expand_binop can't find a suitable code in umul_widen_optab to
2696 make a REG_EQUAL note from, so make one here.
2697 See also smulsi3_highpart.
2698 ??? Alternatively, we could put this at the calling site of expand_binop,
2699 i.e. expand_expr. */
2701 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2706 (define_expand "umulhisi3"
2707 [(set (reg:SI MACL_REG)
2708 (mult:SI (zero_extend:SI
2709 (match_operand:HI 1 "arith_reg_operand" ""))
2711 (match_operand:HI 2 "arith_reg_operand" ""))))
2712 (set (match_operand:SI 0 "arith_reg_operand" "")
2719 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2720 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2721 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2722 invariant code motion can move it. */
2723 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2724 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2725 /* expand_binop can't find a suitable code in umul_widen_optab to
2726 make a REG_EQUAL note from, so make one here.
2727 See also smulsi3_highpart.
2728 ??? Alternatively, we could put this at the calling site of expand_binop,
2729 i.e. expand_expr. */
2731 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2736 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2737 ;; a call to a routine which clobbers known registers.
2740 [(set (match_operand:SI 1 "register_operand" "=z")
2741 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2742 (clobber (reg:SI MACL_REG))
2743 (clobber (reg:SI T_REG))
2744 (clobber (reg:SI PR_REG))
2745 (clobber (reg:SI R3_REG))
2746 (clobber (reg:SI R2_REG))
2747 (clobber (reg:SI R1_REG))
2748 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2751 [(set_attr "type" "sfunc")
2752 (set_attr "needs_delay_slot" "yes")])
2754 (define_expand "mulsi3_call"
2755 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2756 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2757 (parallel[(set (match_operand:SI 0 "register_operand" "")
2758 (mult:SI (reg:SI R4_REG)
2760 (clobber (reg:SI MACL_REG))
2761 (clobber (reg:SI T_REG))
2762 (clobber (reg:SI PR_REG))
2763 (clobber (reg:SI R3_REG))
2764 (clobber (reg:SI R2_REG))
2765 (clobber (reg:SI R1_REG))
2766 (use (match_operand:SI 3 "register_operand" ""))])]
2770 (define_insn "mul_r"
2771 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2772 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2773 (match_operand:SI 2 "arith_reg_operand" "z")))]
2776 [(set_attr "type" "dmpy")])
2778 (define_insn "mul_l"
2779 [(set (reg:SI MACL_REG)
2780 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2781 (match_operand:SI 1 "arith_reg_operand" "r")))]
2784 [(set_attr "type" "dmpy")])
2786 (define_expand "mulsi3"
2787 [(set (reg:SI MACL_REG)
2788 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2789 (match_operand:SI 2 "arith_reg_operand" "")))
2790 (set (match_operand:SI 0 "arith_reg_operand" "")
2799 /* The address must be set outside the libcall,
2800 since it goes into a pseudo. */
2801 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2802 rtx addr = force_reg (SImode, sym);
2803 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2806 last = emit_insn (insns);
2810 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2812 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2813 /* consec_sets_giv can only recognize the first insn that sets a
2814 giv as the giv insn. So we must tag this also with a REG_EQUAL
2816 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2818 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2819 invariant code motion can move it. */
2820 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2821 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2825 (define_insn "mulsidi3_i"
2826 [(set (reg:SI MACH_REG)
2830 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2831 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2833 (set (reg:SI MACL_REG)
2834 (mult:SI (match_dup 0)
2838 [(set_attr "type" "dmpy")])
2840 (define_expand "mulsidi3"
2841 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2842 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2843 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2844 "TARGET_SH2 || TARGET_SHMEDIA"
2849 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2855 (define_insn "mulsidi3_media"
2856 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2857 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2858 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2861 [(set_attr "type" "dmpy_media")
2862 (set_attr "highpart" "ignore")])
2864 (define_insn "mulsidi3_compact"
2865 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2867 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2868 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2869 (clobber (reg:SI MACH_REG))
2870 (clobber (reg:SI MACL_REG))]
2875 [(set (match_operand:DI 0 "arith_reg_dest" "")
2877 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2878 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2879 (clobber (reg:SI MACH_REG))
2880 (clobber (reg:SI MACL_REG))]
2885 rtx low_dst = gen_lowpart (SImode, operands[0]);
2886 rtx high_dst = gen_highpart (SImode, operands[0]);
2888 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2890 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2891 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2892 /* We need something to tag the possible REG_EQUAL notes on to. */
2893 emit_move_insn (operands[0], operands[0]);
2897 (define_insn "umulsidi3_i"
2898 [(set (reg:SI MACH_REG)
2902 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2903 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2905 (set (reg:SI MACL_REG)
2906 (mult:SI (match_dup 0)
2910 [(set_attr "type" "dmpy")])
2912 (define_expand "umulsidi3"
2913 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2914 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2916 "TARGET_SH2 || TARGET_SHMEDIA"
2921 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2927 (define_insn "umulsidi3_media"
2928 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2929 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2930 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2933 [(set_attr "type" "dmpy_media")
2934 (set_attr "highpart" "ignore")])
2936 (define_insn "umulsidi3_compact"
2937 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2939 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2940 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2941 (clobber (reg:SI MACH_REG))
2942 (clobber (reg:SI MACL_REG))]
2947 [(set (match_operand:DI 0 "arith_reg_dest" "")
2948 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2949 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2950 (clobber (reg:SI MACH_REG))
2951 (clobber (reg:SI MACL_REG))]
2956 rtx low_dst = gen_lowpart (SImode, operands[0]);
2957 rtx high_dst = gen_highpart (SImode, operands[0]);
2959 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2961 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2962 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2963 /* We need something to tag the possible REG_EQUAL notes on to. */
2964 emit_move_insn (operands[0], operands[0]);
2968 (define_insn "smulsi3_highpart_i"
2969 [(set (reg:SI MACH_REG)
2973 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2974 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2976 (clobber (reg:SI MACL_REG))]
2979 [(set_attr "type" "dmpy")])
2981 (define_expand "smulsi3_highpart"
2983 [(set (reg:SI MACH_REG)
2987 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2988 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2990 (clobber (reg:SI MACL_REG))])
2991 (set (match_operand:SI 0 "arith_reg_operand" "")
2998 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2999 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3000 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3001 invariant code motion can move it. */
3002 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3003 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3004 /* expand_binop can't find a suitable code in mul_highpart_optab to
3005 make a REG_EQUAL note from, so make one here.
3006 See also {,u}mulhisi.
3007 ??? Alternatively, we could put this at the calling site of expand_binop,
3008 i.e. expand_mult_highpart. */
3010 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
3015 (define_insn "umulsi3_highpart_i"
3016 [(set (reg:SI MACH_REG)
3020 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3023 (clobber (reg:SI MACL_REG))]
3026 [(set_attr "type" "dmpy")])
3028 (define_expand "umulsi3_highpart"
3030 [(set (reg:SI MACH_REG)
3034 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3037 (clobber (reg:SI MACL_REG))])
3038 (set (match_operand:SI 0 "arith_reg_operand" "")
3045 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3046 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3047 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3048 invariant code motion can move it. */
3049 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3050 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3054 (define_insn_and_split "muldi3"
3055 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3056 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3057 (match_operand:DI 2 "arith_reg_operand" "r")))
3058 (clobber (match_scratch:DI 3 "=&r"))
3059 (clobber (match_scratch:DI 4 "=r"))]
3066 rtx op3_v2si, op2_v2si;
3068 op3_v2si = operands[3];
3069 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3071 op3_v2si = XEXP (op3_v2si, 0);
3072 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3074 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3075 op2_v2si = operands[2];
3076 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3078 op2_v2si = XEXP (op2_v2si, 0);
3079 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3081 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3082 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3083 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3084 emit_insn (gen_umulsidi3_media (operands[4],
3085 sh_gen_truncate (SImode, operands[1], 0),
3086 sh_gen_truncate (SImode, operands[2], 0)));
3087 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3088 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3089 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3090 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3095 ;; -------------------------------------------------------------------------
3096 ;; Logical operations
3097 ;; -------------------------------------------------------------------------
3099 (define_insn "*andsi3_compact"
3100 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3101 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3102 (match_operand:SI 2 "logical_operand" "r,K08")))]
3105 [(set_attr "type" "arith")])
3107 (define_insn "*andsi3_media"
3108 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3109 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3110 (match_operand:SI 2 "logical_operand" "r,I10")))]
3115 [(set_attr "type" "arith_media")])
3117 ;; If the constant is 255, then emit an extu.b instruction instead of an
3118 ;; and, since that will give better code.
3120 (define_expand "andsi3"
3121 [(set (match_operand:SI 0 "arith_reg_operand" "")
3122 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3123 (match_operand:SI 2 "logical_operand" "")))]
3128 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3130 emit_insn (gen_zero_extendqisi2 (operands[0],
3131 gen_lowpart (QImode, operands[1])));
3136 (define_insn_and_split "anddi3"
3137 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3138 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3139 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3146 && ! logical_operand (operands[2], DImode)"
3150 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3151 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3153 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3156 [(set_attr "type" "arith_media")])
3158 (define_insn "andcsi3"
3159 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3160 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3161 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3164 [(set_attr "type" "arith_media")])
3166 (define_insn "andcdi3"
3167 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3168 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3169 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3172 [(set_attr "type" "arith_media")])
3174 (define_expand "iorsi3"
3175 [(set (match_operand:SI 0 "arith_reg_operand" "")
3176 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3177 (match_operand:SI 2 "logical_operand" "")))]
3181 (define_insn "*iorsi3_compact"
3182 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3183 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3184 (match_operand:SI 2 "logical_operand" "r,K08")))]
3187 [(set_attr "type" "arith")])
3189 (define_insn "*iorsi3_media"
3190 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3191 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3192 (match_operand:SI 2 "logical_operand" "r,I10")))]
3197 [(set_attr "type" "arith_media")])
3199 (define_insn "iordi3"
3200 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3201 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3202 (match_operand:DI 2 "logical_operand" "r,I10")))]
3207 [(set_attr "type" "arith_media")])
3209 (define_insn_and_split "*logical_sidi3"
3210 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3211 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3212 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3213 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3216 "&& reload_completed"
3217 [(set (match_dup 0) (match_dup 3))]
3221 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3222 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3223 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3226 (define_insn_and_split "*logical_sidisi3"
3227 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3228 (truncate:SI (sign_extend:DI
3229 (match_operator:SI 3 "logical_operator"
3230 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3231 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3235 [(set (match_dup 0) (match_dup 3))])
3237 (define_insn_and_split "*logical_sidi3_2"
3238 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3239 (sign_extend:DI (truncate:SI (sign_extend:DI
3240 (match_operator:SI 3 "logical_operator"
3241 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3242 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3246 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3248 (define_expand "xorsi3"
3249 [(set (match_operand:SI 0 "arith_reg_operand" "")
3250 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3251 (match_operand:SI 2 "xor_operand" "")))]
3255 (define_insn "*xorsi3_compact"
3256 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3257 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3258 (match_operand:SI 2 "logical_operand" "K08,r")))]
3261 [(set_attr "type" "arith")])
3263 (define_insn "*xorsi3_media"
3264 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3265 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3266 (match_operand:SI 2 "xor_operand" "r,I06")))]
3271 [(set_attr "type" "arith_media")])
3273 (define_insn "xordi3"
3274 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3275 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3276 (match_operand:DI 2 "xor_operand" "r,I06")))]
3281 [(set_attr "type" "arith_media")])
3283 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3284 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3286 [(set (match_operand:DI 0 "arith_reg_dest" "")
3287 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3288 [(match_operand 1 "any_register_operand" "")
3289 (match_operand 2 "any_register_operand" "")])))]
3291 [(set (match_dup 5) (match_dup 4))
3292 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3295 enum machine_mode inmode = GET_MODE (operands[1]);
3298 if (GET_CODE (operands[0]) == SUBREG)
3300 offset = SUBREG_BYTE (operands[0]);
3301 operands[0] = SUBREG_REG (operands[0]);
3303 gcc_assert (GET_CODE (operands[0]) == REG);
3304 if (! TARGET_LITTLE_ENDIAN)
3305 offset += 8 - GET_MODE_SIZE (inmode);
3306 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3309 ;; -------------------------------------------------------------------------
3310 ;; Shifts and rotates
3311 ;; -------------------------------------------------------------------------
3313 (define_expand "rotldi3"
3314 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3315 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3316 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3318 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3320 (define_insn "rotldi3_mextr"
3321 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3322 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3323 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3327 static char templ[16];
3329 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3330 8 - (int) (INTVAL (operands[2]) >> 3));
3333 [(set_attr "type" "arith_media")])
3335 (define_expand "rotrdi3"
3336 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3337 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3338 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3340 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3342 (define_insn "rotrdi3_mextr"
3343 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3344 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3345 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3349 static char templ[16];
3351 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3354 [(set_attr "type" "arith_media")])
3357 [(set (match_operand:DI 0 "arith_reg_dest" "")
3358 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3359 "ua_address_operand" "")))
3360 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3362 (clobber (match_operand:DI 3 "register_operand" ""))]
3364 [(match_dup 4) (match_dup 5)]
3367 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3368 (operands[3], operands[1]));
3369 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3370 GEN_INT (56), GEN_INT (8));
3373 (define_insn "rotlsi3_1"
3374 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3375 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3378 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3381 [(set_attr "type" "arith")])
3383 (define_insn "rotlsi3_31"
3384 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3385 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3387 (clobber (reg:SI T_REG))]
3390 [(set_attr "type" "arith")])
3392 (define_insn "rotlsi3_16"
3393 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3394 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3398 [(set_attr "type" "arith")])
3400 (define_expand "rotlsi3"
3401 [(set (match_operand:SI 0 "arith_reg_dest" "")
3402 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3403 (match_operand:SI 2 "immediate_operand" "")))]
3407 static const char rot_tab[] = {
3408 000, 000, 000, 000, 000, 000, 010, 001,
3409 001, 001, 011, 013, 003, 003, 003, 003,
3410 003, 003, 003, 003, 003, 013, 012, 002,
3411 002, 002, 010, 000, 000, 000, 000, 000,
3416 if (GET_CODE (operands[2]) != CONST_INT)
3418 count = INTVAL (operands[2]);
3419 choice = rot_tab[count];
3420 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3426 emit_move_insn (operands[0], operands[1]);
3427 count -= (count & 16) * 2;
3430 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3437 parts[0] = gen_reg_rtx (SImode);
3438 parts[1] = gen_reg_rtx (SImode);
3439 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3440 emit_move_insn (parts[choice-1], operands[1]);
3441 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3442 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3443 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3444 count = (count & ~16) - 8;
3448 for (; count > 0; count--)
3449 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3450 for (; count < 0; count++)
3451 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3456 (define_insn "*rotlhi3_8"
3457 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3458 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3462 [(set_attr "type" "arith")])
3464 (define_expand "rotlhi3"
3465 [(set (match_operand:HI 0 "arith_reg_operand" "")
3466 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3467 (match_operand:HI 2 "immediate_operand" "")))]
3471 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3478 (define_insn "ashlsi3_sh2a"
3479 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3480 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3481 (match_operand:SI 2 "arith_reg_operand" "r")))]
3484 [(set_attr "type" "arith")
3485 (set_attr "length" "4")])
3487 ;; This pattern is used by init_expmed for computing the costs of shift
3490 (define_insn_and_split "ashlsi3_std"
3491 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3492 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3493 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3494 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3496 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3497 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3505 && GET_CODE (operands[2]) == CONST_INT
3506 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3507 [(set (match_dup 3) (match_dup 2))
3509 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3510 (clobber (match_dup 4))])]
3511 "operands[4] = gen_rtx_SCRATCH (SImode);"
3512 [(set_attr "length" "*,*,*,4")
3513 (set_attr "type" "dyn_shift,arith,arith,arith")])
3515 (define_insn "ashlhi3_k"
3516 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3517 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3518 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3519 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3523 [(set_attr "type" "arith")])
3525 (define_insn "ashlsi3_n"
3526 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3527 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3528 (match_operand:SI 2 "const_int_operand" "n")))
3529 (clobber (reg:SI T_REG))]
3530 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3532 [(set (attr "length")
3533 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3535 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3537 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3539 (const_string "8")))
3540 (set_attr "type" "arith")])
3543 [(set (match_operand:SI 0 "arith_reg_dest" "")
3544 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3545 (match_operand:SI 2 "const_int_operand" "")))
3546 (clobber (reg:SI T_REG))]
3547 "TARGET_SH1 && reload_completed"
3548 [(use (reg:SI R0_REG))]
3551 gen_shifty_op (ASHIFT, operands);
3555 (define_insn "ashlsi3_media"
3556 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3557 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3558 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3563 [(set_attr "type" "arith_media")
3564 (set_attr "highpart" "ignore")])
3566 (define_expand "ashlsi3"
3567 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3568 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3569 (match_operand:SI 2 "nonmemory_operand" "")))
3570 (clobber (reg:SI T_REG))])]
3576 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3579 if (GET_CODE (operands[2]) == CONST_INT
3580 && sh_dynamicalize_shift_p (operands[2]))
3581 operands[2] = force_reg (SImode, operands[2]);
3584 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3587 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3591 (define_insn "*ashlhi3_n"
3592 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3593 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3594 (match_operand:HI 2 "const_int_operand" "n")))
3595 (clobber (reg:SI T_REG))]
3598 [(set (attr "length")
3599 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3601 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3603 (const_string "6")))
3604 (set_attr "type" "arith")])
3606 (define_expand "ashlhi3"
3607 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3608 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3609 (match_operand:SI 2 "nonmemory_operand" "")))
3610 (clobber (reg:SI T_REG))])]
3614 if (GET_CODE (operands[2]) != CONST_INT)
3616 /* It may be possible to call gen_ashlhi3 directly with more generic
3617 operands. Make sure operands[1] is a HImode register here. */
3618 if (!arith_reg_operand (operands[1], HImode))
3619 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3623 [(set (match_operand:HI 0 "arith_reg_dest" "")
3624 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3625 (match_operand:HI 2 "const_int_operand" "")))
3626 (clobber (reg:SI T_REG))]
3627 "TARGET_SH1 && reload_completed"
3628 [(use (reg:SI R0_REG))]
3631 gen_shifty_hi_op (ASHIFT, operands);
3636 ; arithmetic shift right
3639 (define_insn "ashrsi3_sh2a"
3640 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3641 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3642 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3645 [(set_attr "type" "dyn_shift")
3646 (set_attr "length" "4")])
3648 (define_insn "ashrsi3_k"
3649 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3650 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3651 (match_operand:SI 2 "const_int_operand" "M")))
3652 (clobber (reg:SI T_REG))]
3653 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3655 [(set_attr "type" "arith")])
3657 ;; We can't do HImode right shifts correctly unless we start out with an
3658 ;; explicit zero / sign extension; doing that would result in worse overall
3659 ;; code, so just let the machine independent code widen the mode.
3660 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3663 ;; ??? This should be a define expand.
3665 (define_insn "ashrsi2_16"
3666 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3667 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3671 [(set_attr "length" "4")])
3674 [(set (match_operand:SI 0 "arith_reg_dest" "")
3675 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3678 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3679 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3680 "operands[2] = gen_lowpart (HImode, operands[0]);")
3682 ;; ??? This should be a define expand.
3684 (define_insn "ashrsi2_31"
3685 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3686 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3688 (clobber (reg:SI T_REG))]
3691 [(set_attr "length" "4")])
3694 [(set (match_operand:SI 0 "arith_reg_dest" "")
3695 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3697 (clobber (reg:SI T_REG))]
3702 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3703 emit_insn (gen_mov_neg_si_t (operands[0]));
3708 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3710 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3712 && peep2_reg_dead_p (2, operands[0])
3713 && peep2_reg_dead_p (2, operands[1])"
3717 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3721 (define_insn "ashlsi_c"
3722 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3723 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3725 (lt:SI (match_dup 1) (const_int 0)))]
3728 [(set_attr "type" "arith")])
3730 (define_insn "*ashlsi_c_void"
3731 [(set (reg:SI T_REG)
3732 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3733 (clobber (match_scratch:SI 1 "=0"))]
3734 "TARGET_SH1 && cse_not_expected"
3736 [(set_attr "type" "arith")])
3738 (define_insn "ashrsi3_d"
3739 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3740 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3741 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3744 [(set_attr "type" "dyn_shift")])
3746 (define_insn "ashrsi3_n"
3747 [(set (reg:SI R4_REG)
3748 (ashiftrt:SI (reg:SI R4_REG)
3749 (match_operand:SI 0 "const_int_operand" "i")))
3750 (clobber (reg:SI T_REG))
3751 (clobber (reg:SI PR_REG))
3752 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3755 [(set_attr "type" "sfunc")
3756 (set_attr "needs_delay_slot" "yes")])
3758 (define_insn "ashrsi3_media"
3759 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3760 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3761 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3766 [(set_attr "type" "arith_media")
3767 (set_attr "highpart" "ignore")])
3769 (define_expand "ashrsi3"
3770 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3771 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3772 (match_operand:SI 2 "nonmemory_operand" "")))
3773 (clobber (reg:SI T_REG))])]
3779 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3782 if (expand_ashiftrt (operands))
3788 ;; logical shift right
3790 (define_insn "lshrsi3_sh2a"
3791 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3792 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3793 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3796 [(set_attr "type" "dyn_shift")
3797 (set_attr "length" "4")])
3799 (define_insn "lshrsi3_d"
3800 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3801 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3802 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3805 [(set_attr "type" "dyn_shift")])
3807 ;; Only the single bit shift clobbers the T bit.
3809 (define_insn "lshrsi3_m"
3810 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3811 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3812 (match_operand:SI 2 "const_int_operand" "M")))
3813 (clobber (reg:SI T_REG))]
3814 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3816 [(set_attr "type" "arith")])
3818 (define_insn "lshrsi3_k"
3819 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3820 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3821 (match_operand:SI 2 "const_int_operand" "P27")))]
3822 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3823 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3825 [(set_attr "type" "arith")])
3827 (define_insn "lshrsi3_n"
3828 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3829 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3830 (match_operand:SI 2 "const_int_operand" "n")))
3831 (clobber (reg:SI T_REG))]
3832 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3834 [(set (attr "length")
3835 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3837 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3839 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3841 (const_string "8")))
3842 (set_attr "type" "arith")])
3845 [(set (match_operand:SI 0 "arith_reg_dest" "")
3846 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3847 (match_operand:SI 2 "const_int_operand" "")))
3848 (clobber (reg:SI T_REG))]
3849 "TARGET_SH1 && reload_completed"
3850 [(use (reg:SI R0_REG))]
3853 gen_shifty_op (LSHIFTRT, operands);
3857 (define_insn "lshrsi3_media"
3858 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3859 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3860 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3865 [(set_attr "type" "arith_media")
3866 (set_attr "highpart" "ignore")])
3868 (define_expand "lshrsi3"
3869 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3870 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3871 (match_operand:SI 2 "nonmemory_operand" "")))
3872 (clobber (reg:SI T_REG))])]
3878 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3881 if (GET_CODE (operands[2]) == CONST_INT
3882 && sh_dynamicalize_shift_p (operands[2]))
3883 operands[2] = force_reg (SImode, operands[2]);
3884 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3886 rtx count = copy_to_mode_reg (SImode, operands[2]);
3887 emit_insn (gen_negsi2 (count, count));
3888 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3891 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3895 ;; ??? This should be a define expand.
3897 (define_insn "ashldi3_k"
3898 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3899 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3901 (clobber (reg:SI T_REG))]
3903 "shll %R0\;rotcl %S0"
3904 [(set_attr "length" "4")
3905 (set_attr "type" "arith")])
3907 (define_insn "ashldi3_media"
3908 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3909 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3910 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3915 [(set_attr "type" "arith_media")])
3917 (define_insn "*ashldisi3_media"
3918 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3919 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3920 (match_operand:DI 2 "const_int_operand" "n")))]
3921 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3922 "shlli.l %1, %2, %0"
3923 [(set_attr "type" "arith_media")
3924 (set_attr "highpart" "ignore")])
3926 (define_expand "ashldi3"
3927 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3928 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3929 (match_operand:DI 2 "immediate_operand" "")))
3930 (clobber (reg:SI T_REG))])]
3936 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3939 if (GET_CODE (operands[2]) != CONST_INT
3940 || INTVAL (operands[2]) != 1)
3944 ;; ??? This should be a define expand.
3946 (define_insn "lshrdi3_k"
3947 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3950 (clobber (reg:SI T_REG))]
3952 "shlr %S0\;rotcr %R0"
3953 [(set_attr "length" "4")
3954 (set_attr "type" "arith")])
3956 (define_insn "lshrdi3_media"
3957 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3958 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3959 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3961 && (arith_reg_dest (operands[0], DImode)
3962 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3966 [(set_attr "type" "arith_media")])
3968 (define_insn "*lshrdisi3_media"
3969 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3970 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3971 (match_operand:DI 2 "const_int_operand" "n")))]
3972 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3973 "shlri.l %1, %2, %0"
3974 [(set_attr "type" "arith_media")
3975 (set_attr "highpart" "ignore")])
3977 (define_expand "lshrdi3"
3978 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3979 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3980 (match_operand:DI 2 "immediate_operand" "")))
3981 (clobber (reg:SI T_REG))])]
3987 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3990 if (GET_CODE (operands[2]) != CONST_INT
3991 || INTVAL (operands[2]) != 1)
3995 ;; ??? This should be a define expand.
3997 (define_insn "ashrdi3_k"
3998 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3999 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4001 (clobber (reg:SI T_REG))]
4003 "shar %S0\;rotcr %R0"
4004 [(set_attr "length" "4")
4005 (set_attr "type" "arith")])
4007 (define_insn "ashrdi3_media"
4008 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4009 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4010 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4012 && (arith_reg_dest (operands[0], DImode)
4013 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4017 [(set_attr "type" "arith_media")])
4019 (define_insn "*ashrdisi3_media"
4020 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4021 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4022 (match_operand:DI 2 "const_int_operand" "n")))]
4023 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4024 "shari.l %1, %2, %0"
4025 [(set_attr "type" "arith_media")
4026 (set_attr "highpart" "ignore")])
4028 (define_insn "ashrdisi3_media_high"
4029 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4031 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4032 (match_operand:DI 2 "const_int_operand" "n"))))]
4033 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4035 [(set_attr "type" "arith_media")])
4037 (define_insn "ashrdisi3_media_opaque"
4038 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4039 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4040 (match_operand:DI 2 "const_int_operand" "n")]
4044 [(set_attr "type" "arith_media")])
4046 (define_expand "ashrdi3"
4047 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4048 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4049 (match_operand:DI 2 "immediate_operand" "")))
4050 (clobber (reg:SI T_REG))])]
4056 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4059 if (GET_CODE (operands[2]) != CONST_INT
4060 || INTVAL (operands[2]) != 1)
4064 ;; combined left/right shift
4067 [(set (match_operand:SI 0 "register_operand" "")
4068 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4069 (match_operand:SI 2 "const_int_operand" ""))
4070 (match_operand:SI 3 "const_int_operand" "")))]
4071 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4072 [(use (reg:SI R0_REG))]
4073 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4077 [(set (match_operand:SI 0 "register_operand" "")
4078 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4079 (match_operand:SI 2 "const_int_operand" ""))
4080 (match_operand:SI 3 "const_int_operand" "")))
4081 (clobber (reg:SI T_REG))]
4082 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4083 [(use (reg:SI R0_REG))]
4084 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4088 [(set (match_operand:SI 0 "register_operand" "=r")
4089 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4090 (match_operand:SI 2 "const_int_operand" "n"))
4091 (match_operand:SI 3 "const_int_operand" "n")))
4092 (clobber (reg:SI T_REG))]
4093 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4095 [(set (attr "length")
4096 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4098 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4100 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4102 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4104 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4106 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4108 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4109 (const_string "16")]
4110 (const_string "18")))
4111 (set_attr "type" "arith")])
4114 [(set (match_operand:SI 0 "register_operand" "=z")
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) == 2"
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 (const_string "10")))
4129 (set_attr "type" "arith")])
4131 ;; shift left / and combination with a scratch register: The combine pass
4132 ;; does not accept the individual instructions, even though they are
4133 ;; cheap. But it needs a precise description so that it is usable after
4135 (define_insn "and_shl_scratch"
4136 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4140 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4141 (match_operand:SI 2 "const_int_operand" "N,n"))
4142 (match_operand:SI 3 "" "0,r"))
4143 (match_operand:SI 4 "const_int_operand" "n,n"))
4144 (match_operand:SI 5 "const_int_operand" "n,n")))
4145 (clobber (reg:SI T_REG))]
4148 [(set (attr "length")
4149 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4151 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4153 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4155 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4156 (const_string "10")]
4157 (const_string "12")))
4158 (set_attr "type" "arith")])
4161 [(set (match_operand:SI 0 "register_operand" "")
4165 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4166 (match_operand:SI 2 "const_int_operand" ""))
4167 (match_operand:SI 3 "register_operand" ""))
4168 (match_operand:SI 4 "const_int_operand" ""))
4169 (match_operand:SI 5 "const_int_operand" "")))
4170 (clobber (reg:SI T_REG))]
4172 [(use (reg:SI R0_REG))]
4175 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4177 if (INTVAL (operands[2]))
4179 gen_shifty_op (LSHIFTRT, operands);
4181 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4182 operands[2] = operands[4];
4183 gen_shifty_op (ASHIFT, operands);
4184 if (INTVAL (operands[5]))
4186 operands[2] = operands[5];
4187 gen_shifty_op (LSHIFTRT, operands);
4192 ;; signed left/right shift combination.
4194 [(set (match_operand:SI 0 "register_operand" "")
4196 (ashift:SI (match_operand:SI 1 "register_operand" "")
4197 (match_operand:SI 2 "const_int_operand" ""))
4198 (match_operand:SI 3 "const_int_operand" "")
4200 (clobber (reg:SI T_REG))]
4202 [(use (reg:SI R0_REG))]
4203 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4206 (define_insn "shl_sext_ext"
4207 [(set (match_operand:SI 0 "register_operand" "=r")
4209 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4210 (match_operand:SI 2 "const_int_operand" "n"))
4211 (match_operand:SI 3 "const_int_operand" "n")
4213 (clobber (reg:SI T_REG))]
4214 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4216 [(set (attr "length")
4217 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4219 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4221 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4223 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4225 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4227 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4229 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4231 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4232 (const_string "16")]
4233 (const_string "18")))
4234 (set_attr "type" "arith")])
4236 (define_insn "shl_sext_sub"
4237 [(set (match_operand:SI 0 "register_operand" "=z")
4239 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4240 (match_operand:SI 2 "const_int_operand" "n"))
4241 (match_operand:SI 3 "const_int_operand" "n")
4243 (clobber (reg:SI T_REG))]
4244 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4246 [(set (attr "length")
4247 (cond [(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))
4254 (const_string "12")]
4255 (const_string "14")))
4256 (set_attr "type" "arith")])
4258 ;; These patterns are found in expansions of DImode shifts by 16, and
4259 ;; allow the xtrct instruction to be generated from C source.
4261 (define_insn "xtrct_left"
4262 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4263 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4265 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4269 [(set_attr "type" "arith")])
4271 (define_insn "xtrct_right"
4272 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4273 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4275 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4279 [(set_attr "type" "arith")])
4281 ;; -------------------------------------------------------------------------
4283 ;; -------------------------------------------------------------------------
4286 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4287 (neg:SI (plus:SI (reg:SI T_REG)
4288 (match_operand:SI 1 "arith_reg_operand" "r"))))
4290 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4294 [(set_attr "type" "arith")])
4296 (define_insn "*negdi_media"
4297 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4298 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4301 [(set_attr "type" "arith_media")])
4303 (define_expand "negdi2"
4304 [(set (match_operand:DI 0 "arith_reg_operand" "")
4305 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4311 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4312 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4314 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4315 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4317 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4318 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4320 emit_insn (gen_clrt ());
4321 emit_insn (gen_negc (low_dst, low_src));
4322 emit_insn (gen_negc (high_dst, high_src));
4327 (define_insn "negsi2"
4328 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4329 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4332 [(set_attr "type" "arith")])
4334 (define_insn "one_cmplsi2"
4335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4339 [(set_attr "type" "arith")])
4341 (define_expand "one_cmpldi2"
4342 [(set (match_operand:DI 0 "arith_reg_dest" "")
4343 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4345 "TARGET_SHMEDIA" "")
4347 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4348 This can be used as some kind of conditional execution, which is useful
4351 [(set (match_operand:SI 0 "arith_reg_dest" "")
4352 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4353 (match_operand:SI 1 "arith_reg_operand" ""))
4357 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4358 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4362 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4363 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4364 (match_operand:SI 1 "arith_reg_operand" "0")
4365 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4367 "bf 0f\;neg %2,%0\\n0:"
4368 [(set_attr "type" "arith") ;; poor approximation
4369 (set_attr "length" "4")])
4372 ;; -------------------------------------------------------------------------
4373 ;; Zero extension instructions
4374 ;; -------------------------------------------------------------------------
4376 (define_insn "zero_extendsidi2"
4377 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4378 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4380 "addz.l %1, r63, %0"
4381 [(set_attr "type" "arith_media")
4382 (set_attr "highpart" "extend")])
4384 (define_insn "zero_extendhidi2"
4385 [(set (match_operand:DI 0 "register_operand" "=r,r")
4386 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4391 [(set_attr "type" "*,load_media")
4392 (set (attr "highpart")
4393 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4394 (const_string "user")]
4395 (const_string "ignore")))])
4398 [(set (match_operand:DI 0 "register_operand" "")
4399 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4400 "TARGET_SHMEDIA && reload_completed"
4401 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4402 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4405 if (GET_CODE (operands[1]) == TRUNCATE)
4406 operands[1] = XEXP (operands[1], 0);
4409 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4410 ;; reload the entire truncate expression.
4411 (define_insn_and_split "*loaddi_trunc"
4412 [(set (match_operand 0 "any_register_operand" "=r")
4413 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4414 "TARGET_SHMEDIA && reload_completed"
4416 "TARGET_SHMEDIA && reload_completed"
4417 [(set (match_dup 0) (match_dup 1))]
4418 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4420 (define_insn "zero_extendqidi2"
4421 [(set (match_operand:DI 0 "register_operand" "=r,r")
4422 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4427 [(set_attr "type" "arith_media,load_media")
4428 (set (attr "highpart")
4429 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4430 (const_string "user")]
4431 (const_string "ignore")))])
4433 (define_expand "zero_extendhisi2"
4434 [(set (match_operand:SI 0 "arith_reg_operand" "")
4435 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4439 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4440 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4443 (define_insn "*zero_extendhisi2_compact"
4444 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4445 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4448 [(set_attr "type" "arith")])
4450 (define_insn "*zero_extendhisi2_media"
4451 [(set (match_operand:SI 0 "register_operand" "=r,r")
4452 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4457 [(set_attr "type" "arith_media,load_media")
4458 (set (attr "highpart")
4459 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4460 (const_string "user")]
4461 (const_string "ignore")))])
4464 [(set (match_operand:SI 0 "register_operand" "")
4465 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4466 "TARGET_SHMEDIA && reload_completed"
4467 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4468 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4471 rtx op1 = operands[1];
4473 if (GET_CODE (op1) == TRUNCATE)
4474 op1 = XEXP (op1, 0);
4476 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4477 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4480 (define_expand "zero_extendqisi2"
4481 [(set (match_operand:SI 0 "arith_reg_operand" "")
4482 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4486 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4487 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4490 (define_insn "*zero_extendqisi2_compact"
4491 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4492 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4495 [(set_attr "type" "arith")])
4497 (define_insn "*zero_extendqisi2_media"
4498 [(set (match_operand:SI 0 "register_operand" "=r,r")
4499 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4504 [(set_attr "type" "arith_media,load_media")
4505 (set (attr "highpart")
4506 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4507 (const_string "user")]
4508 (const_string "ignore")))])
4510 (define_insn "zero_extendqihi2"
4511 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4512 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4515 [(set_attr "type" "arith")])
4517 ;; -------------------------------------------------------------------------
4518 ;; Sign extension instructions
4519 ;; -------------------------------------------------------------------------
4521 ;; ??? This should be a define expand.
4522 ;; ??? Or perhaps it should be dropped?
4524 ;; convert_move generates good code for SH[1-4].
4525 (define_insn "extendsidi2"
4526 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4527 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4533 [(set_attr "type" "arith_media,load_media,fpconv_media")
4534 (set (attr "highpart")
4535 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4536 (const_string "user")]
4537 (const_string "extend")))])
4539 (define_insn "extendhidi2"
4540 [(set (match_operand:DI 0 "register_operand" "=r,r")
4541 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4546 [(set_attr "type" "*,load_media")
4547 (set (attr "highpart")
4548 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4549 (const_string "user")]
4550 (const_string "ignore")))])
4553 [(set (match_operand:DI 0 "register_operand" "")
4554 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4555 "TARGET_SHMEDIA && reload_completed"
4556 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4557 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4560 if (GET_CODE (operands[1]) == TRUNCATE)
4561 operands[1] = XEXP (operands[1], 0);
4564 (define_insn "extendqidi2"
4565 [(set (match_operand:DI 0 "register_operand" "=r,r")
4566 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4571 [(set_attr "type" "*,load_media")
4572 (set (attr "highpart")
4573 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4574 (const_string "user")]
4575 (const_string "ignore")))])
4578 [(set (match_operand:DI 0 "register_operand" "")
4579 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4580 "TARGET_SHMEDIA && reload_completed"
4581 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4582 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4585 if (GET_CODE (operands[1]) == TRUNCATE)
4586 operands[1] = XEXP (operands[1], 0);
4589 (define_expand "extendhisi2"
4590 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4591 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4595 (define_insn "*extendhisi2_compact"
4596 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4597 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4602 [(set_attr "type" "arith,load")])
4604 (define_insn "*extendhisi2_media"
4605 [(set (match_operand:SI 0 "register_operand" "=r,r")
4606 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4611 [(set_attr "type" "arith_media,load_media")
4612 (set (attr "highpart")
4613 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4614 (const_string "user")]
4615 (const_string "ignore")))])
4618 [(set (match_operand:SI 0 "register_operand" "")
4619 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4620 "TARGET_SHMEDIA && reload_completed"
4621 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4622 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4625 rtx op1 = operands[1];
4626 if (GET_CODE (op1) == TRUNCATE)
4627 op1 = XEXP (op1, 0);
4629 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4630 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4633 (define_expand "extendqisi2"
4634 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4635 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4639 (define_insn "*extendqisi2_compact"
4640 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4641 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4646 [(set_attr "type" "arith,load")])
4648 (define_insn "*extendqisi2_media"
4649 [(set (match_operand:SI 0 "register_operand" "=r,r")
4650 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4655 [(set_attr "type" "arith_media,load_media")
4656 (set (attr "highpart")
4657 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4658 (const_string "user")]
4659 (const_string "ignore")))])
4662 [(set (match_operand:SI 0 "register_operand" "")
4663 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4664 "TARGET_SHMEDIA && reload_completed"
4665 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4666 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4669 rtx op1 = operands[1];
4670 if (GET_CODE (op1) == TRUNCATE)
4671 op1 = XEXP (op1, 0);
4673 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4674 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4677 (define_insn "extendqihi2"
4678 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4679 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4684 [(set_attr "type" "arith,load")])
4686 /* It would seem useful to combine the truncXi patterns into the movXi
4687 patterns, but unary operators are ignored when matching constraints,
4688 so we need separate patterns. */
4689 (define_insn "truncdisi2"
4690 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4691 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4700 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4701 (set (attr "highpart")
4702 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4703 (const_string "user")]
4704 (const_string "extend")))])
4706 (define_insn "truncdihi2"
4707 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4708 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4711 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4713 [(set_attr "type" "arith_media,store_media")
4714 (set_attr "length" "8,4")
4715 (set (attr "highpart")
4716 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4717 (const_string "user")]
4718 (const_string "extend")))])
4720 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4721 ; Because we use zero extension, we can't provide signed QImode compares
4722 ; using a simple compare or conditional banch insn.
4723 (define_insn "truncdiqi2"
4724 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4725 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4730 [(set_attr "type" "arith_media,store")
4731 (set (attr "highpart")
4732 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4733 (const_string "user")]
4734 (const_string "extend")))])
4735 ;; -------------------------------------------------------------------------
4736 ;; Move instructions
4737 ;; -------------------------------------------------------------------------
4739 ;; define push and pop so it is easy for sh.c
4740 ;; We can't use push and pop on SHcompact because the stack must always
4741 ;; be 8-byte aligned.
4743 (define_expand "push"
4744 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4745 (match_operand:SI 0 "register_operand" "r,l,x"))]
4746 "TARGET_SH1 && ! TARGET_SH5"
4749 (define_expand "pop"
4750 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4751 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4752 "TARGET_SH1 && ! TARGET_SH5"
4755 (define_expand "push_e"
4756 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4757 (match_operand:SF 0 "" ""))
4758 (use (reg:PSI FPSCR_REG))
4759 (clobber (scratch:SI))])]
4760 "TARGET_SH1 && ! TARGET_SH5"
4763 (define_insn "push_fpul"
4764 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4765 "TARGET_SH2E && ! TARGET_SH5"
4767 [(set_attr "type" "store")
4768 (set_attr "late_fp_use" "yes")
4769 (set_attr "hit_stack" "yes")])
4771 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4773 (define_expand "push_4"
4774 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4775 (match_operand:DF 0 "" ""))
4776 (use (reg:PSI FPSCR_REG))
4777 (clobber (scratch:SI))])]
4778 "TARGET_SH1 && ! TARGET_SH5"
4781 (define_expand "pop_e"
4782 [(parallel [(set (match_operand:SF 0 "" "")
4783 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4784 (use (reg:PSI FPSCR_REG))
4785 (clobber (scratch:SI))])]
4786 "TARGET_SH1 && ! TARGET_SH5"
4789 (define_insn "pop_fpul"
4790 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4791 "TARGET_SH2E && ! TARGET_SH5"
4793 [(set_attr "type" "load")
4794 (set_attr "hit_stack" "yes")])
4796 (define_expand "pop_4"
4797 [(parallel [(set (match_operand:DF 0 "" "")
4798 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4799 (use (reg:PSI FPSCR_REG))
4800 (clobber (scratch:SI))])]
4801 "TARGET_SH1 && ! TARGET_SH5"
4804 (define_expand "push_fpscr"
4809 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4810 gen_rtx_PRE_DEC (Pmode,
4811 stack_pointer_rtx)),
4813 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4817 (define_expand "pop_fpscr"
4822 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4823 gen_frame_mem (PSImode,
4824 gen_rtx_POST_INC (Pmode,
4825 stack_pointer_rtx))));
4826 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4830 ;; These two patterns can happen as the result of optimization, when
4831 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4832 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4835 [(set (reg:SI T_REG) (const_int 0))]
4840 [(set (reg:SI T_REG) (const_int 1))]
4844 ;; t/r must come after r/r, lest reload will try to reload stuff like
4845 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4846 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4847 (define_insn "movsi_i"
4848 [(set (match_operand:SI 0 "general_movdst_operand"
4849 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4850 (match_operand:SI 1 "general_movsrc_operand"
4851 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4855 && (register_operand (operands[0], SImode)
4856 || register_operand (operands[1], SImode))"
4873 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4874 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4876 ;; t/r must come after r/r, lest reload will try to reload stuff like
4877 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4878 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4879 ;; will require a reload.
4880 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4881 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4882 (define_insn "movsi_ie"
4883 [(set (match_operand:SI 0 "general_movdst_operand"
4884 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4885 (match_operand:SI 1 "general_movsrc_operand"
4886 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4887 "(TARGET_SH2E || TARGET_SH2A)
4888 && (register_operand (operands[0], SImode)
4889 || register_operand (operands[1], SImode))"
4914 ! move optimized away"
4915 [(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")
4916 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4917 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4919 (define_insn "movsi_i_lowpart"
4920 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4921 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4923 && (register_operand (operands[0], SImode)
4924 || register_operand (operands[1], SImode))"
4934 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4936 (define_insn_and_split "load_ra"
4937 [(set (match_operand:SI 0 "general_movdst_operand" "")
4938 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4941 "&& ! currently_expanding_to_rtl"
4942 [(set (match_dup 0) (match_dup 1))]
4945 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4946 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4949 ;; The '?'s in the following constraints may not reflect the time taken
4950 ;; to perform the move. They are there to discourage the use of floating-
4951 ;; point registers for storing integer values.
4952 (define_insn "*movsi_media"
4953 [(set (match_operand:SI 0 "general_movdst_operand"
4954 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4955 (match_operand:SI 1 "general_movsrc_operand"
4956 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4958 && (register_operand (operands[0], SImode)
4959 || sh_register_operand (operands[1], SImode)
4960 || GET_CODE (operands[1]) == TRUNCATE)"
4975 [(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")
4976 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4977 (set (attr "highpart")
4978 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4979 (const_string "user")]
4980 (const_string "ignore")))])
4982 (define_insn "*movsi_media_nofpu"
4983 [(set (match_operand:SI 0 "general_movdst_operand"
4984 "=r,r,r,r,m,*b,r,*b")
4985 (match_operand:SI 1 "general_movsrc_operand"
4986 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
4988 && (register_operand (operands[0], SImode)
4989 || sh_register_operand (operands[1], SImode)
4990 || GET_CODE (operands[1]) == TRUNCATE)"
5000 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5001 (set_attr "length" "4,4,8,4,4,4,4,12")
5002 (set (attr "highpart")
5003 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5004 (const_string "user")]
5005 (const_string "ignore")))])
5007 (define_expand "movsi_const"
5008 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5009 (const:SI (sign_extend:SI
5012 (match_operand:DI 1 "immediate_operand" "s")
5015 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5018 (truncate:HI (match_dup 1))))))]
5019 "TARGET_SHMEDIA && reload_completed
5020 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5023 if (GET_CODE (operands[1]) == LABEL_REF
5024 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5025 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5026 else if (GOTOFF_P (operands[1]))
5028 rtx unspec = XEXP (operands[1], 0);
5030 if (! UNSPEC_GOTOFF_P (unspec))
5032 unspec = XEXP (unspec, 0);
5033 if (! UNSPEC_GOTOFF_P (unspec))
5036 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5037 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5038 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5042 (define_expand "movsi_const_16bit"
5043 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5044 (const:SI (sign_extend:SI
5046 (match_operand:DI 1 "immediate_operand" "s")))))]
5047 "TARGET_SHMEDIA && flag_pic && reload_completed
5048 && GET_CODE (operands[1]) == SYMBOL_REF"
5052 [(set (match_operand:SI 0 "arith_reg_dest" "")
5053 (match_operand:SI 1 "immediate_operand" ""))]
5054 "TARGET_SHMEDIA && reload_completed
5055 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5059 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5061 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5068 [(set (match_operand:SI 0 "register_operand" "")
5069 (match_operand:SI 1 "immediate_operand" ""))]
5070 "TARGET_SHMEDIA && reload_completed
5071 && ((GET_CODE (operands[1]) == CONST_INT
5072 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5073 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5074 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5076 (define_expand "movsi"
5077 [(set (match_operand:SI 0 "general_movdst_operand" "")
5078 (match_operand:SI 1 "general_movsrc_operand" ""))]
5080 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5082 (define_expand "ic_invalidate_line"
5083 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5084 (match_dup 1)] UNSPEC_ICACHE)
5085 (clobber (scratch:SI))])]
5086 "TARGET_HARD_SH4 || TARGET_SH5"
5091 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5094 else if (TARGET_SHCOMPACT)
5096 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5097 operands[1] = force_reg (Pmode, operands[1]);
5098 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5101 else if (TARGET_SH4A_ARCH)
5103 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5106 operands[0] = force_reg (Pmode, operands[0]);
5107 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5111 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5112 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5113 ;; the requirement *1*00 for associative address writes. The alignment of
5114 ;; %0 implies that its least significant bit is cleared,
5115 ;; thus we clear the V bit of a matching entry if there is one.
5116 (define_insn "ic_invalidate_line_i"
5117 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5118 (match_operand:SI 1 "register_operand" "r")]
5120 (clobber (match_scratch:SI 2 "=&r"))]
5122 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5123 [(set_attr "length" "8")
5124 (set_attr "type" "cwb")])
5126 (define_insn "ic_invalidate_line_sh4a"
5127 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5130 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5131 [(set_attr "length" "16")
5132 (set_attr "type" "cwb")])
5134 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5135 ;; an add in the code that calculates the address.
5136 (define_insn "ic_invalidate_line_media"
5137 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5140 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5141 [(set_attr "length" "16")
5142 (set_attr "type" "invalidate_line_media")])
5144 (define_insn "ic_invalidate_line_compact"
5145 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5146 (match_operand:SI 1 "register_operand" "r")]
5148 (clobber (reg:SI PR_REG))]
5151 [(set_attr "type" "sfunc")
5152 (set_attr "needs_delay_slot" "yes")])
5154 (define_expand "initialize_trampoline"
5155 [(match_operand:SI 0 "" "")
5156 (match_operand:SI 1 "" "")
5157 (match_operand:SI 2 "" "")]
5163 tramp = force_reg (Pmode, operands[0]);
5164 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5166 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5167 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5169 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5173 (define_insn "initialize_trampoline_compact"
5174 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5175 (match_operand:SI 1 "register_operand" "r")
5176 (reg:SI R2_REG) (reg:SI R3_REG)]
5179 (clobber (reg:SI PR_REG))]
5182 [(set_attr "type" "sfunc")
5183 (set_attr "needs_delay_slot" "yes")])
5185 (define_insn "movqi_i"
5186 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5187 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
5189 && (arith_reg_operand (operands[0], QImode)
5190 || arith_reg_operand (operands[1], QImode))"
5198 [(set_attr "type" "move,load,store,move,move,move")])
5200 (define_insn "*movqi_media"
5201 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5202 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5204 && (arith_reg_operand (operands[0], QImode)
5205 || extend_reg_or_0_operand (operands[1], QImode))"
5211 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5212 (set (attr "highpart")
5213 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5214 (const_string "user")]
5215 (const_string "ignore")))])
5217 (define_expand "movqi"
5218 [(set (match_operand:QI 0 "general_operand" "")
5219 (match_operand:QI 1 "general_operand" ""))]
5221 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5223 (define_expand "reload_inqi"
5224 [(set (match_operand:SI 2 "" "=&r")
5225 (match_operand:QI 1 "inqhi_operand" ""))
5226 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5227 (truncate:QI (match_dup 3)))]
5231 rtx inner = XEXP (operands[1], 0);
5232 int regno = REGNO (inner);
5234 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5235 operands[1] = gen_rtx_REG (SImode, regno);
5236 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5239 /* When storing r0, we have to avoid reg+reg addressing. */
5240 (define_insn "movhi_i"
5241 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5242 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5244 && (arith_reg_operand (operands[0], HImode)
5245 || arith_reg_operand (operands[1], HImode))
5246 && (GET_CODE (operands[0]) != MEM
5247 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5248 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5249 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5259 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5261 (define_insn "*movhi_media"
5262 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5263 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5265 && (arith_reg_operand (operands[0], HImode)
5266 || arith_reg_or_0_operand (operands[1], HImode))"
5273 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5274 (set (attr "highpart")
5275 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5276 (const_string "user")]
5277 (const_string "ignore")))])
5280 [(set (match_operand:HI 0 "register_operand" "")
5281 (match_operand:HI 1 "immediate_operand" ""))]
5282 "TARGET_SHMEDIA && reload_completed
5283 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5284 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5286 (define_expand "movhi"
5287 [(set (match_operand:HI 0 "general_movdst_operand" "")
5288 (match_operand:HI 1 "general_movsrc_operand" ""))]
5290 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5292 (define_expand "reload_inhi"
5293 [(set (match_operand:SI 2 "" "=&r")
5294 (match_operand:HI 1 "inqhi_operand" ""))
5295 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5296 (truncate:HI (match_dup 3)))]
5300 rtx inner = XEXP (operands[1], 0);
5301 int regno = REGNO (inner);
5303 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5304 operands[1] = gen_rtx_REG (SImode, regno);
5305 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5308 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5309 ;; compiled with -m2 -ml -O3 -funroll-loops
5310 (define_insn "*movdi_i"
5311 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5312 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5314 && (arith_reg_operand (operands[0], DImode)
5315 || arith_reg_operand (operands[1], DImode))"
5316 "* return output_movedouble (insn, operands, DImode);"
5317 [(set_attr "length" "4")
5318 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5320 ;; If the output is a register and the input is memory or a register, we have
5321 ;; to be careful and see which word needs to be loaded first.
5324 [(set (match_operand:DI 0 "general_movdst_operand" "")
5325 (match_operand:DI 1 "general_movsrc_operand" ""))]
5326 "TARGET_SH1 && reload_completed"
5327 [(set (match_dup 2) (match_dup 3))
5328 (set (match_dup 4) (match_dup 5))]
5333 if ((GET_CODE (operands[0]) == MEM
5334 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5335 || (GET_CODE (operands[1]) == MEM
5336 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5339 switch (GET_CODE (operands[0]))
5342 regno = REGNO (operands[0]);
5345 regno = subreg_regno (operands[0]);
5355 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5357 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5358 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5359 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5360 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5364 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5365 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5366 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5367 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5370 if (operands[2] == 0 || operands[3] == 0
5371 || operands[4] == 0 || operands[5] == 0)
5375 ;; The '?'s in the following constraints may not reflect the time taken
5376 ;; to perform the move. They are there to discourage the use of floating-
5377 ;; point registers for storing integer values.
5378 (define_insn "*movdi_media"
5379 [(set (match_operand:DI 0 "general_movdst_operand"
5380 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5381 (match_operand:DI 1 "general_movsrc_operand"
5382 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5384 && (register_operand (operands[0], DImode)
5385 || sh_register_operand (operands[1], DImode))"
5400 [(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")
5401 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5403 (define_insn "*movdi_media_nofpu"
5404 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5405 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5407 && (register_operand (operands[0], DImode)
5408 || sh_register_operand (operands[1], DImode))"
5418 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5419 (set_attr "length" "4,4,16,4,4,4,4,*")])
5421 (define_insn "*movdi_media_I16"
5422 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5423 (match_operand:DI 1 "const_int_operand" "I16"))]
5424 "TARGET_SHMEDIA && reload_completed"
5426 [(set_attr "type" "arith_media")
5427 (set_attr "length" "4")])
5430 [(set (match_operand:DI 0 "arith_reg_dest" "")
5431 (match_operand:DI 1 "immediate_operand" ""))]
5432 "TARGET_SHMEDIA && reload_completed
5433 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5434 [(set (match_dup 0) (match_dup 1))]
5439 if (TARGET_SHMEDIA64)
5440 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5442 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5444 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5450 (define_expand "movdi_const"
5451 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5452 (const:DI (sign_extend:DI
5455 (match_operand:DI 1 "immediate_operand" "s")
5458 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5464 (const_int 32)))))))
5466 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5472 (const_int 16)))))))
5474 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5479 "TARGET_SHMEDIA64 && reload_completed
5480 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5483 sh_mark_label (operands[1], 4);
5486 (define_expand "movdi_const_32bit"
5487 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5488 (const:DI (sign_extend:DI
5491 (match_operand:DI 1 "immediate_operand" "s")
5494 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5499 "TARGET_SHMEDIA32 && reload_completed
5500 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5503 sh_mark_label (operands[1], 2);
5506 (define_expand "movdi_const_16bit"
5507 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5508 (const:DI (sign_extend:DI
5510 (match_operand:DI 1 "immediate_operand" "s")))))]
5511 "TARGET_SHMEDIA && flag_pic && reload_completed
5512 && GET_CODE (operands[1]) == SYMBOL_REF"
5516 [(set (match_operand:DI 0 "ext_dest_operand" "")
5517 (match_operand:DI 1 "immediate_operand" ""))]
5518 "TARGET_SHMEDIA && reload_completed
5519 && GET_CODE (operands[1]) == CONST_INT
5520 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5521 [(set (match_dup 0) (match_dup 2))
5525 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5526 unsigned HOST_WIDE_INT low = val;
5527 unsigned HOST_WIDE_INT high = val;
5528 unsigned HOST_WIDE_INT sign;
5529 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5531 /* Zero-extend the 16 least-significant bits. */
5534 /* Arithmetic shift right the word by 16 bits. */
5536 if (GET_CODE (operands[0]) == SUBREG
5537 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5546 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5552 /* If we can't generate the constant with a two-insn movi / shori
5553 sequence, try some other strategies. */
5554 if (! CONST_OK_FOR_I16 (high))
5556 /* Try constant load / left shift. We know VAL != 0. */
5557 val2 = val ^ (val-1);
5560 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5562 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5563 || (! CONST_OK_FOR_I16 (high >> 16)
5564 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5566 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5567 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5568 GEN_INT (trailing_zeroes));
5572 /* Try constant load / right shift. */
5573 val2 = (val >> 15) + 1;
5574 if (val2 == (val2 & -val2))
5576 int shift = 49 - exact_log2 (val2);
5578 val2 = trunc_int_for_mode (val << shift, DImode);
5579 if (CONST_OK_FOR_I16 (val2))
5581 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5587 val2 = val & 0xffff;
5588 if ((val >> 16 & 0xffff) == val2
5589 && (val >> 32 & 0xffff) == val2
5590 && (val >> 48 & 0xffff) == val2)
5592 val2 = (HOST_WIDE_INT) val >> 48;
5593 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5594 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5597 /* Try movi / mshflo.l */
5598 val2 = (HOST_WIDE_INT) val >> 32;
5599 if (val2 == ((unsigned HOST_WIDE_INT)
5600 trunc_int_for_mode (val, SImode)))
5602 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5606 /* Try movi / mshflo.l w/ r63. */
5607 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5608 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5610 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5616 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5619 operands[2] = GEN_INT (val2);
5623 [(set (match_operand:DI 0 "ext_dest_operand" "")
5624 (match_operand:DI 1 "immediate_operand" ""))]
5625 "TARGET_SHMEDIA && reload_completed
5626 && GET_CODE (operands[1]) == CONST_DOUBLE"
5627 [(set (match_dup 0) (match_dup 2))
5629 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5632 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5633 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5634 unsigned HOST_WIDE_INT val = low;
5635 unsigned HOST_WIDE_INT sign;
5637 /* Zero-extend the 16 least-significant bits. */
5639 operands[1] = GEN_INT (val);
5641 /* Arithmetic shift right the double-word by 16 bits. */
5643 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5646 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5650 /* This will only be true if high is a sign-extension of low, i.e.,
5651 it must be either 0 or (unsigned)-1, and be zero iff the
5652 most-significant bit of low is set. */
5653 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5654 operands[2] = GEN_INT (low);
5656 operands[2] = immed_double_const (low, high, DImode);
5659 (define_insn "shori_media"
5660 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5661 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5663 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5664 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5668 [(set_attr "type" "arith_media,*")])
5670 (define_insn "*shori_media_si"
5671 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5672 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5674 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5678 (define_expand "movdi"
5679 [(set (match_operand:DI 0 "general_movdst_operand" "")
5680 (match_operand:DI 1 "general_movsrc_operand" ""))]
5682 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5684 (define_insn "movdf_media"
5685 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5686 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5688 && (register_operand (operands[0], DFmode)
5689 || sh_register_operand (operands[1], DFmode))"
5700 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5702 (define_insn "movdf_media_nofpu"
5703 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5704 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5706 && (register_operand (operands[0], DFmode)
5707 || sh_register_operand (operands[1], DFmode))"
5713 [(set_attr "type" "arith_media,*,load_media,store_media")])
5716 [(set (match_operand:DF 0 "arith_reg_dest" "")
5717 (match_operand:DF 1 "immediate_operand" ""))]
5718 "TARGET_SHMEDIA && reload_completed"
5719 [(set (match_dup 3) (match_dup 2))]
5722 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5724 REAL_VALUE_TYPE value;
5726 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5727 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5729 if (HOST_BITS_PER_WIDE_INT >= 64)
5730 operands[2] = immed_double_const ((unsigned long) values[endian]
5731 | ((HOST_WIDE_INT) values[1 - endian]
5735 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5736 operands[2] = immed_double_const (values[endian], values[1 - endian],
5740 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5743 ;; ??? This should be a define expand.
5745 (define_insn "movdf_k"
5746 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5747 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5749 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5750 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5751 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5752 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5753 && (arith_reg_operand (operands[0], DFmode)
5754 || arith_reg_operand (operands[1], DFmode))"
5755 "* return output_movedouble (insn, operands, DFmode);"
5756 [(set_attr "length" "4")
5757 (set_attr "type" "move,pcload,load,store")])
5759 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5760 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5761 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5762 ;; the d/m/c/X alternative, which is split later into single-precision
5763 ;; instructions. And when not optimizing, no splits are done before fixing
5764 ;; up pcloads, so we need usable length information for that.
5765 (define_insn "movdf_i4"
5766 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5767 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5768 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5769 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5770 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5771 && (arith_reg_operand (operands[0], DFmode)
5772 || arith_reg_operand (operands[1], DFmode))"
5784 [(set_attr_alternative "length"
5785 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5787 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5788 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5789 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5791 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5792 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5793 ;; increment or decrement r15 explicitly.
5795 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5796 (const_int 10) (const_int 8))
5798 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5799 (const_int 10) (const_int 8))])
5800 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5801 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5802 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5803 (const_string "double")
5804 (const_string "none")))])
5806 ;; Moving DFmode between fp/general registers through memory
5807 ;; (the top of the stack) is faster than moving through fpul even for
5808 ;; little endian. Because the type of an instruction is important for its
5809 ;; scheduling, it is beneficial to split these operations, rather than
5810 ;; emitting them in one single chunk, even if this will expose a stack
5811 ;; use that will prevent scheduling of other stack accesses beyond this
5814 [(set (match_operand:DF 0 "register_operand" "")
5815 (match_operand:DF 1 "register_operand" ""))
5816 (use (match_operand:PSI 2 "fpscr_operand" ""))
5817 (clobber (match_scratch:SI 3 "=X"))]
5818 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5819 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5825 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5827 emit_move_insn (stack_pointer_rtx,
5828 plus_constant (stack_pointer_rtx, -8));
5829 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5832 tos = gen_tmp_stack_mem (DFmode,
5833 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5834 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5835 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5836 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5837 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5838 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5840 tos = gen_tmp_stack_mem (DFmode,
5841 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5842 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5843 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5844 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5846 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5850 ;; local-alloc sometimes allocates scratch registers even when not required,
5851 ;; so we must be prepared to handle these.
5853 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5855 [(set (match_operand:DF 0 "general_movdst_operand" "")
5856 (match_operand:DF 1 "general_movsrc_operand" ""))
5857 (use (match_operand:PSI 2 "fpscr_operand" ""))
5858 (clobber (match_scratch:SI 3 ""))]
5859 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5861 && true_regnum (operands[0]) < 16
5862 && true_regnum (operands[1]) < 16"
5863 [(set (match_dup 0) (match_dup 1))]
5866 /* If this was a reg <-> mem operation with base + index reg addressing,
5867 we have to handle this in a special way. */
5868 rtx mem = operands[0];
5870 if (! memory_operand (mem, DFmode))
5875 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5876 mem = SUBREG_REG (mem);
5877 if (GET_CODE (mem) == MEM)
5879 rtx addr = XEXP (mem, 0);
5880 if (GET_CODE (addr) == PLUS
5881 && GET_CODE (XEXP (addr, 0)) == REG
5882 && GET_CODE (XEXP (addr, 1)) == REG)
5885 rtx reg0 = gen_rtx_REG (Pmode, 0);
5886 rtx regop = operands[store_p], word0 ,word1;
5888 if (GET_CODE (regop) == SUBREG)
5889 alter_subreg (®op);
5890 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5894 mem = copy_rtx (mem);
5895 PUT_MODE (mem, SImode);
5896 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5897 alter_subreg (&word0);
5898 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5899 alter_subreg (&word1);
5900 if (store_p || ! refers_to_regno_p (REGNO (word0),
5901 REGNO (word0) + 1, addr, 0))
5904 ? gen_movsi_ie (mem, word0)
5905 : gen_movsi_ie (word0, mem));
5906 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5907 mem = copy_rtx (mem);
5909 ? gen_movsi_ie (mem, word1)
5910 : gen_movsi_ie (word1, mem));
5911 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5915 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5916 emit_insn (gen_movsi_ie (word1, mem));
5917 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5918 mem = copy_rtx (mem);
5919 emit_insn (gen_movsi_ie (word0, mem));
5926 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5928 [(set (match_operand:DF 0 "register_operand" "")
5929 (match_operand:DF 1 "memory_operand" ""))
5930 (use (match_operand:PSI 2 "fpscr_operand" ""))
5931 (clobber (reg:SI R0_REG))]
5932 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5933 [(parallel [(set (match_dup 0) (match_dup 1))
5935 (clobber (scratch:SI))])]
5938 (define_expand "reload_indf__frn"
5939 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5940 (match_operand:DF 1 "immediate_operand" "FQ"))
5941 (use (reg:PSI FPSCR_REG))
5942 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5946 (define_expand "reload_outdf__RnFRm"
5947 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5948 (match_operand:DF 1 "register_operand" "af,r"))
5949 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5953 ;; Simplify no-op moves.
5955 [(set (match_operand:SF 0 "register_operand" "")
5956 (match_operand:SF 1 "register_operand" ""))
5957 (use (match_operand:PSI 2 "fpscr_operand" ""))
5958 (clobber (match_scratch:SI 3 ""))]
5959 "TARGET_SH2E && reload_completed
5960 && true_regnum (operands[0]) == true_regnum (operands[1])"
5961 [(set (match_dup 0) (match_dup 0))]
5964 ;; fmovd substitute post-reload splits
5966 [(set (match_operand:DF 0 "register_operand" "")
5967 (match_operand:DF 1 "register_operand" ""))
5968 (use (match_operand:PSI 2 "fpscr_operand" ""))
5969 (clobber (match_scratch:SI 3 ""))]
5970 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5971 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5972 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5976 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5977 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5978 gen_rtx_REG (SFmode, src), operands[2]));
5979 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5980 gen_rtx_REG (SFmode, src + 1), operands[2]));
5985 [(set (match_operand:DF 0 "register_operand" "")
5986 (mem:DF (match_operand:SI 1 "register_operand" "")))
5987 (use (match_operand:PSI 2 "fpscr_operand" ""))
5988 (clobber (match_scratch:SI 3 ""))]
5989 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5990 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5991 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5995 int regno = true_regnum (operands[0]);
5997 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5999 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6000 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6001 regno + !! TARGET_LITTLE_ENDIAN),
6002 mem2, operands[2]));
6003 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6004 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6005 regno + ! TARGET_LITTLE_ENDIAN),
6006 change_address (mem, SFmode, NULL_RTX),
6012 [(set (match_operand:DF 0 "register_operand" "")
6013 (match_operand:DF 1 "memory_operand" ""))
6014 (use (match_operand:PSI 2 "fpscr_operand" ""))
6015 (clobber (match_scratch:SI 3 ""))]
6016 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6017 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6021 int regno = true_regnum (operands[0]);
6022 rtx addr, insn, adjust = NULL_RTX;
6023 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6024 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6025 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6027 operands[1] = copy_rtx (mem2);
6028 addr = XEXP (mem2, 0);
6029 if (GET_CODE (addr) != POST_INC)
6031 /* If we have to modify the stack pointer, the value that we have
6032 read with post-increment might be modified by an interrupt,
6033 so write it back. */
6034 if (REGNO (addr) == STACK_POINTER_REGNUM)
6035 adjust = gen_push_e (reg0);
6037 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6038 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6040 addr = XEXP (addr, 0);
6041 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6042 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6043 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6047 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6052 [(set (match_operand:DF 0 "memory_operand" "")
6053 (match_operand:DF 1 "register_operand" ""))
6054 (use (match_operand:PSI 2 "fpscr_operand" ""))
6055 (clobber (match_scratch:SI 3 ""))]
6056 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6057 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6061 int regno = true_regnum (operands[1]);
6062 rtx insn, addr, adjust = NULL_RTX;
6064 operands[0] = copy_rtx (operands[0]);
6065 PUT_MODE (operands[0], SFmode);
6066 insn = emit_insn (gen_movsf_ie (operands[0],
6067 gen_rtx_REG (SFmode,
6068 regno + ! TARGET_LITTLE_ENDIAN),
6070 operands[0] = copy_rtx (operands[0]);
6071 addr = XEXP (operands[0], 0);
6072 if (GET_CODE (addr) != PRE_DEC)
6074 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6075 emit_insn_before (adjust, insn);
6076 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6078 addr = XEXP (addr, 0);
6080 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6081 insn = emit_insn (gen_movsf_ie (operands[0],
6082 gen_rtx_REG (SFmode,
6083 regno + !! TARGET_LITTLE_ENDIAN),
6085 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6089 ;; If the output is a register and the input is memory or a register, we have
6090 ;; to be careful and see which word needs to be loaded first.
6093 [(set (match_operand:DF 0 "general_movdst_operand" "")
6094 (match_operand:DF 1 "general_movsrc_operand" ""))]
6095 "TARGET_SH1 && reload_completed"
6096 [(set (match_dup 2) (match_dup 3))
6097 (set (match_dup 4) (match_dup 5))]
6102 if ((GET_CODE (operands[0]) == MEM
6103 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6104 || (GET_CODE (operands[1]) == MEM
6105 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6108 switch (GET_CODE (operands[0]))
6111 regno = REGNO (operands[0]);
6114 regno = subreg_regno (operands[0]);
6124 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6126 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6127 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6128 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6129 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6133 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6134 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6135 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6136 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6139 if (operands[2] == 0 || operands[3] == 0
6140 || operands[4] == 0 || operands[5] == 0)
6144 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6145 ;; used only once, let combine add in the index again.
6148 [(set (match_operand:SI 0 "register_operand" "")
6149 (match_operand:SI 1 "" ""))
6150 (clobber (match_operand 2 "register_operand" ""))]
6151 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6152 && ALLOW_INDEXED_ADDRESS"
6153 [(use (reg:SI R0_REG))]
6156 rtx addr, reg, const_int;
6158 if (GET_CODE (operands[1]) != MEM)
6160 addr = XEXP (operands[1], 0);
6161 if (GET_CODE (addr) != PLUS)
6163 reg = XEXP (addr, 0);
6164 const_int = XEXP (addr, 1);
6165 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6166 && GET_CODE (const_int) == CONST_INT))
6168 emit_move_insn (operands[2], const_int);
6169 emit_move_insn (operands[0],
6170 change_address (operands[1], VOIDmode,
6171 gen_rtx_PLUS (SImode, reg, operands[2])));
6176 [(set (match_operand:SI 1 "" "")
6177 (match_operand:SI 0 "register_operand" ""))
6178 (clobber (match_operand 2 "register_operand" ""))]
6179 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6180 && ALLOW_INDEXED_ADDRESS"
6181 [(use (reg:SI R0_REG))]
6184 rtx addr, reg, const_int;
6186 if (GET_CODE (operands[1]) != MEM)
6188 addr = XEXP (operands[1], 0);
6189 if (GET_CODE (addr) != PLUS)
6191 reg = XEXP (addr, 0);
6192 const_int = XEXP (addr, 1);
6193 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6194 && GET_CODE (const_int) == CONST_INT))
6196 emit_move_insn (operands[2], const_int);
6197 emit_move_insn (change_address (operands[1], VOIDmode,
6198 gen_rtx_PLUS (SImode, reg, operands[2])),
6203 (define_expand "movdf"
6204 [(set (match_operand:DF 0 "general_movdst_operand" "")
6205 (match_operand:DF 1 "general_movsrc_operand" ""))]
6209 if (prepare_move_operands (operands, DFmode)) DONE;
6212 if (TARGET_SHMEDIA_FPU)
6213 emit_insn (gen_movdf_media (operands[0], operands[1]));
6215 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6218 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6220 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6225 ;;This is incompatible with the way gcc uses subregs.
6226 ;;(define_insn "movv2sf_i"
6227 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6228 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6229 ;; "TARGET_SHMEDIA_FPU
6230 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6231 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6235 ;; fst%M0.p %m0, %1"
6236 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6238 (define_insn_and_split "movv2sf_i"
6239 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6240 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6241 "TARGET_SHMEDIA_FPU"
6243 "TARGET_SHMEDIA_FPU && reload_completed"
6244 [(set (match_dup 0) (match_dup 1))]
6247 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6248 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6251 (define_expand "movv2sf"
6252 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6253 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6254 "TARGET_SHMEDIA_FPU"
6257 if (prepare_move_operands (operands, V2SFmode))
6261 (define_expand "addv2sf3"
6262 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6263 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6264 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6265 "TARGET_SHMEDIA_FPU"
6268 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6272 (define_expand "subv2sf3"
6273 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6274 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6275 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6276 "TARGET_SHMEDIA_FPU"
6279 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6283 (define_expand "mulv2sf3"
6284 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6285 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6286 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6287 "TARGET_SHMEDIA_FPU"
6290 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6294 (define_expand "divv2sf3"
6295 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6296 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6297 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6298 "TARGET_SHMEDIA_FPU"
6301 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6305 (define_insn_and_split "*movv4sf_i"
6306 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6307 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6308 "TARGET_SHMEDIA_FPU"
6310 "&& reload_completed"
6316 for (i = 0; i < 4/2; i++)
6320 if (GET_CODE (operands[0]) == MEM)
6321 x = adjust_address (operands[0], V2SFmode,
6322 i * GET_MODE_SIZE (V2SFmode));
6324 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6326 if (GET_CODE (operands[1]) == MEM)
6327 y = adjust_address (operands[1], V2SFmode,
6328 i * GET_MODE_SIZE (V2SFmode));
6330 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6332 emit_insn (gen_movv2sf_i (x, y));
6337 [(set_attr "length" "8")])
6339 (define_expand "movv4sf"
6340 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6341 (match_operand:V4SF 1 "general_operand" ""))]
6342 "TARGET_SHMEDIA_FPU"
6345 if (prepare_move_operands (operands, V4SFmode))
6349 (define_insn_and_split "*movv16sf_i"
6350 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6351 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6352 "TARGET_SHMEDIA_FPU"
6354 "&& reload_completed"
6360 for (i = 0; i < 16/2; i++)
6364 if (GET_CODE (operands[0]) == MEM)
6365 x = adjust_address (operands[0], V2SFmode,
6366 i * GET_MODE_SIZE (V2SFmode));
6369 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6373 if (GET_CODE (operands[1]) == MEM)
6374 y = adjust_address (operands[1], V2SFmode,
6375 i * GET_MODE_SIZE (V2SFmode));
6378 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6382 emit_insn (gen_movv2sf_i (x, y));
6387 [(set_attr "length" "32")])
6389 (define_expand "movv16sf"
6390 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6391 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6392 "TARGET_SHMEDIA_FPU"
6395 if (prepare_move_operands (operands, V16SFmode))
6399 (define_insn "movsf_media"
6400 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6401 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6403 && (register_operand (operands[0], SFmode)
6404 || sh_register_operand (operands[1], SFmode))"
6415 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6416 (set (attr "highpart")
6417 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6418 (const_string "user")]
6419 (const_string "ignore")))])
6421 (define_insn "movsf_media_nofpu"
6422 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6423 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6425 && (register_operand (operands[0], SFmode)
6426 || sh_register_operand (operands[1], SFmode))"
6432 [(set_attr "type" "arith_media,*,load_media,store_media")
6433 (set (attr "highpart")
6434 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6435 (const_string "user")]
6436 (const_string "ignore")))])
6439 [(set (match_operand:SF 0 "arith_reg_dest" "")
6440 (match_operand:SF 1 "immediate_operand" ""))]
6441 "TARGET_SHMEDIA && reload_completed
6442 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6443 [(set (match_dup 3) (match_dup 2))]
6447 REAL_VALUE_TYPE value;
6449 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6450 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6451 operands[2] = GEN_INT (values);
6453 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6456 (define_insn "movsf_i"
6457 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6458 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6461 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6462 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6463 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6464 && (arith_reg_operand (operands[0], SFmode)
6465 || arith_reg_operand (operands[1], SFmode))"
6474 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6476 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6477 ;; update_flow_info would not know where to put REG_EQUAL notes
6478 ;; when the destination changes mode.
6479 (define_insn "movsf_ie"
6480 [(set (match_operand:SF 0 "general_movdst_operand"
6481 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6482 (match_operand:SF 1 "general_movsrc_operand"
6483 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6484 (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"))
6485 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6488 && (arith_reg_operand (operands[0], SFmode)
6489 || arith_reg_operand (operands[1], SFmode)
6490 || arith_reg_operand (operands[3], SImode)
6491 || (fpul_operand (operands[0], SFmode)
6492 && memory_operand (operands[1], SFmode)
6493 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6494 || (fpul_operand (operands[1], SFmode)
6495 && memory_operand (operands[0], SFmode)
6496 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6516 ! move optimized away"
6517 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6518 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6519 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6520 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6521 (const_string "single")
6522 (const_string "none")))])
6525 [(set (match_operand:SF 0 "register_operand" "")
6526 (match_operand:SF 1 "register_operand" ""))
6527 (use (match_operand:PSI 2 "fpscr_operand" ""))
6528 (clobber (reg:SI FPUL_REG))]
6530 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6532 (clobber (scratch:SI))])
6533 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6535 (clobber (scratch:SI))])]
6538 (define_expand "movsf"
6539 [(set (match_operand:SF 0 "general_movdst_operand" "")
6540 (match_operand:SF 1 "general_movsrc_operand" ""))]
6544 if (prepare_move_operands (operands, SFmode))
6548 if (TARGET_SHMEDIA_FPU)
6549 emit_insn (gen_movsf_media (operands[0], operands[1]));
6551 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6556 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6561 (define_insn "mov_nop"
6562 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6565 [(set_attr "length" "0")
6566 (set_attr "type" "nil")])
6568 (define_expand "reload_insf__frn"
6569 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6570 (match_operand:SF 1 "immediate_operand" "FQ"))
6571 (use (reg:PSI FPSCR_REG))
6572 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6576 (define_expand "reload_insi__i_fpul"
6577 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6578 (match_operand:SI 1 "immediate_operand" "i"))
6579 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6583 (define_expand "ptabs"
6584 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6588 if (!TARGET_PT_FIXED)
6590 rtx eq = operands[1];
6592 /* ??? For canonical RTL we really should remove any CONST from EQ
6593 before wrapping it in the AND, and finally wrap the EQ into a
6594 const if is constant. However, for reload we must expose the
6595 input register or symbolic constant, and we can't have
6596 different insn structures outside of the operands for different
6597 alternatives of the same pattern. */
6598 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6601 = (gen_rtx_IF_THEN_ELSE
6604 gen_rtx_MEM (PDImode, operands[1]),
6605 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6606 PDImode, operands[1])));
6610 ;; expanded by ptabs expander.
6611 (define_insn "*extendsipdi_media"
6612 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6613 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6617 (mem:PDI (match_dup 1))
6618 (sign_extend:PDI (match_dup 1))))]
6619 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6623 [(set_attr "type" "ptabs_media,pt_media")
6624 (set_attr "length" "4,*")])
6626 (define_insn "*truncdipdi_media"
6627 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6628 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6632 (mem:PDI (match_dup 1))
6633 (truncate:PDI (match_dup 1))))]
6634 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6638 [(set_attr "type" "ptabs_media,pt_media")
6639 (set_attr "length" "4,*")])
6641 (define_insn "*movsi_y"
6642 [(set (match_operand:SI 0 "register_operand" "=y,y")
6643 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6644 (clobber (match_scratch:SI 2 "=&z,r"))]
6646 && (reload_in_progress || reload_completed)"
6648 [(set_attr "length" "4")
6649 (set_attr "type" "pcload,move")])
6652 [(set (match_operand:SI 0 "register_operand" "")
6653 (match_operand:SI 1 "immediate_operand" ""))
6654 (clobber (match_operand:SI 2 "register_operand" ""))]
6656 [(set (match_dup 2) (match_dup 1))
6657 (set (match_dup 0) (match_dup 2))]
6661 [(set (match_operand:SI 0 "register_operand" "")
6662 (match_operand:SI 1 "memory_operand" ""))
6663 (clobber (reg:SI R0_REG))]
6665 [(set (match_dup 0) (match_dup 1))]
6668 ;; ------------------------------------------------------------------------
6669 ;; Define the real conditional branch instructions.
6670 ;; ------------------------------------------------------------------------
6672 (define_insn "branch_true"
6673 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6674 (label_ref (match_operand 0 "" ""))
6677 "* return output_branch (1, insn, operands);"
6678 [(set_attr "type" "cbranch")])
6680 (define_insn "branch_false"
6681 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6682 (label_ref (match_operand 0 "" ""))
6685 "* return output_branch (0, insn, operands);"
6686 [(set_attr "type" "cbranch")])
6688 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6689 ;; which destination is too far away.
6690 ;; The const_int_operand is distinct for each branch target; it avoids
6691 ;; unwanted matches with redundant_insn.
6692 (define_insn "block_branch_redirect"
6693 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6696 [(set_attr "length" "0")])
6698 ;; This one has the additional purpose to record a possible scratch register
6699 ;; for the following branch.
6700 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6701 ;; because the insn then might be deemed dead and deleted. And we can't
6702 ;; make the use in the jump insn explicit because that would disable
6703 ;; delay slot scheduling from the target.
6704 (define_insn "indirect_jump_scratch"
6705 [(set (match_operand:SI 0 "register_operand" "=r")
6706 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6707 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6710 [(set_attr "length" "0")])
6712 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6713 ;; being pulled into the delay slot of a condbranch that has been made to
6714 ;; jump around the unconditional jump because it was out of range.
6715 (define_insn "stuff_delay_slot"
6717 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6718 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6721 [(set_attr "length" "0")
6722 (set_attr "cond_delay_slot" "yes")])
6724 ;; Conditional branch insns
6726 (define_expand "beq_media"
6728 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6729 (match_operand:DI 2 "arith_operand" "r,I06"))
6730 (match_operand 0 "" "")
6733 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6735 (define_insn "*beq_media_i"
6737 (if_then_else (match_operator 3 "equality_comparison_operator"
6738 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6739 (match_operand:DI 2 "arith_operand" "r,I06")])
6740 (match_operand 0 "target_operand" "b,b")
6745 b%o3i%' %1, %2, %0%>"
6746 [(set_attr "type" "cbranch_media")])
6748 (define_insn "*beq_media_i32"
6750 (if_then_else (match_operator 3 "equality_comparison_operator"
6751 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6752 (match_operand:SI 2 "arith_operand" "r,I06")])
6753 (match_operand 0 "target_operand" "b,b")
6758 b%o3i%' %1, %2, %0%>"
6759 [(set_attr "type" "cbranch_media")])
6761 (define_expand "bne_media"
6763 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6764 (match_operand:DI 2 "arith_operand" "r,I06"))
6765 (match_operand 0 "" "")
6768 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6770 (define_expand "bgt_media"
6772 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6773 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6774 (match_operand 0 "" "")
6777 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6779 (define_expand "bge_media"
6781 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6782 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6783 (match_operand 0 "" "")
6786 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6788 (define_expand "bgtu_media"
6790 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6791 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6792 (match_operand 0 "" "")
6795 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6797 (define_expand "bgeu_media"
6799 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6800 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6801 (match_operand 0 "" "")
6804 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6806 (define_insn "*bgt_media_i"
6808 (if_then_else (match_operator 3 "greater_comparison_operator"
6809 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6810 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6811 (match_operand 0 "target_operand" "b")
6814 "b%o3%' %N1, %N2, %0%>"
6815 [(set_attr "type" "cbranch_media")])
6817 (define_insn "*bgt_media_i32"
6819 (if_then_else (match_operator 3 "greater_comparison_operator"
6820 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6821 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6822 (match_operand 0 "target_operand" "b")
6825 "b%o3%' %N1, %N2, %0%>"
6826 [(set_attr "type" "cbranch_media")])
6828 ;; These are only needed to make invert_jump() happy - otherwise, jump
6829 ;; optimization will be silently disabled.
6830 (define_insn "*blt_media_i"
6832 (if_then_else (match_operator 3 "less_comparison_operator"
6833 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6834 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6835 (match_operand 0 "target_operand" "b")
6838 "b%o3%' %N2, %N1, %0%>"
6839 [(set_attr "type" "cbranch_media")])
6841 (define_insn "*blt_media_i32"
6843 (if_then_else (match_operator 3 "less_comparison_operator"
6844 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6845 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6846 (match_operand 0 "target_operand" "b")
6849 "b%o3%' %N2, %N1, %0%>"
6850 [(set_attr "type" "cbranch_media")])
6852 (define_expand "beq"
6854 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6855 (label_ref (match_operand 0 "" ""))
6862 enum machine_mode mode = GET_MODE (sh_compare_op0);
6864 if (mode != DImode && mode != SImode)
6866 rtx tmp = gen_reg_rtx (DImode);
6868 emit_insn (gen_seq (tmp));
6869 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6873 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6874 if (CONSTANT_P (sh_compare_op1)
6875 && (GET_CODE (sh_compare_op1) != CONST_INT
6876 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6877 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6878 emit_jump_insn (gen_beq_media (operands[0],
6879 sh_compare_op0, sh_compare_op1));
6883 from_compare (operands, EQ);
6886 (define_expand "bne"
6888 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6889 (label_ref (match_operand 0 "" ""))
6896 enum machine_mode mode = GET_MODE (sh_compare_op0);
6898 if (mode != DImode && mode != SImode)
6900 rtx tmp = gen_reg_rtx (DImode);
6902 emit_insn (gen_seq (tmp));
6903 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6907 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6908 if (CONSTANT_P (sh_compare_op1)
6909 && (GET_CODE (sh_compare_op1) != CONST_INT
6910 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6911 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6912 emit_jump_insn (gen_bne_media (operands[0],
6913 sh_compare_op0, sh_compare_op1));
6917 from_compare (operands, EQ);
6920 (define_expand "bgt"
6922 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6923 (label_ref (match_operand 0 "" ""))
6930 enum machine_mode mode = GET_MODE (sh_compare_op0);
6932 if (mode != DImode && mode != SImode)
6934 rtx tmp = gen_reg_rtx (DImode);
6936 emit_insn (gen_sgt (tmp));
6937 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6941 if (sh_compare_op0 != const0_rtx)
6942 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6943 if (sh_compare_op1 != const0_rtx)
6944 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6945 emit_jump_insn (gen_bgt_media (operands[0],
6946 sh_compare_op0, sh_compare_op1));
6950 from_compare (operands, GT);
6953 (define_expand "blt"
6955 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6956 (label_ref (match_operand 0 "" ""))
6963 enum machine_mode mode = GET_MODE (sh_compare_op0);
6965 if (mode != DImode && mode != SImode)
6967 rtx tmp = gen_reg_rtx (DImode);
6969 emit_insn (gen_slt (tmp));
6970 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6974 if (sh_compare_op0 != const0_rtx)
6975 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6976 if (sh_compare_op1 != const0_rtx)
6977 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6978 emit_jump_insn (gen_bgt_media (operands[0],
6979 sh_compare_op1, sh_compare_op0));
6983 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6985 rtx tmp = sh_compare_op0;
6986 sh_compare_op0 = sh_compare_op1;
6987 sh_compare_op1 = tmp;
6988 emit_insn (gen_bgt (operands[0]));
6991 from_compare (operands, GE);
6994 (define_expand "ble"
6996 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6997 (label_ref (match_operand 0 "" ""))
7004 enum machine_mode mode = GET_MODE (sh_compare_op0);
7006 if (mode != DImode && mode != SImode)
7008 rtx tmp = gen_reg_rtx (DImode);
7010 emit_insn (gen_sle (tmp));
7011 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7015 if (sh_compare_op0 != const0_rtx)
7016 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7017 if (sh_compare_op1 != const0_rtx)
7018 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7019 emit_jump_insn (gen_bge_media (operands[0],
7020 sh_compare_op1, sh_compare_op0));
7026 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7028 rtx tmp = sh_compare_op0;
7029 sh_compare_op0 = sh_compare_op1;
7030 sh_compare_op1 = tmp;
7031 emit_insn (gen_bge (operands[0]));
7034 from_compare (operands, GT);
7037 (define_expand "bge"
7039 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7040 (label_ref (match_operand 0 "" ""))
7047 enum machine_mode mode = GET_MODE (sh_compare_op0);
7049 if (mode != DImode && mode != SImode)
7051 rtx tmp = gen_reg_rtx (DImode);
7053 emit_insn (gen_sge (tmp));
7054 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7058 if (sh_compare_op0 != const0_rtx)
7059 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7060 if (sh_compare_op1 != const0_rtx)
7061 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7062 emit_jump_insn (gen_bge_media (operands[0],
7063 sh_compare_op0, sh_compare_op1));
7069 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7071 rtx tmp = sh_compare_op0;
7072 sh_compare_op0 = sh_compare_op1;
7073 sh_compare_op1 = tmp;
7074 emit_insn (gen_ble (operands[0]));
7077 from_compare (operands, GE);
7080 (define_expand "bgtu"
7082 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7083 (label_ref (match_operand 0 "" ""))
7090 enum machine_mode mode = GET_MODE (sh_compare_op0);
7092 if (sh_compare_op0 != const0_rtx)
7093 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7094 if (sh_compare_op1 != const0_rtx)
7095 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7096 emit_jump_insn (gen_bgtu_media (operands[0],
7097 sh_compare_op0, sh_compare_op1));
7101 from_compare (operands, GTU);
7104 (define_expand "bltu"
7106 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7107 (label_ref (match_operand 0 "" ""))
7114 enum machine_mode mode = GET_MODE (sh_compare_op0);
7116 if (sh_compare_op0 != const0_rtx)
7117 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7118 if (sh_compare_op1 != const0_rtx)
7119 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7120 emit_jump_insn (gen_bgtu_media (operands[0],
7121 sh_compare_op1, sh_compare_op0));
7125 from_compare (operands, GEU);
7128 (define_expand "bgeu"
7130 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7131 (label_ref (match_operand 0 "" ""))
7138 enum machine_mode mode = GET_MODE (sh_compare_op0);
7140 if (sh_compare_op0 != const0_rtx)
7141 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7142 if (sh_compare_op1 != const0_rtx)
7143 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7144 emit_jump_insn (gen_bgeu_media (operands[0],
7145 sh_compare_op0, sh_compare_op1));
7149 from_compare (operands, GEU);
7152 (define_expand "bleu"
7154 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7155 (label_ref (match_operand 0 "" ""))
7162 enum machine_mode mode = GET_MODE (sh_compare_op0);
7164 if (sh_compare_op0 != const0_rtx)
7165 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7166 if (sh_compare_op1 != const0_rtx)
7167 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7168 emit_jump_insn (gen_bgeu_media (operands[0],
7169 sh_compare_op1, sh_compare_op0));
7173 from_compare (operands, GTU);
7176 (define_expand "bunordered"
7177 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7179 (if_then_else (ne (match_dup 1) (const_int 0))
7180 (match_operand 0 "" "")
7185 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7186 operands[1] = gen_reg_rtx (DImode);
7187 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7188 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7191 ;; combiner splitter for test-and-branch on single bit in register. This
7192 ;; is endian dependent because the non-paradoxical subreg looks different
7197 (match_operator 3 "equality_comparison_operator"
7198 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7199 "extend_reg_operand" "")
7203 "const_int_operand" "")) 0)
7205 (match_operand 0 "target_operand" "")
7207 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7208 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7209 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7210 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7214 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7215 operands[6] = (GET_CODE (operands[3]) == EQ
7216 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7217 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7220 ;; ------------------------------------------------------------------------
7221 ;; Jump and linkage insns
7222 ;; ------------------------------------------------------------------------
7224 (define_insn "jump_compact"
7226 (label_ref (match_operand 0 "" "")))]
7230 /* The length is 16 if the delay slot is unfilled. */
7231 if (get_attr_length(insn) > 4)
7232 return output_far_jump(insn, operands[0]);
7234 return \"bra %l0%#\";
7236 [(set_attr "type" "jump")
7237 (set_attr "needs_delay_slot" "yes")])
7239 ;; ??? It would be much saner to explicitly use the scratch register
7240 ;; in the jump insn, and have indirect_jump_scratch only set it,
7241 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7242 ;; from the target then, as it uses simplejump_p.
7243 ;;(define_insn "jump_compact_far"
7245 ;; (label_ref (match_operand 0 "" "")))
7246 ;; (use (match_operand 1 "register_operand" "r")]
7248 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7249 ;; [(set_attr "type" "jump")
7250 ;; (set_attr "needs_delay_slot" "yes")])
7252 (define_insn "jump_media"
7254 (match_operand 0 "target_operand" "b"))]
7257 [(set_attr "type" "jump_media")])
7259 (define_expand "jump"
7261 (label_ref (match_operand 0 "" "")))]
7266 emit_jump_insn (gen_jump_compact (operands[0]));
7267 else if (TARGET_SHMEDIA)
7269 if (reload_in_progress || reload_completed)
7271 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7277 (define_insn "force_mode_for_call"
7278 [(use (reg:PSI FPSCR_REG))]
7281 [(set_attr "length" "0")
7282 (set (attr "fp_mode")
7283 (if_then_else (eq_attr "fpu_single" "yes")
7284 (const_string "single") (const_string "double")))])
7286 (define_insn "calli"
7287 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7288 (match_operand 1 "" ""))
7289 (use (reg:PSI FPSCR_REG))
7290 (clobber (reg:SI PR_REG))]
7293 [(set_attr "type" "call")
7294 (set (attr "fp_mode")
7295 (if_then_else (eq_attr "fpu_single" "yes")
7296 (const_string "single") (const_string "double")))
7297 (set_attr "needs_delay_slot" "yes")
7298 (set_attr "fp_set" "unknown")])
7300 ;; This is a pc-rel call, using bsrf, for use with PIC.
7302 (define_insn "calli_pcrel"
7303 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7304 (match_operand 1 "" ""))
7305 (use (reg:PSI FPSCR_REG))
7306 (use (reg:SI PIC_REG))
7307 (use (match_operand 2 "" ""))
7308 (clobber (reg:SI PR_REG))]
7311 [(set_attr "type" "call")
7312 (set (attr "fp_mode")
7313 (if_then_else (eq_attr "fpu_single" "yes")
7314 (const_string "single") (const_string "double")))
7315 (set_attr "needs_delay_slot" "yes")
7316 (set_attr "fp_set" "unknown")])
7318 (define_insn_and_split "call_pcrel"
7319 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7320 (match_operand 1 "" ""))
7321 (use (reg:PSI FPSCR_REG))
7322 (use (reg:SI PIC_REG))
7323 (clobber (reg:SI PR_REG))
7324 (clobber (match_scratch:SI 2 "=r"))]
7331 rtx lab = PATTERN (gen_call_site ());
7333 if (SYMBOL_REF_LOCAL_P (operands[0]))
7334 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7336 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7337 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7340 [(set_attr "type" "call")
7341 (set (attr "fp_mode")
7342 (if_then_else (eq_attr "fpu_single" "yes")
7343 (const_string "single") (const_string "double")))
7344 (set_attr "needs_delay_slot" "yes")
7345 (set_attr "fp_set" "unknown")])
7347 (define_insn "call_compact"
7348 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7349 (match_operand 1 "" ""))
7350 (match_operand 2 "immediate_operand" "n")
7351 (use (reg:SI R0_REG))
7352 (use (reg:SI R1_REG))
7353 (use (reg:PSI FPSCR_REG))
7354 (clobber (reg:SI PR_REG))]
7355 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7357 [(set_attr "type" "call")
7358 (set (attr "fp_mode")
7359 (if_then_else (eq_attr "fpu_single" "yes")
7360 (const_string "single") (const_string "double")))
7361 (set_attr "needs_delay_slot" "yes")])
7363 (define_insn "call_compact_rettramp"
7364 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7365 (match_operand 1 "" ""))
7366 (match_operand 2 "immediate_operand" "n")
7367 (use (reg:SI R0_REG))
7368 (use (reg:SI R1_REG))
7369 (use (reg:PSI FPSCR_REG))
7370 (clobber (reg:SI R10_REG))
7371 (clobber (reg:SI PR_REG))]
7372 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7374 [(set_attr "type" "call")
7375 (set (attr "fp_mode")
7376 (if_then_else (eq_attr "fpu_single" "yes")
7377 (const_string "single") (const_string "double")))
7378 (set_attr "needs_delay_slot" "yes")])
7380 (define_insn "call_media"
7381 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7382 (match_operand 1 "" ""))
7383 (clobber (reg:DI PR_MEDIA_REG))]
7386 [(set_attr "type" "jump_media")])
7388 (define_insn "call_valuei"
7389 [(set (match_operand 0 "" "=rf")
7390 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7391 (match_operand 2 "" "")))
7392 (use (reg:PSI FPSCR_REG))
7393 (clobber (reg:SI PR_REG))]
7396 [(set_attr "type" "call")
7397 (set (attr "fp_mode")
7398 (if_then_else (eq_attr "fpu_single" "yes")
7399 (const_string "single") (const_string "double")))
7400 (set_attr "needs_delay_slot" "yes")
7401 (set_attr "fp_set" "unknown")])
7403 (define_insn "call_valuei_pcrel"
7404 [(set (match_operand 0 "" "=rf")
7405 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7406 (match_operand 2 "" "")))
7407 (use (reg:PSI FPSCR_REG))
7408 (use (reg:SI PIC_REG))
7409 (use (match_operand 3 "" ""))
7410 (clobber (reg:SI PR_REG))]
7413 [(set_attr "type" "call")
7414 (set (attr "fp_mode")
7415 (if_then_else (eq_attr "fpu_single" "yes")
7416 (const_string "single") (const_string "double")))
7417 (set_attr "needs_delay_slot" "yes")
7418 (set_attr "fp_set" "unknown")])
7420 (define_insn_and_split "call_value_pcrel"
7421 [(set (match_operand 0 "" "=rf")
7422 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7423 (match_operand 2 "" "")))
7424 (use (reg:PSI FPSCR_REG))
7425 (use (reg:SI PIC_REG))
7426 (clobber (reg:SI PR_REG))
7427 (clobber (match_scratch:SI 3 "=r"))]
7434 rtx lab = PATTERN (gen_call_site ());
7436 if (SYMBOL_REF_LOCAL_P (operands[1]))
7437 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7439 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7440 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7444 [(set_attr "type" "call")
7445 (set (attr "fp_mode")
7446 (if_then_else (eq_attr "fpu_single" "yes")
7447 (const_string "single") (const_string "double")))
7448 (set_attr "needs_delay_slot" "yes")
7449 (set_attr "fp_set" "unknown")])
7451 (define_insn "call_value_compact"
7452 [(set (match_operand 0 "" "=rf")
7453 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7454 (match_operand 2 "" "")))
7455 (match_operand 3 "immediate_operand" "n")
7456 (use (reg:SI R0_REG))
7457 (use (reg:SI R1_REG))
7458 (use (reg:PSI FPSCR_REG))
7459 (clobber (reg:SI PR_REG))]
7460 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7462 [(set_attr "type" "call")
7463 (set (attr "fp_mode")
7464 (if_then_else (eq_attr "fpu_single" "yes")
7465 (const_string "single") (const_string "double")))
7466 (set_attr "needs_delay_slot" "yes")])
7468 (define_insn "call_value_compact_rettramp"
7469 [(set (match_operand 0 "" "=rf")
7470 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7471 (match_operand 2 "" "")))
7472 (match_operand 3 "immediate_operand" "n")
7473 (use (reg:SI R0_REG))
7474 (use (reg:SI R1_REG))
7475 (use (reg:PSI FPSCR_REG))
7476 (clobber (reg:SI R10_REG))
7477 (clobber (reg:SI PR_REG))]
7478 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7480 [(set_attr "type" "call")
7481 (set (attr "fp_mode")
7482 (if_then_else (eq_attr "fpu_single" "yes")
7483 (const_string "single") (const_string "double")))
7484 (set_attr "needs_delay_slot" "yes")])
7486 (define_insn "call_value_media"
7487 [(set (match_operand 0 "" "=rf")
7488 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7489 (match_operand 2 "" "")))
7490 (clobber (reg:DI PR_MEDIA_REG))]
7493 [(set_attr "type" "jump_media")])
7495 (define_expand "call"
7496 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7497 (match_operand 1 "" ""))
7498 (match_operand 2 "" "")
7499 (use (reg:PSI FPSCR_REG))
7500 (clobber (reg:SI PR_REG))])]
7506 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7507 emit_call_insn (gen_call_media (operands[0], operands[1]));
7510 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7512 rtx cookie_rtx = operands[2];
7513 long cookie = INTVAL (cookie_rtx);
7514 rtx func = XEXP (operands[0], 0);
7519 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7521 rtx reg = gen_reg_rtx (Pmode);
7523 emit_insn (gen_symGOTPLT2reg (reg, func));
7527 func = legitimize_pic_address (func, Pmode, 0);
7530 r0 = gen_rtx_REG (SImode, R0_REG);
7531 r1 = gen_rtx_REG (SImode, R1_REG);
7533 /* Since such a call function may use all call-clobbered
7534 registers, we force a mode switch earlier, so that we don't
7535 run out of registers when adjusting fpscr for the call. */
7536 emit_insn (gen_force_mode_for_call ());
7539 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7541 operands[0] = force_reg (SImode, operands[0]);
7543 emit_move_insn (r0, func);
7544 emit_move_insn (r1, cookie_rtx);
7546 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7547 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7550 emit_call_insn (gen_call_compact (operands[0], operands[1],
7555 else if (TARGET_SHCOMPACT && flag_pic
7556 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7557 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7559 rtx reg = gen_reg_rtx (Pmode);
7561 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7562 XEXP (operands[0], 0) = reg;
7564 if (flag_pic && TARGET_SH2
7565 && GET_CODE (operands[0]) == MEM
7566 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7568 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7573 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7574 operands[1] = operands[2];
7577 emit_call_insn (gen_calli (operands[0], operands[1]));
7581 (define_insn "call_pop_compact"
7582 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7583 (match_operand 1 "" ""))
7584 (match_operand 2 "immediate_operand" "n")
7585 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7586 (match_operand 3 "immediate_operand" "n")))
7587 (use (reg:SI R0_REG))
7588 (use (reg:SI R1_REG))
7589 (use (reg:PSI FPSCR_REG))
7590 (clobber (reg:SI PR_REG))]
7591 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7593 [(set_attr "type" "call")
7594 (set (attr "fp_mode")
7595 (if_then_else (eq_attr "fpu_single" "yes")
7596 (const_string "single") (const_string "double")))
7597 (set_attr "needs_delay_slot" "yes")])
7599 (define_insn "call_pop_compact_rettramp"
7600 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7601 (match_operand 1 "" ""))
7602 (match_operand 2 "immediate_operand" "n")
7603 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7604 (match_operand 3 "immediate_operand" "n")))
7605 (use (reg:SI R0_REG))
7606 (use (reg:SI R1_REG))
7607 (use (reg:PSI FPSCR_REG))
7608 (clobber (reg:SI R10_REG))
7609 (clobber (reg:SI PR_REG))]
7610 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7612 [(set_attr "type" "call")
7613 (set (attr "fp_mode")
7614 (if_then_else (eq_attr "fpu_single" "yes")
7615 (const_string "single") (const_string "double")))
7616 (set_attr "needs_delay_slot" "yes")])
7618 (define_expand "call_pop"
7619 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7620 (match_operand 1 "" ""))
7621 (match_operand 2 "" "")
7622 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7623 (match_operand 3 "" "")))])]
7632 gcc_assert (operands[2] && INTVAL (operands[2]));
7633 cookie_rtx = operands[2];
7634 cookie = INTVAL (cookie_rtx);
7635 func = XEXP (operands[0], 0);
7639 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7641 rtx reg = gen_reg_rtx (Pmode);
7642 emit_insn (gen_symGOTPLT2reg (reg, func));
7646 func = legitimize_pic_address (func, Pmode, 0);
7649 r0 = gen_rtx_REG (SImode, R0_REG);
7650 r1 = gen_rtx_REG (SImode, R1_REG);
7652 /* Since such a call function may use all call-clobbered
7653 registers, we force a mode switch earlier, so that we don't
7654 run out of registers when adjusting fpscr for the call. */
7655 emit_insn (gen_force_mode_for_call ());
7657 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7659 operands[0] = force_reg (SImode, operands[0]);
7661 emit_move_insn (r0, func);
7662 emit_move_insn (r1, cookie_rtx);
7664 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7665 emit_call_insn (gen_call_pop_compact_rettramp
7666 (operands[0], operands[1], operands[2], operands[3]));
7668 emit_call_insn (gen_call_pop_compact
7669 (operands[0], operands[1], operands[2], operands[3]));
7674 (define_expand "call_value"
7675 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7676 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7677 (match_operand 2 "" "")))
7678 (match_operand 3 "" "")
7679 (use (reg:PSI FPSCR_REG))
7680 (clobber (reg:SI PR_REG))])]
7686 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7687 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7691 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7693 rtx cookie_rtx = operands[3];
7694 long cookie = INTVAL (cookie_rtx);
7695 rtx func = XEXP (operands[1], 0);
7700 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7702 rtx reg = gen_reg_rtx (Pmode);
7704 emit_insn (gen_symGOTPLT2reg (reg, func));
7708 func = legitimize_pic_address (func, Pmode, 0);
7711 r0 = gen_rtx_REG (SImode, R0_REG);
7712 r1 = gen_rtx_REG (SImode, R1_REG);
7714 /* Since such a call function may use all call-clobbered
7715 registers, we force a mode switch earlier, so that we don't
7716 run out of registers when adjusting fpscr for the call. */
7717 emit_insn (gen_force_mode_for_call ());
7720 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7722 operands[1] = force_reg (SImode, operands[1]);
7724 emit_move_insn (r0, func);
7725 emit_move_insn (r1, cookie_rtx);
7727 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7728 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7733 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7734 operands[2], operands[3]));
7738 else if (TARGET_SHCOMPACT && flag_pic
7739 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7740 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7742 rtx reg = gen_reg_rtx (Pmode);
7744 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7745 XEXP (operands[1], 0) = reg;
7747 if (flag_pic && TARGET_SH2
7748 && GET_CODE (operands[1]) == MEM
7749 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7751 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7756 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7758 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7762 (define_insn "sibcalli"
7763 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7764 (match_operand 1 "" ""))
7765 (use (reg:PSI FPSCR_REG))
7769 [(set_attr "needs_delay_slot" "yes")
7770 (set (attr "fp_mode")
7771 (if_then_else (eq_attr "fpu_single" "yes")
7772 (const_string "single") (const_string "double")))
7773 (set_attr "type" "jump_ind")])
7775 (define_insn "sibcalli_pcrel"
7776 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7777 (match_operand 1 "" ""))
7778 (use (match_operand 2 "" ""))
7779 (use (reg:PSI FPSCR_REG))
7783 [(set_attr "needs_delay_slot" "yes")
7784 (set (attr "fp_mode")
7785 (if_then_else (eq_attr "fpu_single" "yes")
7786 (const_string "single") (const_string "double")))
7787 (set_attr "type" "jump_ind")])
7789 ;; This uses an unspec to describe that the symbol_ref is very close.
7790 (define_insn "sibcalli_thunk"
7791 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7793 (match_operand 1 "" ""))
7794 (use (reg:PSI FPSCR_REG))
7798 [(set_attr "needs_delay_slot" "yes")
7799 (set (attr "fp_mode")
7800 (if_then_else (eq_attr "fpu_single" "yes")
7801 (const_string "single") (const_string "double")))
7802 (set_attr "type" "jump")
7803 (set_attr "length" "2")])
7805 (define_insn_and_split "sibcall_pcrel"
7806 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7807 (match_operand 1 "" ""))
7808 (use (reg:PSI FPSCR_REG))
7809 (clobber (match_scratch:SI 2 "=k"))
7817 rtx lab = PATTERN (gen_call_site ());
7820 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7821 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7823 SIBLING_CALL_P (call_insn) = 1;
7826 [(set_attr "needs_delay_slot" "yes")
7827 (set (attr "fp_mode")
7828 (if_then_else (eq_attr "fpu_single" "yes")
7829 (const_string "single") (const_string "double")))
7830 (set_attr "type" "jump_ind")])
7832 (define_insn "sibcall_compact"
7833 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7834 (match_operand 1 "" ""))
7836 (use (match_operand:SI 2 "register_operand" "z,x"))
7837 (use (reg:SI R1_REG))
7838 (use (reg:PSI FPSCR_REG))
7839 ;; We want to make sure the `x' above will only match MACH_REG
7840 ;; because sibcall_epilogue may clobber MACL_REG.
7841 (clobber (reg:SI MACL_REG))]
7845 jmp @%0\\n sts %2, r0"
7846 [(set_attr "needs_delay_slot" "yes,no")
7847 (set_attr "length" "2,4")
7848 (set (attr "fp_mode") (const_string "single"))
7849 (set_attr "type" "jump_ind")])
7851 (define_insn "sibcall_media"
7852 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7853 (match_operand 1 "" ""))
7854 (use (reg:SI PR_MEDIA_REG))
7858 [(set_attr "type" "jump_media")])
7860 (define_expand "sibcall"
7862 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7863 (match_operand 1 "" ""))
7864 (match_operand 2 "" "")
7865 (use (reg:PSI FPSCR_REG))
7872 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7873 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7876 else if (TARGET_SHCOMPACT && operands[2]
7877 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7879 rtx cookie_rtx = operands[2];
7880 long cookie = INTVAL (cookie_rtx);
7881 rtx func = XEXP (operands[0], 0);
7886 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7888 rtx reg = gen_reg_rtx (Pmode);
7890 emit_insn (gen_symGOT2reg (reg, func));
7894 func = legitimize_pic_address (func, Pmode, 0);
7897 /* FIXME: if we could tell whether all argument registers are
7898 already taken, we could decide whether to force the use of
7899 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7900 simple way to tell. We could use the CALL_COOKIE, but we
7901 can't currently tell a register used for regular argument
7902 passing from one that is unused. If we leave it up to reload
7903 to decide which register to use, it seems to always choose
7904 R0_REG, which leaves no available registers in SIBCALL_REGS
7905 to hold the address of the trampoline. */
7906 mach = gen_rtx_REG (SImode, MACH_REG);
7907 r1 = gen_rtx_REG (SImode, R1_REG);
7909 /* Since such a call function may use all call-clobbered
7910 registers, we force a mode switch earlier, so that we don't
7911 run out of registers when adjusting fpscr for the call. */
7912 emit_insn (gen_force_mode_for_call ());
7915 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7917 operands[0] = force_reg (SImode, operands[0]);
7919 /* We don't need a return trampoline, since the callee will
7920 return directly to the upper caller. */
7921 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7923 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7924 cookie_rtx = GEN_INT (cookie);
7927 emit_move_insn (mach, func);
7928 emit_move_insn (r1, cookie_rtx);
7930 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7933 else if (TARGET_SHCOMPACT && flag_pic
7934 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7935 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7937 rtx reg = gen_reg_rtx (Pmode);
7939 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7940 XEXP (operands[0], 0) = reg;
7942 if (flag_pic && TARGET_SH2
7943 && GET_CODE (operands[0]) == MEM
7944 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7945 /* The PLT needs the PIC register, but the epilogue would have
7946 to restore it, so we can only use PC-relative PIC calls for
7947 static functions. */
7948 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7950 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7954 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7956 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7960 (define_expand "sibcall_value"
7961 [(set (match_operand 0 "" "")
7962 (call (match_operand 1 "" "")
7963 (match_operand 2 "" "")))
7964 (match_operand 3 "" "")]
7968 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7972 (define_insn "call_value_pop_compact"
7973 [(set (match_operand 0 "" "=rf")
7974 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7975 (match_operand 2 "" "")))
7976 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7977 (match_operand 4 "immediate_operand" "n")))
7978 (match_operand 3 "immediate_operand" "n")
7979 (use (reg:SI R0_REG))
7980 (use (reg:SI R1_REG))
7981 (use (reg:PSI FPSCR_REG))
7982 (clobber (reg:SI PR_REG))]
7983 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7985 [(set_attr "type" "call")
7986 (set (attr "fp_mode")
7987 (if_then_else (eq_attr "fpu_single" "yes")
7988 (const_string "single") (const_string "double")))
7989 (set_attr "needs_delay_slot" "yes")])
7991 (define_insn "call_value_pop_compact_rettramp"
7992 [(set (match_operand 0 "" "=rf")
7993 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7994 (match_operand 2 "" "")))
7995 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7996 (match_operand 4 "immediate_operand" "n")))
7997 (match_operand 3 "immediate_operand" "n")
7998 (use (reg:SI R0_REG))
7999 (use (reg:SI R1_REG))
8000 (use (reg:PSI FPSCR_REG))
8001 (clobber (reg:SI R10_REG))
8002 (clobber (reg:SI PR_REG))]
8003 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8005 [(set_attr "type" "call")
8006 (set (attr "fp_mode")
8007 (if_then_else (eq_attr "fpu_single" "yes")
8008 (const_string "single") (const_string "double")))
8009 (set_attr "needs_delay_slot" "yes")])
8011 (define_expand "call_value_pop"
8012 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8013 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8014 (match_operand 2 "" "")))
8015 (match_operand 3 "" "")
8016 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8017 (match_operand 4 "" "")))])]
8026 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8027 cookie_rtx = operands[3];
8028 cookie = INTVAL (cookie_rtx);
8029 func = XEXP (operands[1], 0);
8033 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8035 rtx reg = gen_reg_rtx (Pmode);
8037 emit_insn (gen_symGOTPLT2reg (reg, func));
8041 func = legitimize_pic_address (func, Pmode, 0);
8044 r0 = gen_rtx_REG (SImode, R0_REG);
8045 r1 = gen_rtx_REG (SImode, R1_REG);
8047 /* Since such a call function may use all call-clobbered
8048 registers, we force a mode switch earlier, so that we don't
8049 run out of registers when adjusting fpscr for the call. */
8050 emit_insn (gen_force_mode_for_call ());
8052 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8054 operands[1] = force_reg (SImode, operands[1]);
8056 emit_move_insn (r0, func);
8057 emit_move_insn (r1, cookie_rtx);
8059 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8060 emit_call_insn (gen_call_value_pop_compact_rettramp
8061 (operands[0], operands[1], operands[2],
8062 operands[3], operands[4]));
8064 emit_call_insn (gen_call_value_pop_compact
8065 (operands[0], operands[1], operands[2],
8066 operands[3], operands[4]));
8071 (define_expand "sibcall_epilogue"
8076 sh_expand_epilogue (1);
8077 if (TARGET_SHCOMPACT)
8081 /* If epilogue clobbers r0, preserve it in macl. */
8082 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8083 if ((set = single_set (insn))
8084 && GET_CODE (SET_DEST (set)) == REG
8085 && REGNO (SET_DEST (set)) == R0_REG)
8087 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8088 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8091 /* We can't tell at this point whether the sibcall is a
8092 sibcall_compact and, if it is, whether it uses r0 or
8093 mach as operand 2, so let the instructions that
8094 preserve r0 be optimized away if r0 turns out to be
8096 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8097 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8099 i = emit_move_insn (r0, tmp);
8100 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8108 (define_insn "indirect_jump_compact"
8110 (match_operand:SI 0 "arith_reg_operand" "r"))]
8113 [(set_attr "needs_delay_slot" "yes")
8114 (set_attr "type" "jump_ind")])
8116 (define_expand "indirect_jump"
8118 (match_operand 0 "register_operand" ""))]
8122 if (GET_MODE (operands[0]) != Pmode)
8123 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8126 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8127 ;; which can be present in structured code from indirect jumps which can not
8128 ;; be present in structured code. This allows -fprofile-arcs to work.
8130 ;; For SH1 processors.
8131 (define_insn "casesi_jump_1"
8133 (match_operand:SI 0 "register_operand" "r"))
8134 (use (label_ref (match_operand 1 "" "")))]
8137 [(set_attr "needs_delay_slot" "yes")
8138 (set_attr "type" "jump_ind")])
8140 ;; For all later processors.
8141 (define_insn "casesi_jump_2"
8142 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8143 (label_ref (match_operand 1 "" ""))))
8144 (use (label_ref (match_operand 2 "" "")))]
8146 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8148 [(set_attr "needs_delay_slot" "yes")
8149 (set_attr "type" "jump_ind")])
8151 (define_insn "casesi_jump_media"
8152 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8153 (use (label_ref (match_operand 1 "" "")))]
8156 [(set_attr "type" "jump_media")])
8158 ;; Call subroutine returning any type.
8159 ;; ??? This probably doesn't work.
8161 (define_expand "untyped_call"
8162 [(parallel [(call (match_operand 0 "" "")
8164 (match_operand 1 "" "")
8165 (match_operand 2 "" "")])]
8166 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8171 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8173 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8175 rtx set = XVECEXP (operands[2], 0, i);
8176 emit_move_insn (SET_DEST (set), SET_SRC (set));
8179 /* The optimizer does not know that the call sets the function value
8180 registers we stored in the result block. We avoid problems by
8181 claiming that all hard registers are used and clobbered at this
8183 emit_insn (gen_blockage ());
8188 ;; ------------------------------------------------------------------------
8190 ;; ------------------------------------------------------------------------
8193 [(set (reg:SI T_REG)
8194 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8195 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8198 [(set_attr "type" "arith")])
8205 ;; Load address of a label. This is only generated by the casesi expand,
8206 ;; and by machine_dependent_reorg (fixing up fp moves).
8207 ;; This must use unspec, because this only works for labels that are
8211 [(set (reg:SI R0_REG)
8212 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8215 [(set_attr "in_delay_slot" "no")
8216 (set_attr "type" "arith")])
8218 ;; machine_dependent_reorg will make this a `mova'.
8219 (define_insn "mova_const"
8220 [(set (reg:SI R0_REG)
8221 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8224 [(set_attr "in_delay_slot" "no")
8225 (set_attr "type" "arith")])
8227 (define_expand "GOTaddr2picreg"
8228 [(set (reg:SI R0_REG)
8229 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8231 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8232 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8235 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8236 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8240 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8241 rtx pic = operands[0];
8242 rtx lab = PATTERN (gen_call_site ());
8245 equiv = operands[1];
8246 operands[1] = gen_rtx_MINUS (Pmode,
8250 gen_rtx_MINUS (Pmode,
8251 gen_rtx_CONST (Pmode,
8254 operands[1] = gen_sym2PIC (operands[1]);
8255 PUT_MODE (operands[1], Pmode);
8257 if (Pmode == SImode)
8259 emit_insn (gen_movsi_const (pic, operands[1]));
8260 emit_insn (gen_ptrel_si (tr, pic, lab));
8264 emit_insn (gen_movdi_const (pic, operands[1]));
8265 emit_insn (gen_ptrel_di (tr, pic, lab));
8268 insn = emit_move_insn (operands[0], tr);
8270 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8279 [(set (match_operand 0 "target_reg_operand" "=b")
8280 (const (unspec [(match_operand 1 "" "Csy")]
8281 UNSPEC_DATALABEL)))]
8282 "TARGET_SHMEDIA && flag_pic
8283 && EXTRA_CONSTRAINT_Csy (operands[1])"
8284 "ptb/u datalabel %1, %0"
8285 [(set_attr "type" "ptabs_media")
8286 (set_attr "length" "*")])
8288 (define_insn "ptrel_si"
8289 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8290 (plus:SI (match_operand:SI 1 "register_operand" "r")
8292 (match_operand:SI 2 "" "")]
8294 "%O2: ptrel/u %1, %0"
8295 [(set_attr "type" "ptabs_media")])
8297 (define_insn "ptrel_di"
8298 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8299 (plus:DI (match_operand:DI 1 "register_operand" "r")
8301 (match_operand:DI 2 "" "")]
8303 "%O2: ptrel/u %1, %0"
8304 [(set_attr "type" "ptabs_media")])
8306 (define_expand "builtin_setjmp_receiver"
8307 [(match_operand 0 "" "")]
8311 emit_insn (gen_GOTaddr2picreg ());
8315 (define_expand "call_site"
8316 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8320 static HOST_WIDE_INT i = 0;
8321 operands[0] = GEN_INT (i);
8325 (define_expand "sym_label2reg"
8326 [(set (match_operand:SI 0 "" "")
8329 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8332 (match_operand:SI 2 "" "")
8336 (define_expand "symGOT_load"
8337 [(set (match_dup 2) (match_operand 1 "" ""))
8338 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8339 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8345 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8346 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8350 rtx reg = operands[2];
8352 if (Pmode == DImode)
8355 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8357 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8362 emit_insn (gen_movsi_const (reg, operands[1]));
8364 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8368 emit_move_insn (operands[2], operands[1]);
8370 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8372 gen_rtx_REG (Pmode, PIC_REG)));
8374 /* N.B. This is not constant for a GOTPLT relocation. */
8375 mem = gen_rtx_MEM (Pmode, operands[3]);
8376 MEM_NOTRAP_P (mem) = 1;
8377 /* ??? Should we have a special alias set for the GOT? */
8378 insn = emit_move_insn (operands[0], mem);
8380 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8387 (define_expand "sym2GOT"
8388 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8392 (define_expand "symGOT2reg"
8393 [(match_operand 0 "" "") (match_operand 1 "" "")]
8399 gotsym = gen_sym2GOT (operands[1]);
8400 PUT_MODE (gotsym, Pmode);
8401 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8403 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8408 (define_expand "symGOTPLT2reg"
8409 [(match_operand 0 "" "") (match_operand 1 "" "")]
8413 rtx pltsym = gen_rtx_CONST (Pmode,
8414 gen_rtx_UNSPEC (Pmode,
8415 gen_rtvec (1, operands[1]),
8417 emit_insn (gen_symGOT_load (operands[0], pltsym));
8421 (define_expand "sym2GOTOFF"
8422 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8426 (define_expand "symGOTOFF2reg"
8427 [(match_operand 0 "" "") (match_operand 1 "" "")]
8431 rtx gotoffsym, insn;
8432 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8434 gotoffsym = gen_sym2GOTOFF (operands[1]);
8435 PUT_MODE (gotoffsym, Pmode);
8436 emit_move_insn (t, gotoffsym);
8437 insn = emit_move_insn (operands[0],
8438 gen_rtx_PLUS (Pmode, t,
8439 gen_rtx_REG (Pmode, PIC_REG)));
8441 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8447 (define_expand "symPLT_label2reg"
8448 [(set (match_operand:SI 0 "" "")
8451 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8455 (match_operand:SI 2 "" "")
8457 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8458 ;; Even though the PIC register is not really used by the call
8459 ;; sequence in which this is expanded, the PLT code assumes the PIC
8460 ;; register is set, so we must not skip its initialization. Since
8461 ;; we only use this expand as part of calling sequences, and never
8462 ;; to take the address of a function, this is the best point to
8463 ;; insert the (use). Using the PLT to take the address of a
8464 ;; function would be wrong, not only because the PLT entry could
8465 ;; then be called from a function that doesn't initialize the PIC
8466 ;; register to the proper GOT, but also because pointers to the
8467 ;; same function might not compare equal, should they be set by
8468 ;; different shared libraries.
8469 (use (reg:SI PIC_REG))]
8473 (define_expand "sym2PIC"
8474 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8478 ;; TLS code generation.
8479 ;; ??? this should be a define_insn_and_split
8480 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8481 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8484 (define_insn "tls_global_dynamic"
8485 [(set (match_operand:SI 0 "register_operand" "=&z")
8486 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8489 (use (reg:PSI FPSCR_REG))
8490 (use (reg:SI PIC_REG))
8491 (clobber (reg:SI PR_REG))
8492 (clobber (scratch:SI))]
8498 \\tmova\\t2f,r0\\n\\
8499 \\tmov.l\\t2f,r1\\n\\
8502 \\tadd\\tr12,r4\\n\\
8506 1:\\t.long\\t%a1@TLSGD\\n\\
8507 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8510 [(set_attr "type" "tls_load")
8511 (set_attr "length" "26")])
8513 (define_insn "tls_local_dynamic"
8514 [(set (match_operand:SI 0 "register_operand" "=&z")
8515 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8518 (use (reg:PSI FPSCR_REG))
8519 (use (reg:SI PIC_REG))
8520 (clobber (reg:SI PR_REG))
8521 (clobber (scratch:SI))]
8527 \\tmova\\t2f,r0\\n\\
8528 \\tmov.l\\t2f,r1\\n\\
8531 \\tadd\\tr12,r4\\n\\
8535 1:\\t.long\\t%a1@TLSLDM\\n\\
8536 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8539 [(set_attr "type" "tls_load")
8540 (set_attr "length" "26")])
8542 (define_expand "sym2DTPOFF"
8543 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8547 (define_expand "symDTPOFF2reg"
8548 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8552 rtx dtpoffsym, insn;
8553 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8555 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8556 PUT_MODE (dtpoffsym, Pmode);
8557 emit_move_insn (t, dtpoffsym);
8558 insn = emit_move_insn (operands[0],
8559 gen_rtx_PLUS (Pmode, t, operands[2]));
8563 (define_expand "sym2GOTTPOFF"
8564 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8568 (define_insn "tls_initial_exec"
8569 [(set (match_operand:SI 0 "register_operand" "=&r")
8570 (unspec:SI [(match_operand:SI 1 "" "")]
8572 (use (reg:SI GBR_REG))
8573 (use (reg:SI PIC_REG))
8574 (clobber (reg:SI R0_REG))]
8580 \\tstc\\tgbr,%0\\n\\
8581 \\tmov.l\\t@(r0,r12),r0\\n\\
8585 1:\\t.long\\t%a1\\n\\
8588 [(set_attr "type" "tls_load")
8589 (set_attr "length" "16")])
8591 (define_expand "sym2TPOFF"
8592 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8596 (define_expand "symTPOFF2reg"
8597 [(match_operand 0 "" "") (match_operand 1 "" "")]
8603 tpoffsym = gen_sym2TPOFF (operands[1]);
8604 PUT_MODE (tpoffsym, Pmode);
8605 insn = emit_move_insn (operands[0], tpoffsym);
8609 (define_insn "load_gbr"
8610 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8611 (use (reg:SI GBR_REG))]
8614 [(set_attr "type" "tls_load")])
8616 ;; case instruction for switch statements.
8618 ;; Operand 0 is index
8619 ;; operand 1 is the minimum bound
8620 ;; operand 2 is the maximum bound - minimum bound + 1
8621 ;; operand 3 is CODE_LABEL for the table;
8622 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8624 (define_expand "casesi"
8625 [(match_operand:SI 0 "arith_reg_operand" "")
8626 (match_operand:SI 1 "arith_reg_operand" "")
8627 (match_operand:SI 2 "arith_reg_operand" "")
8628 (match_operand 3 "" "") (match_operand 4 "" "")]
8632 rtx reg = gen_reg_rtx (SImode);
8633 rtx reg2 = gen_reg_rtx (SImode);
8636 rtx reg = gen_reg_rtx (DImode);
8637 rtx reg2 = gen_reg_rtx (DImode);
8638 rtx reg3 = gen_reg_rtx (Pmode);
8639 rtx reg4 = gen_reg_rtx (Pmode);
8640 rtx reg5 = gen_reg_rtx (Pmode);
8643 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8644 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8645 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8647 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8648 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8649 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8650 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8651 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8652 (Pmode, operands[3])));
8653 /* Messy: can we subreg to clean this up? */
8654 if (Pmode == DImode)
8655 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8657 load = gen_casesi_load_media (reg4,
8658 gen_rtx_SUBREG (DImode, reg3, 0),
8660 PUT_MODE (SET_SRC (load), Pmode);
8662 /* ??? The following add could be eliminated if we used ptrel. */
8663 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8664 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8668 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8669 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8670 /* If optimizing, casesi_worker depends on the mode of the instruction
8671 before label it 'uses' - operands[3]. */
8672 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8674 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8676 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8678 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8679 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8680 operands[3], but to lab. We will fix this up in
8681 machine_dependent_reorg. */
8686 (define_expand "casesi_0"
8687 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8688 (set (match_dup 4) (minus:SI (match_dup 4)
8689 (match_operand:SI 1 "arith_operand" "")))
8691 (gtu:SI (match_dup 4)
8692 (match_operand:SI 2 "arith_reg_operand" "")))
8694 (if_then_else (ne (reg:SI T_REG)
8696 (label_ref (match_operand 3 "" ""))
8701 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8702 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8703 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8705 (define_insn "casesi_worker_0"
8706 [(set (match_operand:SI 0 "register_operand" "=r,r")
8707 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8708 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8709 (clobber (match_scratch:SI 3 "=X,1"))
8710 (clobber (match_scratch:SI 4 "=&z,z"))]
8715 [(set (match_operand:SI 0 "register_operand" "")
8716 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8717 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8718 (clobber (match_scratch:SI 3 ""))
8719 (clobber (match_scratch:SI 4 ""))]
8720 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8721 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8722 (parallel [(set (match_dup 0)
8723 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8724 (label_ref (match_dup 2))] UNSPEC_CASESI))
8725 (clobber (match_dup 3))])
8726 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8727 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8730 [(set (match_operand:SI 0 "register_operand" "")
8731 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8732 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8733 (clobber (match_scratch:SI 3 ""))
8734 (clobber (match_scratch:SI 4 ""))]
8735 "TARGET_SH2 && reload_completed"
8736 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8737 (parallel [(set (match_dup 0)
8738 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8739 (label_ref (match_dup 2))] UNSPEC_CASESI))
8740 (clobber (match_dup 3))])]
8741 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8743 (define_insn "casesi_worker_1"
8744 [(set (match_operand:SI 0 "register_operand" "=r,r")
8745 (unspec:SI [(reg:SI R0_REG)
8746 (match_operand:SI 1 "register_operand" "0,r")
8747 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8748 (clobber (match_scratch:SI 3 "=X,1"))]
8752 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8754 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8756 switch (GET_MODE (diff_vec))
8759 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8761 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8763 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8764 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8765 return \"mov.b @(r0,%1),%0\";
8770 [(set_attr "length" "4")])
8772 (define_insn "casesi_worker_2"
8773 [(set (match_operand:SI 0 "register_operand" "=r,r")
8774 (unspec:SI [(reg:SI R0_REG)
8775 (match_operand:SI 1 "register_operand" "0,r")
8776 (label_ref (match_operand 2 "" ""))
8777 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8778 (clobber (match_operand:SI 4 "" "=X,1"))]
8779 "TARGET_SH2 && reload_completed && flag_pic"
8782 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8785 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8787 switch (GET_MODE (diff_vec))
8790 output_asm_insn (\"shll2 %1\", operands);
8791 load = \"mov.l @(r0,%1),%0\"; break;
8793 output_asm_insn (\"add %1,%1\", operands);
8794 load = \"mov.w @(r0,%1),%0\"; break;
8796 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8797 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8799 load = \"mov.b @(r0,%1),%0\";
8804 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8807 [(set_attr "length" "8")])
8809 (define_insn "casesi_shift_media"
8810 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8811 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8812 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8817 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8819 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8821 switch (GET_MODE (diff_vec))
8824 return \"shlli %1, 2, %0\";
8826 return \"shlli %1, 1, %0\";
8828 if (rtx_equal_p (operands[0], operands[1]))
8830 return \"add %1, r63, %0\";
8835 [(set_attr "type" "arith_media")])
8837 (define_insn "casesi_load_media"
8838 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8839 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8840 (match_operand:DI 2 "arith_reg_operand" "r")
8841 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8845 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8847 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8849 switch (GET_MODE (diff_vec))
8852 return \"ldx.l %1, %2, %0\";
8855 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8856 return \"ldx.uw %1, %2, %0\";
8858 return \"ldx.w %1, %2, %0\";
8860 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8861 return \"ldx.ub %1, %2, %0\";
8862 return \"ldx.b %1, %2, %0\";
8867 [(set_attr "type" "load_media")])
8869 (define_expand "return"
8871 "reload_completed && ! sh_need_epilogue ()"
8876 emit_jump_insn (gen_return_media ());
8880 if (TARGET_SHCOMPACT
8881 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8883 emit_jump_insn (gen_shcompact_return_tramp ());
8888 (define_insn "*return_i"
8890 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8891 && (current_function_args_info.call_cookie
8892 & CALL_COOKIE_RET_TRAMP (1)))
8894 && lookup_attribute (\"trap_exit\",
8895 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8897 [(set_attr "type" "return")
8898 (set_attr "needs_delay_slot" "yes")])
8900 ;; trapa has no delay slot.
8901 (define_insn "*return_trapa"
8903 "TARGET_SH1 && !TARGET_SHCOMPACT
8904 && reload_completed"
8906 [(set_attr "type" "return")])
8908 (define_expand "shcompact_return_tramp"
8911 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8914 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8916 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8917 emit_jump_insn (gen_shcompact_return_tramp_i ());
8921 (define_insn "shcompact_return_tramp_i"
8922 [(parallel [(return) (use (reg:SI R0_REG))])]
8924 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8926 [(set_attr "type" "jump_ind")
8927 (set_attr "needs_delay_slot" "yes")])
8929 (define_insn "return_media_i"
8930 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8931 "TARGET_SHMEDIA && reload_completed"
8933 [(set_attr "type" "jump_media")])
8935 (define_insn "return_media_rte"
8937 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8939 [(set_attr "type" "jump_media")])
8941 (define_expand "return_media"
8943 "TARGET_SHMEDIA && reload_completed"
8946 int tr_regno = sh_media_register_for_return ();
8949 if (current_function_interrupt)
8951 emit_jump_insn (gen_return_media_rte ());
8956 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8958 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8960 tr = gen_rtx_REG (Pmode, tr_regno);
8961 emit_move_insn (tr, r18);
8964 tr = gen_rtx_REG (Pmode, tr_regno);
8966 emit_jump_insn (gen_return_media_i (tr));
8970 (define_insn "shcompact_preserve_incoming_args"
8971 [(set (match_operand:SI 0 "register_operand" "+r")
8972 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8975 [(set_attr "length" "0")])
8977 (define_insn "shcompact_incoming_args"
8978 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8979 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8980 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8981 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8982 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8983 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8984 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8985 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8986 (set (mem:BLK (reg:SI MACL_REG))
8987 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8988 (use (reg:SI R0_REG))
8989 (clobber (reg:SI R0_REG))
8990 (clobber (reg:SI MACL_REG))
8991 (clobber (reg:SI MACH_REG))
8992 (clobber (reg:SI PR_REG))]
8995 [(set_attr "needs_delay_slot" "yes")])
8997 (define_insn "shmedia_save_restore_regs_compact"
8998 [(set (reg:SI SP_REG)
8999 (plus:SI (reg:SI SP_REG)
9000 (match_operand:SI 0 "immediate_operand" "i")))
9001 (use (reg:SI R0_REG))
9002 (clobber (reg:SI PR_REG))]
9004 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9005 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9007 [(set_attr "needs_delay_slot" "yes")])
9009 (define_expand "prologue"
9012 "sh_expand_prologue (); DONE;")
9014 (define_expand "epilogue"
9019 sh_expand_epilogue (0);
9020 emit_jump_insn (gen_return ());
9024 (define_expand "eh_return"
9025 [(use (match_operand 0 "register_operand" ""))]
9028 rtx ra = operands[0];
9030 if (TARGET_SHMEDIA64)
9031 emit_insn (gen_eh_set_ra_di (ra));
9033 emit_insn (gen_eh_set_ra_si (ra));
9038 ;; Clobber the return address on the stack. We can't expand this
9039 ;; until we know where it will be put in the stack frame.
9041 (define_insn "eh_set_ra_si"
9042 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9043 (clobber (match_scratch:SI 1 "=&r"))]
9044 "! TARGET_SHMEDIA64"
9047 (define_insn "eh_set_ra_di"
9048 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9049 (clobber (match_scratch:DI 1 "=&r"))]
9054 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9055 (clobber (match_scratch 1 ""))]
9060 sh_set_return_address (operands[0], operands[1]);
9064 (define_insn "blockage"
9065 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9068 [(set_attr "length" "0")])
9070 ;; ------------------------------------------------------------------------
9072 ;; ------------------------------------------------------------------------
9075 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9076 (eq:SI (reg:SI T_REG) (const_int 1)))]
9079 [(set_attr "type" "arith")])
9081 (define_expand "seq"
9082 [(set (match_operand:SI 0 "arith_reg_dest" "")
9089 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9090 if (sh_compare_op1 != const0_rtx)
9091 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9092 ? GET_MODE (sh_compare_op0)
9093 : GET_MODE (sh_compare_op1),
9095 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9097 if (GET_MODE (operands[0]) != SImode)
9098 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9100 switch (GET_MODE (sh_compare_op0))
9103 emit_insn (gen_cmpsieqsi_media (operands[0],
9104 sh_compare_op0, sh_compare_op1));
9108 emit_insn (gen_cmpsieqdi_media (operands[0],
9109 sh_compare_op0, sh_compare_op1));
9113 if (! TARGET_SHMEDIA_FPU)
9115 emit_insn (gen_cmpsieqsf_media (operands[0],
9116 sh_compare_op0, sh_compare_op1));
9120 if (! TARGET_SHMEDIA_FPU)
9122 emit_insn (gen_cmpsieqdf_media (operands[0],
9123 sh_compare_op0, sh_compare_op1));
9132 if (GET_MODE (operands[0]) != DImode)
9133 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9135 switch (GET_MODE (sh_compare_op0))
9138 emit_insn (gen_cmpeqsi_media (operands[0],
9139 sh_compare_op0, sh_compare_op1));
9143 emit_insn (gen_cmpeqdi_media (operands[0],
9144 sh_compare_op0, sh_compare_op1));
9148 if (! TARGET_SHMEDIA_FPU)
9150 emit_insn (gen_cmpeqsf_media (operands[0],
9151 sh_compare_op0, sh_compare_op1));
9155 if (! TARGET_SHMEDIA_FPU)
9157 emit_insn (gen_cmpeqdf_media (operands[0],
9158 sh_compare_op0, sh_compare_op1));
9166 if (sh_expand_t_scc (EQ, operands[0]))
9168 if (! currently_expanding_to_rtl)
9170 operands[1] = prepare_scc_operands (EQ);
9173 (define_expand "slt"
9174 [(set (match_operand:SI 0 "arith_reg_operand" "")
9181 if (GET_MODE (operands[0]) != DImode)
9182 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9183 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9184 if (sh_compare_op1 != const0_rtx)
9185 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9186 ? GET_MODE (sh_compare_op0)
9187 : GET_MODE (sh_compare_op1),
9190 switch (GET_MODE (sh_compare_op0))
9193 emit_insn (gen_cmpgtsi_media (operands[0],
9194 sh_compare_op1, sh_compare_op0));
9198 emit_insn (gen_cmpgtdi_media (operands[0],
9199 sh_compare_op1, sh_compare_op0));
9203 if (! TARGET_SHMEDIA_FPU)
9205 emit_insn (gen_cmpgtsf_media (operands[0],
9206 sh_compare_op1, sh_compare_op0));
9210 if (! TARGET_SHMEDIA_FPU)
9212 emit_insn (gen_cmpgtdf_media (operands[0],
9213 sh_compare_op1, sh_compare_op0));
9221 if (! currently_expanding_to_rtl)
9223 operands[1] = prepare_scc_operands (LT);
9226 (define_expand "sle"
9227 [(match_operand:SI 0 "arith_reg_operand" "")]
9231 rtx tmp = sh_compare_op0;
9235 if (GET_MODE (operands[0]) != DImode)
9236 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9237 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9238 if (sh_compare_op1 != const0_rtx)
9239 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9240 ? GET_MODE (sh_compare_op0)
9241 : GET_MODE (sh_compare_op1),
9244 switch (GET_MODE (sh_compare_op0))
9248 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9250 emit_insn (gen_cmpgtsi_media (tmp,
9251 sh_compare_op0, sh_compare_op1));
9252 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9258 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9260 emit_insn (gen_cmpgtdi_media (tmp,
9261 sh_compare_op0, sh_compare_op1));
9262 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9267 if (! TARGET_SHMEDIA_FPU)
9269 emit_insn (gen_cmpgesf_media (operands[0],
9270 sh_compare_op1, sh_compare_op0));
9274 if (! TARGET_SHMEDIA_FPU)
9276 emit_insn (gen_cmpgedf_media (operands[0],
9277 sh_compare_op1, sh_compare_op0));
9286 sh_compare_op0 = sh_compare_op1;
9287 sh_compare_op1 = tmp;
9288 emit_insn (gen_sge (operands[0]));
9292 (define_expand "sgt"
9293 [(set (match_operand:SI 0 "arith_reg_operand" "")
9300 if (GET_MODE (operands[0]) != DImode)
9301 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9302 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9303 if (sh_compare_op1 != const0_rtx)
9304 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9305 ? GET_MODE (sh_compare_op0)
9306 : GET_MODE (sh_compare_op1),
9309 switch (GET_MODE (sh_compare_op0))
9312 emit_insn (gen_cmpgtsi_media (operands[0],
9313 sh_compare_op0, sh_compare_op1));
9317 emit_insn (gen_cmpgtdi_media (operands[0],
9318 sh_compare_op0, sh_compare_op1));
9322 if (! TARGET_SHMEDIA_FPU)
9324 emit_insn (gen_cmpgtsf_media (operands[0],
9325 sh_compare_op0, sh_compare_op1));
9329 if (! TARGET_SHMEDIA_FPU)
9331 emit_insn (gen_cmpgtdf_media (operands[0],
9332 sh_compare_op0, sh_compare_op1));
9340 if (! currently_expanding_to_rtl)
9342 operands[1] = prepare_scc_operands (GT);
9345 (define_expand "sge"
9346 [(set (match_operand:SI 0 "arith_reg_operand" "")
9353 enum machine_mode mode = GET_MODE (sh_compare_op0);
9355 if ((mode) == VOIDmode)
9356 mode = GET_MODE (sh_compare_op1);
9357 if (GET_MODE (operands[0]) != DImode)
9358 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9359 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9360 if (sh_compare_op1 != const0_rtx)
9361 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9367 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9369 emit_insn (gen_cmpgtsi_media (tmp,
9370 sh_compare_op1, sh_compare_op0));
9371 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9377 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9379 emit_insn (gen_cmpgtdi_media (tmp,
9380 sh_compare_op1, sh_compare_op0));
9381 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9386 if (! TARGET_SHMEDIA_FPU)
9388 emit_insn (gen_cmpgesf_media (operands[0],
9389 sh_compare_op0, sh_compare_op1));
9393 if (! TARGET_SHMEDIA_FPU)
9395 emit_insn (gen_cmpgedf_media (operands[0],
9396 sh_compare_op0, sh_compare_op1));
9405 if (! currently_expanding_to_rtl)
9407 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9411 rtx lab = gen_label_rtx ();
9412 prepare_scc_operands (EQ);
9413 emit_jump_insn (gen_branch_true (lab));
9414 prepare_scc_operands (GT);
9416 emit_insn (gen_movt (operands[0]));
9419 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9422 operands[1] = prepare_scc_operands (GE);
9425 (define_expand "sgtu"
9426 [(set (match_operand:SI 0 "arith_reg_operand" "")
9433 if (GET_MODE (operands[0]) != DImode)
9434 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9435 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9436 if (sh_compare_op1 != const0_rtx)
9437 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9438 ? GET_MODE (sh_compare_op0)
9439 : GET_MODE (sh_compare_op1),
9442 emit_insn (gen_cmpgtudi_media (operands[0],
9443 sh_compare_op0, sh_compare_op1));
9446 if (! currently_expanding_to_rtl)
9448 operands[1] = prepare_scc_operands (GTU);
9451 (define_expand "sltu"
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_op1, sh_compare_op0));
9472 if (! currently_expanding_to_rtl)
9474 operands[1] = prepare_scc_operands (LTU);
9477 (define_expand "sleu"
9478 [(set (match_operand:SI 0 "arith_reg_operand" "")
9487 if (GET_MODE (operands[0]) != DImode)
9488 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9489 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9490 if (sh_compare_op1 != const0_rtx)
9491 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9492 ? GET_MODE (sh_compare_op0)
9493 : GET_MODE (sh_compare_op1),
9496 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9498 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9499 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9503 if (! currently_expanding_to_rtl)
9505 operands[1] = prepare_scc_operands (LEU);
9508 (define_expand "sgeu"
9509 [(set (match_operand:SI 0 "arith_reg_operand" "")
9518 if (GET_MODE (operands[0]) != DImode)
9519 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9520 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9521 if (sh_compare_op1 != const0_rtx)
9522 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9523 ? GET_MODE (sh_compare_op0)
9524 : GET_MODE (sh_compare_op1),
9527 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9529 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9530 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9535 if (! currently_expanding_to_rtl)
9537 operands[1] = prepare_scc_operands (GEU);
9540 ;; sne moves the complement of the T reg to DEST like this:
9544 ;; This is better than xoring compare result with 1 because it does
9545 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9548 (define_expand "sne"
9549 [(set (match_dup 2) (const_int -1))
9550 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9551 (neg:SI (plus:SI (match_dup 1)
9554 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9563 if (GET_MODE (operands[0]) != DImode)
9564 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9566 if (! TARGET_SHMEDIA_FPU
9567 && GET_MODE (sh_compare_op0) != DImode
9568 && GET_MODE (sh_compare_op0) != SImode)
9571 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9572 if (sh_compare_op1 != const0_rtx)
9573 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9574 ? GET_MODE (sh_compare_op0)
9575 : GET_MODE (sh_compare_op1),
9578 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9580 emit_insn (gen_seq (tmp));
9581 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9586 if (sh_expand_t_scc (NE, operands[0]))
9588 if (! currently_expanding_to_rtl)
9590 operands[1] = prepare_scc_operands (EQ);
9591 operands[2] = gen_reg_rtx (SImode);
9594 (define_expand "sunordered"
9595 [(set (match_operand:DI 0 "arith_reg_operand" "")
9596 (unordered:DI (match_dup 1) (match_dup 2)))]
9597 "TARGET_SHMEDIA_FPU"
9600 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9601 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9604 ;; Use the same trick for FP sle / sge
9606 ;; Apart from the constant use and the T setting, this is like movt,
9607 ;; except that it uses the logically negated value of T, i.e.
9608 ;; operand[0] := T ? 0 : 1.
9609 (define_expand "movnegt"
9610 [(set (match_dup 2) (const_int -1))
9611 (parallel [(set (match_operand 0 "" "")
9612 (neg:SI (plus:SI (match_dup 1)
9615 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9618 "operands[2] = gen_reg_rtx (SImode);")
9620 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9621 ;; This prevents a regression that occurred when we switched from xor to
9625 [(set (match_operand:SI 0 "arith_reg_dest" "")
9626 (plus:SI (reg:SI T_REG)
9629 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9630 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9633 ;; -------------------------------------------------------------------------
9634 ;; Instructions to cope with inline literal tables
9635 ;; -------------------------------------------------------------------------
9637 ; 2 byte integer in line
9639 (define_insn "consttable_2"
9640 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9641 (match_operand 1 "" "")]
9646 if (operands[1] != const0_rtx)
9647 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9650 [(set_attr "length" "2")
9651 (set_attr "in_delay_slot" "no")])
9653 ; 4 byte integer in line
9655 (define_insn "consttable_4"
9656 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9657 (match_operand 1 "" "")]
9662 if (operands[1] != const0_rtx)
9663 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9666 [(set_attr "length" "4")
9667 (set_attr "in_delay_slot" "no")])
9669 ; 8 byte integer in line
9671 (define_insn "consttable_8"
9672 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9673 (match_operand 1 "" "")]
9678 if (operands[1] != const0_rtx)
9679 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9682 [(set_attr "length" "8")
9683 (set_attr "in_delay_slot" "no")])
9685 ; 4 byte floating point
9687 (define_insn "consttable_sf"
9688 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9689 (match_operand 1 "" "")]
9694 if (operands[1] != const0_rtx)
9697 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9698 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9702 [(set_attr "length" "4")
9703 (set_attr "in_delay_slot" "no")])
9705 ; 8 byte floating point
9707 (define_insn "consttable_df"
9708 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9709 (match_operand 1 "" "")]
9714 if (operands[1] != const0_rtx)
9717 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9718 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9722 [(set_attr "length" "8")
9723 (set_attr "in_delay_slot" "no")])
9725 ;; Alignment is needed for some constant tables; it may also be added for
9726 ;; Instructions at the start of loops, or after unconditional branches.
9727 ;; ??? We would get more accurate lengths if we did instruction
9728 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9729 ;; here is too conservative.
9731 ; align to a two byte boundary
9733 (define_expand "align_2"
9734 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9738 ; align to a four byte boundary
9739 ;; align_4 and align_log are instructions for the starts of loops, or
9740 ;; after unconditional branches, which may take up extra room.
9742 (define_expand "align_4"
9743 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9747 ; align to a cache line boundary
9749 (define_insn "align_log"
9750 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9753 [(set_attr "length" "0")
9754 (set_attr "in_delay_slot" "no")])
9756 ; emitted at the end of the literal table, used to emit the
9757 ; 32bit branch labels if needed.
9759 (define_insn "consttable_end"
9760 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9762 "* return output_jump_label_table ();"
9763 [(set_attr "in_delay_slot" "no")])
9765 ; emitted at the end of the window in the literal table.
9767 (define_insn "consttable_window_end"
9768 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9771 [(set_attr "length" "0")
9772 (set_attr "in_delay_slot" "no")])
9774 ;; -------------------------------------------------------------------------
9776 ;; -------------------------------------------------------------------------
9778 ;; String/block move insn.
9780 (define_expand "movmemsi"
9781 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9782 (mem:BLK (match_operand:BLK 1 "" "")))
9783 (use (match_operand:SI 2 "nonmemory_operand" ""))
9784 (use (match_operand:SI 3 "immediate_operand" ""))
9785 (clobber (reg:SI PR_REG))
9786 (clobber (reg:SI R4_REG))
9787 (clobber (reg:SI R5_REG))
9788 (clobber (reg:SI R0_REG))])]
9789 "TARGET_SH1 && ! TARGET_SH5"
9792 if(expand_block_move (operands))
9797 (define_insn "block_move_real"
9798 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9799 (mem:BLK (reg:SI R5_REG)))
9800 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9801 (clobber (reg:SI PR_REG))
9802 (clobber (reg:SI R0_REG))])]
9803 "TARGET_SH1 && ! TARGET_HARD_SH4"
9805 [(set_attr "type" "sfunc")
9806 (set_attr "needs_delay_slot" "yes")])
9808 (define_insn "block_lump_real"
9809 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9810 (mem:BLK (reg:SI R5_REG)))
9811 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9812 (use (reg:SI R6_REG))
9813 (clobber (reg:SI PR_REG))
9814 (clobber (reg:SI T_REG))
9815 (clobber (reg:SI R4_REG))
9816 (clobber (reg:SI R5_REG))
9817 (clobber (reg:SI R6_REG))
9818 (clobber (reg:SI R0_REG))])]
9819 "TARGET_SH1 && ! TARGET_HARD_SH4"
9821 [(set_attr "type" "sfunc")
9822 (set_attr "needs_delay_slot" "yes")])
9824 (define_insn "block_move_real_i4"
9825 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9826 (mem:BLK (reg:SI R5_REG)))
9827 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9828 (clobber (reg:SI PR_REG))
9829 (clobber (reg:SI R0_REG))
9830 (clobber (reg:SI R1_REG))
9831 (clobber (reg:SI R2_REG))])]
9834 [(set_attr "type" "sfunc")
9835 (set_attr "needs_delay_slot" "yes")])
9837 (define_insn "block_lump_real_i4"
9838 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9839 (mem:BLK (reg:SI R5_REG)))
9840 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9841 (use (reg:SI R6_REG))
9842 (clobber (reg:SI PR_REG))
9843 (clobber (reg:SI T_REG))
9844 (clobber (reg:SI R4_REG))
9845 (clobber (reg:SI R5_REG))
9846 (clobber (reg:SI R6_REG))
9847 (clobber (reg:SI R0_REG))
9848 (clobber (reg:SI R1_REG))
9849 (clobber (reg:SI R2_REG))
9850 (clobber (reg:SI R3_REG))])]
9853 [(set_attr "type" "sfunc")
9854 (set_attr "needs_delay_slot" "yes")])
9856 ;; -------------------------------------------------------------------------
9857 ;; Floating point instructions.
9858 ;; -------------------------------------------------------------------------
9860 ;; ??? All patterns should have a type attribute.
9862 (define_expand "movpsi"
9863 [(set (match_operand:PSI 0 "register_operand" "")
9864 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9865 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9868 ;; The c / m alternative is a fake to guide reload to load directly into
9869 ;; fpscr, since reload doesn't know how to use post-increment.
9870 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9871 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9872 ;; predicate after reload.
9873 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9874 ;; like a mac -> gpr move.
9875 (define_insn "fpu_switch"
9876 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9877 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9879 && (! reload_completed
9880 || true_regnum (operands[0]) != FPSCR_REG
9881 || GET_CODE (operands[1]) != MEM
9882 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9884 ! precision stays the same
9893 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9894 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9897 [(set (reg:PSI FPSCR_REG)
9898 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9899 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9902 rtx fpscr, mem, new_insn;
9904 fpscr = SET_DEST (PATTERN (curr_insn));
9905 mem = SET_SRC (PATTERN (curr_insn));
9906 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9908 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9909 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9914 [(set (reg:PSI FPSCR_REG)
9915 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9916 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9917 && (flag_peephole2 ? flow2_completed : reload_completed)"
9920 rtx fpscr, mem, new_insn;
9922 fpscr = SET_DEST (PATTERN (curr_insn));
9923 mem = SET_SRC (PATTERN (curr_insn));
9924 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9926 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9927 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9929 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9930 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9934 ;; ??? This uses the fp unit, but has no type indicating that.
9935 ;; If we did that, this would either give a bogus latency or introduce
9936 ;; a bogus FIFO constraint.
9937 ;; Since this insn is currently only used for prologues/epilogues,
9938 ;; it is probably best to claim no function unit, which matches the
9940 (define_insn "toggle_sz"
9941 [(set (reg:PSI FPSCR_REG)
9942 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9943 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9945 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9947 ;; There's no way we can use it today, since optimize mode switching
9948 ;; doesn't enable us to know from which mode we're switching to the
9949 ;; mode it requests, to tell whether we can use a relative mode switch
9950 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9952 (define_insn "toggle_pr"
9953 [(set (reg:PSI FPSCR_REG)
9954 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9955 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9957 [(set_attr "type" "fp")])
9959 (define_expand "addsf3"
9960 [(set (match_operand:SF 0 "arith_reg_operand" "")
9961 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9962 (match_operand:SF 2 "arith_reg_operand" "")))]
9963 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9968 expand_sf_binop (&gen_addsf3_i, operands);
9973 (define_insn "*addsf3_media"
9974 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9975 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9976 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9977 "TARGET_SHMEDIA_FPU"
9979 [(set_attr "type" "fparith_media")])
9981 (define_insn_and_split "unary_sf_op"
9982 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9987 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9988 (match_operator:SF 2 "unary_float_operator"
9989 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9990 (parallel [(match_operand 4
9991 "const_int_operand" "n")]))]))
9992 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9993 "TARGET_SHMEDIA_FPU"
9995 "TARGET_SHMEDIA_FPU && reload_completed"
9996 [(set (match_dup 5) (match_dup 6))]
9999 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10000 rtx op1 = gen_rtx_REG (SFmode,
10001 (true_regnum (operands[1])
10002 + (INTVAL (operands[4]) ^ endian)));
10004 operands[7] = gen_rtx_REG (SFmode,
10005 (true_regnum (operands[0])
10006 + (INTVAL (operands[3]) ^ endian)));
10007 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10009 [(set_attr "type" "fparith_media")])
10011 (define_insn_and_split "binary_sf_op"
10012 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10017 (parallel [(match_operand 7 "const_int_operand" "n")]))
10018 (match_operator:SF 3 "binary_float_operator"
10019 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10020 (parallel [(match_operand 5
10021 "const_int_operand" "n")]))
10022 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10023 (parallel [(match_operand 6
10024 "const_int_operand" "n")]))]))
10025 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10026 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10028 "&& reload_completed"
10029 [(set (match_dup 8) (match_dup 9))]
10032 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10033 rtx op1 = gen_rtx_REG (SFmode,
10034 (true_regnum (operands[1])
10035 + (INTVAL (operands[5]) ^ endian)));
10036 rtx op2 = gen_rtx_REG (SFmode,
10037 (true_regnum (operands[2])
10038 + (INTVAL (operands[6]) ^ endian)));
10040 operands[8] = gen_rtx_REG (SFmode,
10041 (true_regnum (operands[0])
10042 + (INTVAL (operands[4]) ^ endian)));
10043 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10045 [(set_attr "type" "fparith_media")])
10047 (define_insn "addsf3_i"
10048 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10049 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10050 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10051 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10054 [(set_attr "type" "fp")
10055 (set_attr "fp_mode" "single")])
10057 (define_expand "subsf3"
10058 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10059 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10060 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10061 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10066 expand_sf_binop (&gen_subsf3_i, operands);
10071 (define_insn "*subsf3_media"
10072 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10073 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10074 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10075 "TARGET_SHMEDIA_FPU"
10076 "fsub.s %1, %2, %0"
10077 [(set_attr "type" "fparith_media")])
10079 (define_insn "subsf3_i"
10080 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10081 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10082 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10083 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10086 [(set_attr "type" "fp")
10087 (set_attr "fp_mode" "single")])
10089 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10090 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
10091 ;; mixed-precision SH4 targets. To allow it to be still generated for the
10092 ;; SH3E, we use a separate insn for SH3E mulsf3.
10094 (define_expand "mulsf3"
10095 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10096 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10097 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10098 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10101 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10102 expand_sf_binop (&gen_mulsf3_i4, operands);
10103 else if (TARGET_SH2E)
10104 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10105 if (! TARGET_SHMEDIA)
10109 (define_insn "*mulsf3_media"
10110 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10111 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10112 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10113 "TARGET_SHMEDIA_FPU"
10114 "fmul.s %1, %2, %0"
10115 [(set_attr "type" "fparith_media")])
10117 (define_insn "mulsf3_i4"
10118 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10119 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10120 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10121 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10124 [(set_attr "type" "fp")
10125 (set_attr "fp_mode" "single")])
10127 (define_insn "mulsf3_ie"
10128 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10129 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10130 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10131 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10133 [(set_attr "type" "fp")])
10135 (define_insn "mac_media"
10136 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10137 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10138 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10139 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10140 "TARGET_SHMEDIA_FPU"
10141 "fmac.s %1, %2, %0"
10142 [(set_attr "type" "fparith_media")])
10144 (define_insn "*macsf3"
10145 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10146 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10147 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10148 (match_operand:SF 3 "arith_reg_operand" "0")))
10149 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10150 "TARGET_SH2E && ! TARGET_SH4"
10152 [(set_attr "type" "fp")
10153 (set_attr "fp_mode" "single")])
10155 (define_expand "divsf3"
10156 [(set (match_operand:SF 0 "arith_reg_operand" "")
10157 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10158 (match_operand:SF 2 "arith_reg_operand" "")))]
10159 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10164 expand_sf_binop (&gen_divsf3_i, operands);
10169 (define_insn "*divsf3_media"
10170 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10171 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10172 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10173 "TARGET_SHMEDIA_FPU"
10174 "fdiv.s %1, %2, %0"
10175 [(set_attr "type" "fdiv_media")])
10177 (define_insn "divsf3_i"
10178 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10179 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10180 (match_operand:SF 2 "arith_reg_operand" "f")))
10181 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10184 [(set_attr "type" "fdiv")
10185 (set_attr "fp_mode" "single")])
10187 (define_insn "floatdisf2"
10188 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10189 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10190 "TARGET_SHMEDIA_FPU"
10192 [(set_attr "type" "fpconv_media")])
10194 (define_expand "floatsisf2"
10195 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10196 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10197 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10200 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10202 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10207 (define_insn "*floatsisf2_media"
10208 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10209 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10210 "TARGET_SHMEDIA_FPU"
10212 [(set_attr "type" "fpconv_media")])
10214 (define_insn "floatsisf2_i4"
10215 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10216 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10217 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10218 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10220 [(set_attr "type" "fp")
10221 (set_attr "fp_mode" "single")])
10223 (define_insn "*floatsisf2_ie"
10224 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10225 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10226 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10228 [(set_attr "type" "fp")])
10230 (define_insn "fix_truncsfdi2"
10231 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10232 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10233 "TARGET_SHMEDIA_FPU"
10235 [(set_attr "type" "fpconv_media")])
10237 (define_expand "fix_truncsfsi2"
10238 [(set (match_operand:SI 0 "fpul_operand" "=y")
10239 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10240 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10243 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10245 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10250 (define_insn "*fix_truncsfsi2_media"
10251 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10252 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10253 "TARGET_SHMEDIA_FPU"
10255 [(set_attr "type" "fpconv_media")])
10257 (define_insn "fix_truncsfsi2_i4"
10258 [(set (match_operand:SI 0 "fpul_operand" "=y")
10259 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10260 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10261 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10263 [(set_attr "type" "ftrc_s")
10264 (set_attr "fp_mode" "single")])
10266 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10267 ;; fix_truncsfsi2_i4.
10268 ;; (define_insn "fix_truncsfsi2_i4_2"
10269 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10270 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10271 ;; (use (reg:PSI FPSCR_REG))
10272 ;; (clobber (reg:SI FPUL_REG))]
10275 ;; [(set_attr "length" "4")
10276 ;; (set_attr "fp_mode" "single")])
10279 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10280 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10281 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10282 ;; (clobber (reg:SI FPUL_REG))]
10284 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10285 ;; (use (match_dup 2))])
10286 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10288 (define_insn "*fixsfsi"
10289 [(set (match_operand:SI 0 "fpul_operand" "=y")
10290 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10291 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10293 [(set_attr "type" "fp")])
10295 (define_insn "cmpgtsf_t"
10296 [(set (reg:SI T_REG)
10297 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10298 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10299 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10301 [(set_attr "type" "fp")
10302 (set_attr "fp_mode" "single")])
10304 (define_insn "cmpeqsf_t"
10305 [(set (reg:SI T_REG)
10306 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10307 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10308 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10310 [(set_attr "type" "fp")
10311 (set_attr "fp_mode" "single")])
10313 (define_insn "ieee_ccmpeqsf_t"
10314 [(set (reg:SI T_REG)
10315 (ior:SI (reg:SI T_REG)
10316 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10317 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10318 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10319 "* return output_ieee_ccmpeq (insn, operands);"
10320 [(set_attr "length" "4")])
10323 (define_insn "cmpgtsf_t_i4"
10324 [(set (reg:SI T_REG)
10325 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10326 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10327 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10328 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10330 [(set_attr "type" "fp")
10331 (set_attr "fp_mode" "single")])
10333 (define_insn "cmpeqsf_t_i4"
10334 [(set (reg:SI T_REG)
10335 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10336 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10337 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10338 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10340 [(set_attr "type" "fp")
10341 (set_attr "fp_mode" "single")])
10343 (define_insn "*ieee_ccmpeqsf_t_4"
10344 [(set (reg:SI T_REG)
10345 (ior:SI (reg:SI T_REG)
10346 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10347 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10348 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10349 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10350 "* return output_ieee_ccmpeq (insn, operands);"
10351 [(set_attr "length" "4")
10352 (set_attr "fp_mode" "single")])
10354 (define_insn "cmpeqsf_media"
10355 [(set (match_operand:DI 0 "register_operand" "=r")
10356 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10357 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10358 "TARGET_SHMEDIA_FPU"
10359 "fcmpeq.s %1, %2, %0"
10360 [(set_attr "type" "fcmp_media")])
10362 (define_insn "cmpsieqsf_media"
10363 [(set (match_operand:SI 0 "register_operand" "=r")
10364 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10365 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10366 "TARGET_SHMEDIA_FPU"
10367 "fcmpeq.s %1, %2, %0"
10368 [(set_attr "type" "fcmp_media")])
10370 (define_insn "cmpgtsf_media"
10371 [(set (match_operand:DI 0 "register_operand" "=r")
10372 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10373 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10374 "TARGET_SHMEDIA_FPU"
10375 "fcmpgt.s %1, %2, %0"
10376 [(set_attr "type" "fcmp_media")])
10378 (define_insn "cmpgesf_media"
10379 [(set (match_operand:DI 0 "register_operand" "=r")
10380 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10381 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10382 "TARGET_SHMEDIA_FPU"
10383 "fcmpge.s %1, %2, %0"
10384 [(set_attr "type" "fcmp_media")])
10386 (define_insn "cmpunsf_media"
10387 [(set (match_operand:DI 0 "register_operand" "=r")
10388 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10389 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10390 "TARGET_SHMEDIA_FPU"
10391 "fcmpun.s %1, %2, %0"
10392 [(set_attr "type" "fcmp_media")])
10394 (define_expand "cmpsf"
10395 [(set (reg:SI T_REG)
10396 (compare (match_operand:SF 0 "arith_operand" "")
10397 (match_operand:SF 1 "arith_operand" "")))]
10398 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10401 sh_compare_op0 = operands[0];
10402 sh_compare_op1 = operands[1];
10406 (define_expand "negsf2"
10407 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10408 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10409 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10414 expand_sf_unop (&gen_negsf2_i, operands);
10419 (define_insn "*negsf2_media"
10420 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10421 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10422 "TARGET_SHMEDIA_FPU"
10424 [(set_attr "type" "fmove_media")])
10426 (define_insn "negsf2_i"
10427 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10428 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10429 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10432 [(set_attr "type" "fmove")
10433 (set_attr "fp_mode" "single")])
10435 (define_expand "sqrtsf2"
10436 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10437 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10438 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10443 expand_sf_unop (&gen_sqrtsf2_i, operands);
10448 (define_insn "*sqrtsf2_media"
10449 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10450 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10451 "TARGET_SHMEDIA_FPU"
10453 [(set_attr "type" "fdiv_media")])
10455 (define_insn "sqrtsf2_i"
10456 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10457 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10458 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10461 [(set_attr "type" "fdiv")
10462 (set_attr "fp_mode" "single")])
10464 (define_insn "rsqrtsf2"
10465 [(set (match_operand:SF 0 "register_operand" "=f")
10466 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10467 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10468 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10469 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10470 && operands[1] == CONST1_RTX (SFmode)"
10472 [(set_attr "type" "fsrra")
10473 (set_attr "fp_mode" "single")])
10475 (define_insn "fsca"
10476 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10478 (unspec:SF [(mult:SF
10479 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10480 (match_operand:SF 2 "immediate_operand" "i"))
10482 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10484 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10485 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10486 && operands[2] == sh_fsca_int2sf ()"
10488 [(set_attr "type" "fsca")
10489 (set_attr "fp_mode" "single")])
10491 (define_expand "sinsf2"
10492 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10493 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10495 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10498 rtx scaled = gen_reg_rtx (SFmode);
10499 rtx truncated = gen_reg_rtx (SImode);
10500 rtx fsca = gen_reg_rtx (V2SFmode);
10501 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10503 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10504 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10505 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10506 get_fpscr_rtx ()));
10507 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10511 (define_expand "cossf2"
10512 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10513 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10515 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10518 rtx scaled = gen_reg_rtx (SFmode);
10519 rtx truncated = gen_reg_rtx (SImode);
10520 rtx fsca = gen_reg_rtx (V2SFmode);
10521 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10523 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10524 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10525 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10526 get_fpscr_rtx ()));
10527 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10531 (define_expand "sindf2"
10532 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10533 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10535 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10538 rtx scaled = gen_reg_rtx (DFmode);
10539 rtx truncated = gen_reg_rtx (SImode);
10540 rtx fsca = gen_reg_rtx (V2SFmode);
10541 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10542 rtx sfresult = gen_reg_rtx (SFmode);
10544 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10545 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10546 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10547 get_fpscr_rtx ()));
10548 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10549 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10553 (define_expand "cosdf2"
10554 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10555 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10557 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10560 rtx scaled = gen_reg_rtx (DFmode);
10561 rtx truncated = gen_reg_rtx (SImode);
10562 rtx fsca = gen_reg_rtx (V2SFmode);
10563 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10564 rtx sfresult = gen_reg_rtx (SFmode);
10566 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10567 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10568 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10569 get_fpscr_rtx ()));
10570 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10571 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10575 (define_expand "abssf2"
10576 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10577 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10578 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10583 expand_sf_unop (&gen_abssf2_i, operands);
10588 (define_insn "*abssf2_media"
10589 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10590 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10591 "TARGET_SHMEDIA_FPU"
10593 [(set_attr "type" "fmove_media")])
10595 (define_insn "abssf2_i"
10596 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10597 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10598 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10601 [(set_attr "type" "fmove")
10602 (set_attr "fp_mode" "single")])
10604 (define_expand "adddf3"
10605 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10606 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10607 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10608 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10611 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10613 expand_df_binop (&gen_adddf3_i, operands);
10618 (define_insn "*adddf3_media"
10619 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10620 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10621 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10622 "TARGET_SHMEDIA_FPU"
10623 "fadd.d %1, %2, %0"
10624 [(set_attr "type" "dfparith_media")])
10626 (define_insn "adddf3_i"
10627 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10628 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10629 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10630 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10631 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10633 [(set_attr "type" "dfp_arith")
10634 (set_attr "fp_mode" "double")])
10636 (define_expand "subdf3"
10637 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10638 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10639 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10640 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10643 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10645 expand_df_binop (&gen_subdf3_i, operands);
10650 (define_insn "*subdf3_media"
10651 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10652 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10653 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10654 "TARGET_SHMEDIA_FPU"
10655 "fsub.d %1, %2, %0"
10656 [(set_attr "type" "dfparith_media")])
10658 (define_insn "subdf3_i"
10659 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10660 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10661 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10662 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10663 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10665 [(set_attr "type" "dfp_arith")
10666 (set_attr "fp_mode" "double")])
10668 (define_expand "muldf3"
10669 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10670 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10671 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10672 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10675 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10677 expand_df_binop (&gen_muldf3_i, operands);
10682 (define_insn "*muldf3_media"
10683 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10684 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10685 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10686 "TARGET_SHMEDIA_FPU"
10687 "fmul.d %1, %2, %0"
10688 [(set_attr "type" "dfmul_media")])
10690 (define_insn "muldf3_i"
10691 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10692 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10693 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10694 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10695 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10697 [(set_attr "type" "dfp_arith")
10698 (set_attr "fp_mode" "double")])
10700 (define_expand "divdf3"
10701 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10702 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10703 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10704 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10707 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10709 expand_df_binop (&gen_divdf3_i, operands);
10714 (define_insn "*divdf3_media"
10715 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10716 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10717 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10718 "TARGET_SHMEDIA_FPU"
10719 "fdiv.d %1, %2, %0"
10720 [(set_attr "type" "dfdiv_media")])
10722 (define_insn "divdf3_i"
10723 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10724 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10725 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10726 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10727 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10729 [(set_attr "type" "dfdiv")
10730 (set_attr "fp_mode" "double")])
10732 (define_insn "floatdidf2"
10733 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10734 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10735 "TARGET_SHMEDIA_FPU"
10737 [(set_attr "type" "dfpconv_media")])
10739 (define_expand "floatsidf2"
10740 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10741 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10742 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10745 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10747 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10748 get_fpscr_rtx ()));
10753 (define_insn "*floatsidf2_media"
10754 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10755 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10756 "TARGET_SHMEDIA_FPU"
10758 [(set_attr "type" "dfpconv_media")])
10760 (define_insn "floatsidf2_i"
10761 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10762 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10763 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10764 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10766 [(set_attr "type" "dfp_conv")
10767 (set_attr "fp_mode" "double")])
10769 (define_insn "fix_truncdfdi2"
10770 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10771 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10772 "TARGET_SHMEDIA_FPU"
10774 [(set_attr "type" "dfpconv_media")])
10776 (define_expand "fix_truncdfsi2"
10777 [(set (match_operand:SI 0 "fpul_operand" "")
10778 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10779 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10782 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10784 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10785 get_fpscr_rtx ()));
10790 (define_insn "*fix_truncdfsi2_media"
10791 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10792 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10793 "TARGET_SHMEDIA_FPU"
10795 [(set_attr "type" "dfpconv_media")])
10797 (define_insn "fix_truncdfsi2_i"
10798 [(set (match_operand:SI 0 "fpul_operand" "=y")
10799 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10800 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10801 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10803 [(set_attr "type" "dfp_conv")
10804 (set_attr "dfp_comp" "no")
10805 (set_attr "fp_mode" "double")])
10807 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10808 ;; fix_truncdfsi2_i.
10809 ;; (define_insn "fix_truncdfsi2_i4"
10810 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10811 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10812 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10813 ;; (clobber (reg:SI FPUL_REG))]
10816 ;; [(set_attr "length" "4")
10817 ;; (set_attr "fp_mode" "double")])
10820 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10821 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10822 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10823 ;; (clobber (reg:SI FPUL_REG))]
10825 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10826 ;; (use (match_dup 2))])
10827 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10829 (define_insn "cmpgtdf_t"
10830 [(set (reg:SI T_REG)
10831 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10832 (match_operand:DF 1 "arith_reg_operand" "f")))
10833 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10834 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10836 [(set_attr "type" "dfp_cmp")
10837 (set_attr "fp_mode" "double")])
10839 (define_insn "cmpeqdf_t"
10840 [(set (reg:SI T_REG)
10841 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10842 (match_operand:DF 1 "arith_reg_operand" "f")))
10843 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10844 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10846 [(set_attr "type" "dfp_cmp")
10847 (set_attr "fp_mode" "double")])
10849 (define_insn "*ieee_ccmpeqdf_t"
10850 [(set (reg:SI T_REG)
10851 (ior:SI (reg:SI T_REG)
10852 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10853 (match_operand:DF 1 "arith_reg_operand" "f"))))
10854 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10855 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10856 "* return output_ieee_ccmpeq (insn, operands);"
10857 [(set_attr "length" "4")
10858 (set_attr "fp_mode" "double")])
10860 (define_insn "cmpeqdf_media"
10861 [(set (match_operand:DI 0 "register_operand" "=r")
10862 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10863 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10864 "TARGET_SHMEDIA_FPU"
10865 "fcmpeq.d %1,%2,%0"
10866 [(set_attr "type" "fcmp_media")])
10868 (define_insn "cmpsieqdf_media"
10869 [(set (match_operand:SI 0 "register_operand" "=r")
10870 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10871 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10872 "TARGET_SHMEDIA_FPU"
10873 "fcmpeq.d %1,%2,%0"
10874 [(set_attr "type" "fcmp_media")])
10876 (define_insn "cmpgtdf_media"
10877 [(set (match_operand:DI 0 "register_operand" "=r")
10878 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10879 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10880 "TARGET_SHMEDIA_FPU"
10881 "fcmpgt.d %1,%2,%0"
10882 [(set_attr "type" "fcmp_media")])
10884 (define_insn "cmpgedf_media"
10885 [(set (match_operand:DI 0 "register_operand" "=r")
10886 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10887 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10888 "TARGET_SHMEDIA_FPU"
10889 "fcmpge.d %1,%2,%0"
10890 [(set_attr "type" "fcmp_media")])
10892 (define_insn "cmpundf_media"
10893 [(set (match_operand:DI 0 "register_operand" "=r")
10894 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10895 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10896 "TARGET_SHMEDIA_FPU"
10897 "fcmpun.d %1,%2,%0"
10898 [(set_attr "type" "fcmp_media")])
10900 (define_expand "cmpdf"
10901 [(set (reg:SI T_REG)
10902 (compare (match_operand:DF 0 "arith_operand" "")
10903 (match_operand:DF 1 "arith_operand" "")))]
10904 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10907 sh_compare_op0 = operands[0];
10908 sh_compare_op1 = operands[1];
10912 (define_expand "negdf2"
10913 [(set (match_operand:DF 0 "arith_reg_operand" "")
10914 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10918 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10920 expand_df_unop (&gen_negdf2_i, operands);
10925 (define_insn "*negdf2_media"
10926 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10927 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10928 "TARGET_SHMEDIA_FPU"
10930 [(set_attr "type" "fmove_media")])
10932 (define_insn "negdf2_i"
10933 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10934 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10935 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10936 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10938 [(set_attr "type" "fmove")
10939 (set_attr "fp_mode" "double")])
10941 (define_expand "sqrtdf2"
10942 [(set (match_operand:DF 0 "arith_reg_operand" "")
10943 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10944 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10947 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10949 expand_df_unop (&gen_sqrtdf2_i, operands);
10954 (define_insn "*sqrtdf2_media"
10955 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10956 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10957 "TARGET_SHMEDIA_FPU"
10959 [(set_attr "type" "dfdiv_media")])
10961 (define_insn "sqrtdf2_i"
10962 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10963 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10964 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10965 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10967 [(set_attr "type" "dfdiv")
10968 (set_attr "fp_mode" "double")])
10970 (define_expand "absdf2"
10971 [(set (match_operand:DF 0 "arith_reg_operand" "")
10972 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10973 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10976 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10978 expand_df_unop (&gen_absdf2_i, operands);
10983 (define_insn "*absdf2_media"
10984 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10985 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10986 "TARGET_SHMEDIA_FPU"
10988 [(set_attr "type" "fmove_media")])
10990 (define_insn "absdf2_i"
10991 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10992 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10993 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10994 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10996 [(set_attr "type" "fmove")
10997 (set_attr "fp_mode" "double")])
10999 (define_expand "extendsfdf2"
11000 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11001 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11002 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11005 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11007 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11008 get_fpscr_rtx ()));
11013 (define_insn "*extendsfdf2_media"
11014 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11015 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11016 "TARGET_SHMEDIA_FPU"
11018 [(set_attr "type" "dfpconv_media")])
11020 (define_insn "extendsfdf2_i4"
11021 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11022 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11023 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11024 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11026 [(set_attr "type" "fp")
11027 (set_attr "fp_mode" "double")])
11029 (define_expand "truncdfsf2"
11030 [(set (match_operand:SF 0 "fpul_operand" "")
11031 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11032 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11035 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11037 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11038 get_fpscr_rtx ()));
11043 (define_insn "*truncdfsf2_media"
11044 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11045 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11046 "TARGET_SHMEDIA_FPU"
11048 [(set_attr "type" "dfpconv_media")])
11050 (define_insn "truncdfsf2_i4"
11051 [(set (match_operand:SF 0 "fpul_operand" "=y")
11052 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11053 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11054 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11056 [(set_attr "type" "fp")
11057 (set_attr "fp_mode" "double")])
11059 ;; Bit field extract patterns. These give better code for packed bitfields,
11060 ;; because they allow auto-increment addresses to be generated.
11062 (define_expand "insv"
11063 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11064 (match_operand:SI 1 "immediate_operand" "")
11065 (match_operand:SI 2 "immediate_operand" ""))
11066 (match_operand:SI 3 "general_operand" ""))]
11067 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11070 rtx addr_target, orig_address, shift_reg, qi_val;
11071 HOST_WIDE_INT bitsize, size, v = 0;
11072 rtx x = operands[3];
11074 /* ??? expmed doesn't care for non-register predicates. */
11075 if (! memory_operand (operands[0], VOIDmode)
11076 || ! immediate_operand (operands[1], VOIDmode)
11077 || ! immediate_operand (operands[2], VOIDmode)
11078 || ! general_operand (x, VOIDmode))
11080 /* If this isn't a 16 / 24 / 32 bit field, or if
11081 it doesn't start on a byte boundary, then fail. */
11082 bitsize = INTVAL (operands[1]);
11083 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11084 || (INTVAL (operands[2]) % 8) != 0)
11087 size = bitsize / 8;
11088 orig_address = XEXP (operands[0], 0);
11089 shift_reg = gen_reg_rtx (SImode);
11090 if (GET_CODE (x) == CONST_INT)
11093 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11097 emit_insn (gen_movsi (shift_reg, operands[3]));
11098 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11100 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11102 operands[0] = replace_equiv_address (operands[0], addr_target);
11103 emit_insn (gen_movqi (operands[0], qi_val));
11107 if (GET_CODE (x) == CONST_INT)
11109 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11112 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11113 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11115 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11116 emit_insn (gen_movqi (operands[0], qi_val));
11122 (define_insn "movua"
11123 [(set (match_operand:SI 0 "register_operand" "=z")
11124 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11125 (const_int 32) (const_int 0)))]
11128 [(set_attr "type" "movua")])
11130 ;; We shouldn't need this, but cse replaces increments with references
11131 ;; to other regs before flow has a chance to create post_inc
11132 ;; addressing modes, and only postreload's cse_move2add brings the
11133 ;; increments back to a usable form.
11135 [(set (match_operand:SI 0 "register_operand" "")
11136 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11137 (const_int 32) (const_int 0)))
11138 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11139 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11140 [(set (match_operand:SI 0 "register_operand" "")
11141 (sign_extract:SI (mem:SI (post_inc:SI
11142 (match_operand:SI 1 "register_operand" "")))
11143 (const_int 32) (const_int 0)))]
11146 (define_expand "extv"
11147 [(set (match_operand:SI 0 "register_operand" "")
11148 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11149 (match_operand 2 "const_int_operand" "")
11150 (match_operand 3 "const_int_operand" "")))]
11153 if (TARGET_SH4A_ARCH
11154 && INTVAL (operands[2]) == 32
11155 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11156 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11158 emit_insn (gen_movua (operands[0],
11159 adjust_address (operands[1], SImode, 0)));
11166 (define_expand "extzv"
11167 [(set (match_operand:SI 0 "register_operand" "")
11168 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11169 (match_operand 2 "const_int_operand" "")
11170 (match_operand 3 "const_int_operand" "")))]
11173 if (TARGET_SH4A_ARCH
11174 && INTVAL (operands[2]) == 32
11175 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11176 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11178 emit_insn (gen_movua (operands[0],
11179 adjust_address (operands[1], SImode, 0)));
11187 ;; -------------------------------------------------------------------------
11189 ;; -------------------------------------------------------------------------
11191 ;; This matches cases where a stack pointer increment at the start of the
11192 ;; epilogue combines with a stack slot read loading the return value.
11195 [(set (match_operand:SI 0 "arith_reg_operand" "")
11196 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11197 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11198 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11201 ;; See the comment on the dt combiner pattern above.
11204 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11205 (plus:SI (match_dup 0)
11207 (set (reg:SI T_REG)
11208 (eq:SI (match_dup 0)
11213 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11214 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11215 ;; reload when the constant is too large for a reg+offset address.
11217 ;; ??? We would get much better code if this was done in reload. This would
11218 ;; require modifying find_reloads_address to recognize that if the constant
11219 ;; is out-of-range for an immediate add, then we get better code by reloading
11220 ;; the constant into a register than by reloading the sum into a register,
11221 ;; since the former is one instruction shorter if the address does not need
11222 ;; to be offsettable. Unfortunately this does not work, because there is
11223 ;; only one register, r0, that can be used as an index register. This register
11224 ;; is also the function return value register. So, if we try to force reload
11225 ;; to use double-reg addresses, then we end up with some instructions that
11226 ;; need to use r0 twice. The only way to fix this is to change the calling
11227 ;; convention so that r0 is not used to return values.
11230 [(set (match_operand:SI 0 "register_operand" "=r")
11231 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11232 (set (mem:SI (match_dup 0))
11233 (match_operand:SI 2 "general_movsrc_operand" ""))]
11234 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11235 "mov.l %2,@(%0,%1)")
11238 [(set (match_operand:SI 0 "register_operand" "=r")
11239 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11240 (set (match_operand:SI 2 "general_movdst_operand" "")
11241 (mem:SI (match_dup 0)))]
11242 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11243 "mov.l @(%0,%1),%2")
11246 [(set (match_operand:SI 0 "register_operand" "=r")
11247 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11248 (set (mem:HI (match_dup 0))
11249 (match_operand:HI 2 "general_movsrc_operand" ""))]
11250 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11251 "mov.w %2,@(%0,%1)")
11254 [(set (match_operand:SI 0 "register_operand" "=r")
11255 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11256 (set (match_operand:HI 2 "general_movdst_operand" "")
11257 (mem:HI (match_dup 0)))]
11258 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11259 "mov.w @(%0,%1),%2")
11262 [(set (match_operand:SI 0 "register_operand" "=r")
11263 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11264 (set (mem:QI (match_dup 0))
11265 (match_operand:QI 2 "general_movsrc_operand" ""))]
11266 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11267 "mov.b %2,@(%0,%1)")
11270 [(set (match_operand:SI 0 "register_operand" "=r")
11271 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11272 (set (match_operand:QI 2 "general_movdst_operand" "")
11273 (mem:QI (match_dup 0)))]
11274 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11275 "mov.b @(%0,%1),%2")
11278 [(set (match_operand:SI 0 "register_operand" "=r")
11279 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11280 (set (mem:SF (match_dup 0))
11281 (match_operand:SF 2 "general_movsrc_operand" ""))]
11282 "TARGET_SH1 && REGNO (operands[0]) == 0
11283 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11284 || (GET_CODE (operands[2]) == SUBREG
11285 && REGNO (SUBREG_REG (operands[2])) < 16))
11286 && reg_unused_after (operands[0], insn)"
11287 "mov.l %2,@(%0,%1)")
11290 [(set (match_operand:SI 0 "register_operand" "=r")
11291 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11292 (set (match_operand:SF 2 "general_movdst_operand" "")
11294 (mem:SF (match_dup 0)))]
11295 "TARGET_SH1 && REGNO (operands[0]) == 0
11296 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11297 || (GET_CODE (operands[2]) == SUBREG
11298 && REGNO (SUBREG_REG (operands[2])) < 16))
11299 && reg_unused_after (operands[0], insn)"
11300 "mov.l @(%0,%1),%2")
11303 [(set (match_operand:SI 0 "register_operand" "=r")
11304 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11305 (set (mem:SF (match_dup 0))
11306 (match_operand:SF 2 "general_movsrc_operand" ""))]
11307 "TARGET_SH2E && REGNO (operands[0]) == 0
11308 && ((GET_CODE (operands[2]) == REG
11309 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11310 || (GET_CODE (operands[2]) == SUBREG
11311 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11312 && reg_unused_after (operands[0], insn)"
11313 "fmov{.s|} %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_SH2E && REGNO (operands[0]) == 0
11322 && ((GET_CODE (operands[2]) == REG
11323 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11324 || (GET_CODE (operands[2]) == SUBREG
11325 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11326 && reg_unused_after (operands[0], insn)"
11327 "fmov{.s|} @(%0,%1),%2")
11329 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11330 (define_insn "sp_switch_1"
11331 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11335 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11336 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11337 return \"mov r0,r15\";
11339 [(set_attr "length" "10")])
11341 ;; Switch back to the original stack for interrupt functions with the
11342 ;; sp_switch attribute. */
11343 (define_insn "sp_switch_2"
11346 "mov.l @r15+,r15\;mov.l @r15+,r0"
11347 [(set_attr "length" "4")])
11349 ;; Integer vector moves
11351 (define_expand "movv8qi"
11352 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11353 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11355 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11357 (define_insn "movv8qi_i"
11358 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11359 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11361 && (register_operand (operands[0], V8QImode)
11362 || sh_register_operand (operands[1], V8QImode))"
11369 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11370 (set_attr "length" "4,4,16,4,4")])
11373 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11374 (subreg:V8QI (const_int 0) 0))]
11376 [(set (match_dup 0)
11377 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11378 (const_int 0) (const_int 0) (const_int 0)
11379 (const_int 0) (const_int 0)]))])
11382 [(set (match_operand 0 "arith_reg_dest" "")
11383 (match_operand 1 "sh_rep_vec" ""))]
11384 "TARGET_SHMEDIA && reload_completed
11385 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11386 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11387 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11388 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11389 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11390 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11391 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11392 [(set (match_dup 0) (match_dup 1))
11396 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11397 rtx elt1 = XVECEXP (operands[1], 0, 1);
11400 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11404 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11405 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11407 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11408 operands[1] = XVECEXP (operands[1], 0, 0);
11411 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11413 = GEN_INT (TARGET_LITTLE_ENDIAN
11414 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11415 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11418 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11420 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11426 [(set (match_operand 0 "arith_reg_dest" "")
11427 (match_operand 1 "sh_const_vec" ""))]
11428 "TARGET_SHMEDIA && reload_completed
11429 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11430 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11431 [(set (match_dup 0) (match_dup 1))]
11434 rtx v = operands[1];
11435 enum machine_mode new_mode
11436 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11438 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11440 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11443 (define_expand "movv2hi"
11444 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11445 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11447 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11449 (define_insn "movv2hi_i"
11450 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11451 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11453 && (register_operand (operands[0], V2HImode)
11454 || sh_register_operand (operands[1], V2HImode))"
11461 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11462 (set_attr "length" "4,4,16,4,4")
11463 (set (attr "highpart")
11464 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11465 (const_string "user")]
11466 (const_string "ignore")))])
11468 (define_expand "movv4hi"
11469 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11470 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11472 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11474 (define_insn "movv4hi_i"
11475 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11476 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11478 && (register_operand (operands[0], V4HImode)
11479 || sh_register_operand (operands[1], V4HImode))"
11486 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11487 (set_attr "length" "4,4,16,4,4")
11488 (set_attr "highpart" "depend")])
11490 (define_expand "movv2si"
11491 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11492 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11494 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11496 (define_insn "movv2si_i"
11497 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11498 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11500 && (register_operand (operands[0], V2SImode)
11501 || sh_register_operand (operands[1], V2SImode))"
11508 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11509 (set_attr "length" "4,4,16,4,4")
11510 (set_attr "highpart" "depend")])
11512 ;; Multimedia Intrinsics
11514 (define_insn "absv2si2"
11515 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11516 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11519 [(set_attr "type" "mcmp_media")
11520 (set_attr "highpart" "depend")])
11522 (define_insn "absv4hi2"
11523 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11524 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11527 [(set_attr "type" "mcmp_media")
11528 (set_attr "highpart" "depend")])
11530 (define_insn "addv2si3"
11531 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11532 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11533 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11535 "madd.l %1, %2, %0"
11536 [(set_attr "type" "arith_media")
11537 (set_attr "highpart" "depend")])
11539 (define_insn "addv4hi3"
11540 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11541 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11542 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11544 "madd.w %1, %2, %0"
11545 [(set_attr "type" "arith_media")
11546 (set_attr "highpart" "depend")])
11548 (define_insn_and_split "addv2hi3"
11549 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11550 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11551 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11558 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11559 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11560 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11561 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11562 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11564 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11565 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11568 [(set_attr "highpart" "must_split")])
11570 (define_insn "ssaddv2si3"
11571 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11572 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11573 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11575 "madds.l %1, %2, %0"
11576 [(set_attr "type" "mcmp_media")
11577 (set_attr "highpart" "depend")])
11579 (define_insn "usaddv8qi3"
11580 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11581 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11582 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11584 "madds.ub %1, %2, %0"
11585 [(set_attr "type" "mcmp_media")
11586 (set_attr "highpart" "depend")])
11588 (define_insn "ssaddv4hi3"
11589 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11590 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11591 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11593 "madds.w %1, %2, %0"
11594 [(set_attr "type" "mcmp_media")
11595 (set_attr "highpart" "depend")])
11597 (define_insn "negcmpeqv8qi"
11598 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11599 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11600 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11602 "mcmpeq.b %N1, %N2, %0"
11603 [(set_attr "type" "mcmp_media")
11604 (set_attr "highpart" "depend")])
11606 (define_insn "negcmpeqv2si"
11607 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11608 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11609 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11611 "mcmpeq.l %N1, %N2, %0"
11612 [(set_attr "type" "mcmp_media")
11613 (set_attr "highpart" "depend")])
11615 (define_insn "negcmpeqv4hi"
11616 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11617 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11618 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11620 "mcmpeq.w %N1, %N2, %0"
11621 [(set_attr "type" "mcmp_media")
11622 (set_attr "highpart" "depend")])
11624 (define_insn "negcmpgtuv8qi"
11625 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11626 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11627 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11629 "mcmpgt.ub %N1, %N2, %0"
11630 [(set_attr "type" "mcmp_media")
11631 (set_attr "highpart" "depend")])
11633 (define_insn "negcmpgtv2si"
11634 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11635 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11636 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11638 "mcmpgt.l %N1, %N2, %0"
11639 [(set_attr "type" "mcmp_media")
11640 (set_attr "highpart" "depend")])
11642 (define_insn "negcmpgtv4hi"
11643 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11644 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11645 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11647 "mcmpgt.w %N1, %N2, %0"
11648 [(set_attr "type" "mcmp_media")
11649 (set_attr "highpart" "depend")])
11651 (define_insn "mcmv"
11652 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11653 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11654 (match_operand:DI 2 "arith_reg_operand" "r"))
11655 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11656 (not:DI (match_dup 2)))))]
11659 [(set_attr "type" "arith_media")
11660 (set_attr "highpart" "depend")])
11662 (define_insn "mcnvs_lw"
11663 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11665 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11666 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11668 "mcnvs.lw %N1, %N2, %0"
11669 [(set_attr "type" "mcmp_media")])
11671 (define_insn "mcnvs_wb"
11672 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11674 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11675 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11677 "mcnvs.wb %N1, %N2, %0"
11678 [(set_attr "type" "mcmp_media")])
11680 (define_insn "mcnvs_wub"
11681 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11683 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11684 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11686 "mcnvs.wub %N1, %N2, %0"
11687 [(set_attr "type" "mcmp_media")])
11689 (define_insn "mextr_rl"
11690 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11691 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11692 (match_operand:HI 3 "mextr_bit_offset" "i"))
11693 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11694 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11695 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11698 static char templ[21];
11700 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11701 (int) INTVAL (operands[3]) >> 3);
11704 [(set_attr "type" "arith_media")])
11706 (define_insn "*mextr_lr"
11707 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11708 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11709 (match_operand:HI 3 "mextr_bit_offset" "i"))
11710 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11711 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11712 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11715 static char templ[21];
11717 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11718 (int) INTVAL (operands[4]) >> 3);
11721 [(set_attr "type" "arith_media")])
11723 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11724 ; vector then varies depending on endianness.
11725 (define_expand "mextr1"
11726 [(match_operand:DI 0 "arith_reg_dest" "")
11727 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11728 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11732 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11733 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11737 (define_expand "mextr2"
11738 [(match_operand:DI 0 "arith_reg_dest" "")
11739 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11740 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11744 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11745 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11749 (define_expand "mextr3"
11750 [(match_operand:DI 0 "arith_reg_dest" "")
11751 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11752 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11756 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11757 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11761 (define_expand "mextr4"
11762 [(match_operand:DI 0 "arith_reg_dest" "")
11763 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11764 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11768 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11769 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11773 (define_expand "mextr5"
11774 [(match_operand:DI 0 "arith_reg_dest" "")
11775 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11776 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11780 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11781 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11785 (define_expand "mextr6"
11786 [(match_operand:DI 0 "arith_reg_dest" "")
11787 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11788 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11792 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11793 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11797 (define_expand "mextr7"
11798 [(match_operand:DI 0 "arith_reg_dest" "")
11799 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11800 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11804 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11805 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11809 (define_expand "mmacfx_wl"
11810 [(match_operand:V2SI 0 "arith_reg_dest" "")
11811 (match_operand:V2HI 1 "extend_reg_operand" "")
11812 (match_operand:V2HI 2 "extend_reg_operand" "")
11813 (match_operand:V2SI 3 "arith_reg_operand" "")]
11817 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11818 operands[1], operands[2]));
11822 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11824 (define_insn "mmacfx_wl_i"
11825 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11827 (match_operand:V2SI 1 "arith_reg_operand" "0")
11832 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11833 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11836 "mmacfx.wl %2, %3, %0"
11837 [(set_attr "type" "mac_media")
11838 (set_attr "highpart" "depend")])
11840 (define_expand "mmacnfx_wl"
11841 [(match_operand:V2SI 0 "arith_reg_dest" "")
11842 (match_operand:V2HI 1 "extend_reg_operand" "")
11843 (match_operand:V2HI 2 "extend_reg_operand" "")
11844 (match_operand:V2SI 3 "arith_reg_operand" "")]
11848 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11849 operands[1], operands[2]));
11853 (define_insn "mmacnfx_wl_i"
11854 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11856 (match_operand:V2SI 1 "arith_reg_operand" "0")
11861 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11862 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11865 "mmacnfx.wl %2, %3, %0"
11866 [(set_attr "type" "mac_media")
11867 (set_attr "highpart" "depend")])
11869 (define_insn "mulv2si3"
11870 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11871 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11872 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11874 "mmul.l %1, %2, %0"
11875 [(set_attr "type" "d2mpy_media")
11876 (set_attr "highpart" "depend")])
11878 (define_insn "mulv4hi3"
11879 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11880 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11881 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11883 "mmul.w %1, %2, %0"
11884 [(set_attr "type" "dmpy_media")
11885 (set_attr "highpart" "depend")])
11887 (define_insn "mmulfx_l"
11888 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11892 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11893 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11896 "mmulfx.l %1, %2, %0"
11897 [(set_attr "type" "d2mpy_media")
11898 (set_attr "highpart" "depend")])
11900 (define_insn "mmulfx_w"
11901 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11905 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11906 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11909 "mmulfx.w %1, %2, %0"
11910 [(set_attr "type" "dmpy_media")
11911 (set_attr "highpart" "depend")])
11913 (define_insn "mmulfxrp_w"
11914 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11919 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11920 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11924 "mmulfxrp.w %1, %2, %0"
11925 [(set_attr "type" "dmpy_media")
11926 (set_attr "highpart" "depend")])
11929 (define_expand "mmulhi_wl"
11930 [(match_operand:V2SI 0 "arith_reg_dest" "")
11931 (match_operand:V4HI 1 "arith_reg_operand" "")
11932 (match_operand:V4HI 2 "arith_reg_operand" "")]
11936 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11937 (operands[0], operands[1], operands[2]));
11941 (define_expand "mmullo_wl"
11942 [(match_operand:V2SI 0 "arith_reg_dest" "")
11943 (match_operand:V4HI 1 "arith_reg_operand" "")
11944 (match_operand:V4HI 2 "arith_reg_operand" "")]
11948 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11949 (operands[0], operands[1], operands[2]));
11953 (define_insn "mmul23_wl"
11954 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11957 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11958 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11959 (parallel [(const_int 2) (const_int 3)])))]
11961 "* return (TARGET_LITTLE_ENDIAN
11962 ? \"mmulhi.wl %1, %2, %0\"
11963 : \"mmullo.wl %1, %2, %0\");"
11964 [(set_attr "type" "dmpy_media")
11965 (set (attr "highpart")
11966 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11967 (const_string "user")))])
11969 (define_insn "mmul01_wl"
11970 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11973 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11974 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11975 (parallel [(const_int 0) (const_int 1)])))]
11977 "* return (TARGET_LITTLE_ENDIAN
11978 ? \"mmullo.wl %1, %2, %0\"
11979 : \"mmulhi.wl %1, %2, %0\");"
11980 [(set_attr "type" "dmpy_media")
11981 (set (attr "highpart")
11982 (cond [(eq_attr "endian" "little") (const_string "ignore")]
11983 (const_string "user")))])
11986 (define_expand "mmulsum_wq"
11987 [(match_operand:DI 0 "arith_reg_dest" "")
11988 (match_operand:V4HI 1 "arith_reg_operand" "")
11989 (match_operand:V4HI 2 "arith_reg_operand" "")
11990 (match_operand:DI 3 "arith_reg_operand" "")]
11994 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11995 operands[1], operands[2]));
11999 (define_insn "mmulsum_wq_i"
12000 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12001 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12006 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12007 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12008 (parallel [(const_int 0)]))
12009 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12010 (sign_extend:V4DI (match_dup 3)))
12011 (parallel [(const_int 1)])))
12013 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12014 (sign_extend:V4DI (match_dup 3)))
12015 (parallel [(const_int 2)]))
12016 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12017 (sign_extend:V4DI (match_dup 3)))
12018 (parallel [(const_int 3)]))))))]
12020 "mmulsum.wq %2, %3, %0"
12021 [(set_attr "type" "mac_media")])
12023 (define_expand "mperm_w"
12024 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12025 (match_operand:V4HI 1 "arith_reg_operand" "r")
12026 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12030 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12031 (operands[0], operands[1], operands[2]));
12035 ; This use of vec_select isn't exactly correct according to rtl.texi
12036 ; (because not constant), but it seems a straightforward extension.
12037 (define_insn "mperm_w_little"
12038 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12040 (match_operand:V4HI 1 "arith_reg_operand" "r")
12042 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12043 (const_int 2) (const_int 0))
12044 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12045 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12046 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12047 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12048 "mperm.w %1, %N2, %0"
12049 [(set_attr "type" "arith_media")])
12051 (define_insn "mperm_w_big"
12052 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12054 (match_operand:V4HI 1 "arith_reg_operand" "r")
12056 [(zero_extract:QI (not:QI (match_operand:QI 2
12057 "extend_reg_or_0_operand" "rZ"))
12058 (const_int 2) (const_int 0))
12059 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12060 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12061 (zero_extract:QI (not:QI (match_dup 2))
12062 (const_int 2) (const_int 6))])))]
12063 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12064 "mperm.w %1, %N2, %0"
12065 [(set_attr "type" "arith_media")])
12067 (define_insn "mperm_w0"
12068 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12069 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12070 "trunc_hi_operand" "r"))))]
12072 "mperm.w %1, r63, %0"
12073 [(set_attr "type" "arith_media")
12074 (set_attr "highpart" "ignore")])
12076 (define_expand "msad_ubq"
12077 [(match_operand:DI 0 "arith_reg_dest" "")
12078 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12079 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12080 (match_operand:DI 3 "arith_reg_operand" "")]
12084 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12085 operands[1], operands[2]));
12089 (define_insn "msad_ubq_i"
12090 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12095 (match_operand:DI 1 "arith_reg_operand" "0")
12096 (abs:DI (vec_select:DI
12099 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12101 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12102 (parallel [(const_int 0)]))))
12103 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12104 (zero_extend:V8DI (match_dup 3)))
12105 (parallel [(const_int 1)]))))
12107 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12108 (zero_extend:V8DI (match_dup 3)))
12109 (parallel [(const_int 2)])))
12110 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12111 (zero_extend:V8DI (match_dup 3)))
12112 (parallel [(const_int 3)])))))
12115 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12116 (zero_extend:V8DI (match_dup 3)))
12117 (parallel [(const_int 4)])))
12118 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12119 (zero_extend:V8DI (match_dup 3)))
12120 (parallel [(const_int 5)]))))
12122 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12123 (zero_extend:V8DI (match_dup 3)))
12124 (parallel [(const_int 6)])))
12125 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12126 (zero_extend:V8DI (match_dup 3)))
12127 (parallel [(const_int 7)])))))))]
12129 "msad.ubq %N2, %N3, %0"
12130 [(set_attr "type" "mac_media")])
12132 (define_insn "mshalds_l"
12133 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12136 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12137 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12138 (const_int 31)))))]
12140 "mshalds.l %1, %2, %0"
12141 [(set_attr "type" "mcmp_media")
12142 (set_attr "highpart" "depend")])
12144 (define_insn "mshalds_w"
12145 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12148 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12149 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12150 (const_int 15)))))]
12152 "mshalds.w %1, %2, %0"
12153 [(set_attr "type" "mcmp_media")
12154 (set_attr "highpart" "depend")])
12156 (define_insn "ashrv2si3"
12157 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12158 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12159 (match_operand:DI 2 "arith_reg_operand" "r")))]
12161 "mshard.l %1, %2, %0"
12162 [(set_attr "type" "arith_media")
12163 (set_attr "highpart" "depend")])
12165 (define_insn "ashrv4hi3"
12166 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12167 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12168 (match_operand:DI 2 "arith_reg_operand" "r")))]
12170 "mshard.w %1, %2, %0"
12171 [(set_attr "type" "arith_media")
12172 (set_attr "highpart" "depend")])
12174 (define_insn "mshards_q"
12175 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12177 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12178 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12180 "mshards.q %1, %N2, %0"
12181 [(set_attr "type" "mcmp_media")])
12183 (define_expand "mshfhi_b"
12184 [(match_operand:V8QI 0 "arith_reg_dest" "")
12185 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12186 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12190 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12191 (operands[0], operands[1], operands[2]));
12195 (define_expand "mshflo_b"
12196 [(match_operand:V8QI 0 "arith_reg_dest" "")
12197 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12198 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12202 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12203 (operands[0], operands[1], operands[2]));
12207 (define_insn "mshf4_b"
12209 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12211 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12212 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12213 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12214 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12216 "* return (TARGET_LITTLE_ENDIAN
12217 ? \"mshfhi.b %N1, %N2, %0\"
12218 : \"mshflo.b %N1, %N2, %0\");"
12219 [(set_attr "type" "arith_media")
12220 (set (attr "highpart")
12221 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12222 (const_string "user")))])
12224 (define_insn "mshf0_b"
12226 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12228 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12229 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12230 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12231 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12233 "* return (TARGET_LITTLE_ENDIAN
12234 ? \"mshflo.b %N1, %N2, %0\"
12235 : \"mshfhi.b %N1, %N2, %0\");"
12236 [(set_attr "type" "arith_media")
12237 (set (attr "highpart")
12238 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12239 (const_string "user")))])
12241 (define_expand "mshfhi_l"
12242 [(match_operand:V2SI 0 "arith_reg_dest" "")
12243 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12244 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12248 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12249 (operands[0], operands[1], operands[2]));
12253 (define_expand "mshflo_l"
12254 [(match_operand:V2SI 0 "arith_reg_dest" "")
12255 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12256 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12260 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12261 (operands[0], operands[1], operands[2]));
12265 (define_insn "mshf4_l"
12266 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12268 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12269 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12270 (parallel [(const_int 1) (const_int 3)])))]
12272 "* return (TARGET_LITTLE_ENDIAN
12273 ? \"mshfhi.l %N1, %N2, %0\"
12274 : \"mshflo.l %N1, %N2, %0\");"
12275 [(set_attr "type" "arith_media")
12276 (set (attr "highpart")
12277 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12278 (const_string "user")))])
12280 (define_insn "mshf0_l"
12281 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12283 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12284 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12285 (parallel [(const_int 0) (const_int 2)])))]
12287 "* return (TARGET_LITTLE_ENDIAN
12288 ? \"mshflo.l %N1, %N2, %0\"
12289 : \"mshfhi.l %N1, %N2, %0\");"
12290 [(set_attr "type" "arith_media")
12291 (set (attr "highpart")
12292 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12293 (const_string "user")))])
12295 (define_expand "mshfhi_w"
12296 [(match_operand:V4HI 0 "arith_reg_dest" "")
12297 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12298 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12302 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12303 (operands[0], operands[1], operands[2]));
12307 (define_expand "mshflo_w"
12308 [(match_operand:V4HI 0 "arith_reg_dest" "")
12309 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12310 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12314 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12315 (operands[0], operands[1], operands[2]));
12319 (define_insn "mshf4_w"
12320 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12322 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12323 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12324 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12326 "* return (TARGET_LITTLE_ENDIAN
12327 ? \"mshfhi.w %N1, %N2, %0\"
12328 : \"mshflo.w %N1, %N2, %0\");"
12329 [(set_attr "type" "arith_media")
12330 (set (attr "highpart")
12331 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12332 (const_string "user")))])
12334 (define_insn "mshf0_w"
12335 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12337 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12338 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12339 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12341 "* return (TARGET_LITTLE_ENDIAN
12342 ? \"mshflo.w %N1, %N2, %0\"
12343 : \"mshfhi.w %N1, %N2, %0\");"
12344 [(set_attr "type" "arith_media")
12345 (set (attr "highpart")
12346 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12347 (const_string "user")))])
12349 (define_insn "mshflo_w_x"
12350 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12352 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12353 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12354 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12356 "mshflo.w %N1, %N2, %0"
12357 [(set_attr "type" "arith_media")
12358 (set_attr "highpart" "ignore")])
12360 /* These are useful to expand ANDs and as combiner patterns. */
12361 (define_insn_and_split "mshfhi_l_di"
12362 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12363 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12365 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12366 (const_int -4294967296))))]
12369 mshfhi.l %N1, %N2, %0
12371 "TARGET_SHMEDIA && reload_completed
12372 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12373 [(set (match_dup 3) (match_dup 4))
12374 (set (match_dup 5) (match_dup 6))]
12377 operands[3] = gen_lowpart (SImode, operands[0]);
12378 operands[4] = gen_highpart (SImode, operands[1]);
12379 operands[5] = gen_highpart (SImode, operands[0]);
12380 operands[6] = gen_highpart (SImode, operands[2]);
12382 [(set_attr "type" "arith_media")])
12384 (define_insn "*mshfhi_l_di_rev"
12385 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12386 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12387 (const_int -4294967296))
12388 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12391 "mshfhi.l %N2, %N1, %0"
12392 [(set_attr "type" "arith_media")])
12395 [(set (match_operand:DI 0 "arith_reg_dest" "")
12396 (ior:DI (zero_extend:DI (match_operand:SI 1
12397 "extend_reg_or_0_operand" ""))
12398 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12399 (const_int -4294967296))))
12400 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12405 emit_insn (gen_ashldi3_media (operands[3],
12406 simplify_gen_subreg (DImode, operands[1],
12409 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12413 (define_insn "mshflo_l_di"
12414 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12415 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12416 (const_int 4294967295))
12417 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12421 "mshflo.l %N1, %N2, %0"
12422 [(set_attr "type" "arith_media")
12423 (set_attr "highpart" "ignore")])
12425 (define_insn "*mshflo_l_di_rev"
12426 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12427 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12429 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12430 (const_int 4294967295))))]
12433 "mshflo.l %N2, %N1, %0"
12434 [(set_attr "type" "arith_media")
12435 (set_attr "highpart" "ignore")])
12437 ;; Combiner pattern for trampoline initialization.
12438 (define_insn_and_split "*double_shori"
12439 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12440 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12442 (match_operand:DI 2 "const_int_operand" "n")))]
12444 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12446 "rtx_equal_p (operands[0], operands[1])"
12450 HOST_WIDE_INT v = INTVAL (operands[2]);
12452 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12453 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12456 [(set_attr "highpart" "ignore")])
12459 (define_insn "*mshflo_l_di_x"
12460 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12461 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12463 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12467 "mshflo.l %N1, %N2, %0"
12468 [(set_attr "type" "arith_media")
12469 (set_attr "highpart" "ignore")])
12471 (define_insn_and_split "concat_v2sf"
12472 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12473 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12474 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12475 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12479 mshflo.l %N1, %N2, %0
12482 "TARGET_SHMEDIA && reload_completed
12483 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12484 [(set (match_dup 3) (match_dup 1))
12485 (set (match_dup 4) (match_dup 2))]
12488 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12489 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12491 [(set_attr "type" "arith_media")
12492 (set_attr "highpart" "ignore")])
12494 (define_insn "*mshflo_l_di_x_rev"
12495 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12496 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12498 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12501 "mshflo.l %N2, %N1, %0"
12502 [(set_attr "type" "arith_media")
12503 (set_attr "highpart" "ignore")])
12505 (define_insn "ashlv2si3"
12506 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12507 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12508 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12510 "mshlld.l %1, %2, %0"
12511 [(set_attr "type" "arith_media")
12512 (set_attr "highpart" "depend")])
12515 [(set (match_operand 0 "any_register_operand" "")
12516 (match_operator 3 "shift_operator"
12517 [(match_operand 1 "any_register_operand" "")
12518 (match_operand 2 "shift_count_reg_operand" "")]))]
12519 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12520 [(set (match_dup 0) (match_dup 3))]
12523 rtx count = operands[2];
12524 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12526 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12527 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12528 || GET_CODE (count) == TRUNCATE)
12529 count = XEXP (count, 0);
12530 inner_mode = GET_MODE (count);
12531 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12532 subreg_lowpart_offset (outer_mode, inner_mode));
12533 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12534 operands[1], count);
12537 (define_insn "ashlv4hi3"
12538 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12539 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12540 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12542 "mshlld.w %1, %2, %0"
12543 [(set_attr "type" "arith_media")
12544 (set_attr "highpart" "depend")])
12546 (define_insn "lshrv2si3"
12547 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12548 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12549 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12551 "mshlrd.l %1, %2, %0"
12552 [(set_attr "type" "arith_media")
12553 (set_attr "highpart" "depend")])
12555 (define_insn "lshrv4hi3"
12556 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12557 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12558 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12560 "mshlrd.w %1, %2, %0"
12561 [(set_attr "type" "arith_media")
12562 (set_attr "highpart" "depend")])
12564 (define_insn "subv2si3"
12565 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12566 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12567 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12569 "msub.l %N1, %2, %0"
12570 [(set_attr "type" "arith_media")
12571 (set_attr "highpart" "depend")])
12573 (define_insn "subv4hi3"
12574 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12575 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12576 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12578 "msub.w %N1, %2, %0"
12579 [(set_attr "type" "arith_media")
12580 (set_attr "highpart" "depend")])
12582 (define_insn_and_split "subv2hi3"
12583 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12584 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12585 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12592 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12593 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12594 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12595 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12596 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12598 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12599 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12602 [(set_attr "highpart" "must_split")])
12604 (define_insn "sssubv2si3"
12605 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12606 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12607 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12609 "msubs.l %N1, %2, %0"
12610 [(set_attr "type" "mcmp_media")
12611 (set_attr "highpart" "depend")])
12613 (define_insn "ussubv8qi3"
12614 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12615 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12616 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12618 "msubs.ub %N1, %2, %0"
12619 [(set_attr "type" "mcmp_media")
12620 (set_attr "highpart" "depend")])
12622 (define_insn "sssubv4hi3"
12623 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12624 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12625 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12627 "msubs.w %N1, %2, %0"
12628 [(set_attr "type" "mcmp_media")
12629 (set_attr "highpart" "depend")])
12631 ;; Floating Point Intrinsics
12633 (define_insn "fcosa_s"
12634 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12635 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12639 [(set_attr "type" "atrans_media")])
12641 (define_insn "fsina_s"
12642 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12643 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12647 [(set_attr "type" "atrans_media")])
12649 (define_insn "fipr"
12650 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12651 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12652 "fp_arith_reg_operand" "f")
12653 (match_operand:V4SF 2
12654 "fp_arith_reg_operand" "f"))
12655 (parallel [(const_int 0)]))
12656 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12657 (parallel [(const_int 1)])))
12658 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12659 (parallel [(const_int 2)]))
12660 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12661 (parallel [(const_int 3)])))))]
12663 "fipr.s %1, %2, %0"
12664 [(set_attr "type" "fparith_media")])
12666 (define_insn "fsrra_s"
12667 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12668 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12672 [(set_attr "type" "atrans_media")])
12674 (define_insn "ftrv"
12675 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12679 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12680 (parallel [(const_int 0) (const_int 5)
12681 (const_int 10) (const_int 15)]))
12682 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12684 (vec_select:V4SF (match_dup 1)
12685 (parallel [(const_int 4) (const_int 9)
12686 (const_int 14) (const_int 3)]))
12687 (vec_select:V4SF (match_dup 2)
12688 (parallel [(const_int 1) (const_int 2)
12689 (const_int 3) (const_int 0)]))))
12692 (vec_select:V4SF (match_dup 1)
12693 (parallel [(const_int 8) (const_int 13)
12694 (const_int 2) (const_int 7)]))
12695 (vec_select:V4SF (match_dup 2)
12696 (parallel [(const_int 2) (const_int 3)
12697 (const_int 0) (const_int 1)])))
12699 (vec_select:V4SF (match_dup 1)
12700 (parallel [(const_int 12) (const_int 1)
12701 (const_int 6) (const_int 11)]))
12702 (vec_select:V4SF (match_dup 2)
12703 (parallel [(const_int 3) (const_int 0)
12704 (const_int 1) (const_int 2)]))))))]
12706 "ftrv.s %1, %2, %0"
12707 [(set_attr "type" "fparith_media")])
12709 (define_insn "ldhi_l"
12710 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12712 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12715 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12719 [(set_attr "type" "load_media")])
12721 (define_insn "ldhi_q"
12722 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12724 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12727 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12731 [(set_attr "type" "load_media")])
12733 (define_insn_and_split "*ldhi_q_comb0"
12734 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12736 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12737 "register_operand" "r")
12738 (match_operand:SI 2
12739 "ua_offset" "I06"))
12742 (plus:SI (and:SI (match_dup 1) (const_int 7))
12745 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12749 "emit_insn (gen_ldhi_q (operands[0],
12750 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12754 (define_insn_and_split "*ldhi_q_comb1"
12755 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12757 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12758 "register_operand" "r")
12759 (match_operand:SI 2
12760 "ua_offset" "I06"))
12763 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12764 "ua_offset" "I06"))
12768 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12769 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12773 "emit_insn (gen_ldhi_q (operands[0],
12774 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12778 (define_insn "ldlo_l"
12779 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12781 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12783 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12784 (and:SI (match_dup 1) (const_int 3))))]
12787 [(set_attr "type" "load_media")])
12789 (define_insn "ldlo_q"
12790 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12792 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12794 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12795 (and:SI (match_dup 1) (const_int 7))))]
12798 [(set_attr "type" "load_media")])
12800 (define_insn_and_split "*ldlo_q_comb0"
12801 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12803 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12804 (match_operand:SI 2 "ua_offset" "I06"))
12806 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12807 (and:SI (match_dup 1) (const_int 7))))]
12808 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12812 "emit_insn (gen_ldlo_q (operands[0],
12813 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12816 (define_insn_and_split "*ldlo_q_comb1"
12817 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12819 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12820 (match_operand:SI 2 "ua_offset" "I06"))
12822 (minus:SI (const_int 8)
12823 (and:SI (plus:SI (match_dup 1)
12824 (match_operand:SI 3 "ua_offset" "I06"))
12826 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12827 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12828 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12832 "emit_insn (gen_ldlo_q (operands[0],
12833 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12836 (define_insn "sthi_l"
12837 [(set (zero_extract:SI
12838 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12841 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12843 (match_operand:SI 1 "arith_reg_operand" "r"))]
12846 [(set_attr "type" "ustore_media")])
12848 ;; All unaligned stores are considered to be 'narrow' because they typically
12849 ;; operate on less that a quadword, and when they operate on a full quadword,
12850 ;; the vanilla store high / store low sequence will cause a stall if not
12851 ;; scheduled apart.
12852 (define_insn "sthi_q"
12853 [(set (zero_extract:DI
12854 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12857 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12859 (match_operand:DI 1 "arith_reg_operand" "r"))]
12862 [(set_attr "type" "ustore_media")])
12864 (define_insn_and_split "*sthi_q_comb0"
12865 [(set (zero_extract:DI
12866 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12867 "register_operand" "r")
12868 (match_operand:SI 1 "ua_offset"
12872 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12874 (match_operand:DI 2 "arith_reg_operand" "r"))]
12875 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12879 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12883 (define_insn_and_split "*sthi_q_comb1"
12884 [(set (zero_extract:DI
12885 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12886 "register_operand" "r")
12887 (match_operand:SI 1 "ua_offset"
12891 (plus:SI (and:SI (plus:SI (match_dup 0)
12892 (match_operand:SI 2 "ua_offset" "I06"))
12896 (match_operand:DI 3 "arith_reg_operand" "r"))]
12897 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12898 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12902 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12906 ;; This is highpart user because the address is used as full 64 bit.
12907 (define_insn "stlo_l"
12908 [(set (zero_extract:SI
12909 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12911 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12912 (and:SI (match_dup 0) (const_int 3)))
12913 (match_operand:SI 1 "arith_reg_operand" "r"))]
12916 [(set_attr "type" "ustore_media")])
12918 (define_insn "stlo_q"
12919 [(set (zero_extract:DI
12920 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12922 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12923 (and:SI (match_dup 0) (const_int 7)))
12924 (match_operand:DI 1 "arith_reg_operand" "r"))]
12927 [(set_attr "type" "ustore_media")])
12929 (define_insn_and_split "*stlo_q_comb0"
12930 [(set (zero_extract:DI
12931 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12932 (match_operand:SI 1 "ua_offset" "I06"))
12934 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12935 (and:SI (match_dup 0) (const_int 7)))
12936 (match_operand:DI 2 "arith_reg_operand" "r"))]
12937 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12941 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12945 (define_insn_and_split "*stlo_q_comb1"
12946 [(set (zero_extract:DI
12947 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12948 (match_operand:SI 1 "ua_offset" "I06"))
12950 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12951 (match_operand:SI 2
12952 "ua_offset" "I06"))
12954 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12955 (match_operand:DI 3 "arith_reg_operand" "r"))]
12956 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12960 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12964 (define_insn "ldhi_l64"
12965 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12967 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12970 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12974 [(set_attr "type" "load_media")])
12976 (define_insn "ldhi_q64"
12977 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12979 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12982 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12986 [(set_attr "type" "load_media")])
12988 (define_insn "ldlo_l64"
12989 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12991 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12993 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12994 (and:DI (match_dup 1) (const_int 3))))]
12997 [(set_attr "type" "load_media")])
12999 (define_insn "ldlo_q64"
13000 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13002 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13004 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13005 (and:DI (match_dup 1) (const_int 7))))]
13008 [(set_attr "type" "load_media")])
13010 (define_insn "sthi_l64"
13011 [(set (zero_extract:SI
13012 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13015 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13017 (match_operand:SI 1 "arith_reg_operand" "r"))]
13020 [(set_attr "type" "ustore_media")])
13022 (define_insn "sthi_q64"
13023 [(set (zero_extract:DI
13024 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13027 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13029 (match_operand:DI 1 "arith_reg_operand" "r"))]
13032 [(set_attr "type" "ustore_media")])
13034 (define_insn "stlo_l64"
13035 [(set (zero_extract:SI
13036 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13038 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13039 (and:DI (match_dup 0) (const_int 3)))
13040 (match_operand:SI 1 "arith_reg_operand" "r"))]
13043 [(set_attr "type" "ustore_media")])
13045 (define_insn "stlo_q64"
13046 [(set (zero_extract:DI
13047 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13049 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13050 (and:DI (match_dup 0) (const_int 7)))
13051 (match_operand:DI 1 "arith_reg_operand" "r"))]
13054 [(set_attr "type" "ustore_media")])
13057 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13058 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13062 [(set_attr "type" "arith_media")])
13064 (define_insn "nsbsi"
13065 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13067 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13071 [(set_attr "type" "arith_media")])
13073 (define_insn "nsbdi"
13074 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13076 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13080 [(set_attr "type" "arith_media")])
13082 (define_expand "ffsdi2"
13083 [(set (match_operand:DI 0 "arith_reg_dest" "")
13084 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13088 rtx scratch = gen_reg_rtx (DImode);
13091 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13092 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13093 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13094 emit_insn (gen_nsbdi (scratch, scratch));
13095 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13096 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13097 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13099 = gen_rtx_EXPR_LIST (REG_EQUAL,
13100 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13104 (define_expand "ffssi2"
13105 [(set (match_operand:SI 0 "arith_reg_dest" "")
13106 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13110 rtx scratch = gen_reg_rtx (SImode);
13111 rtx discratch = gen_reg_rtx (DImode);
13114 emit_insn (gen_adddi3 (discratch,
13115 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13117 emit_insn (gen_andcdi3 (discratch,
13118 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13120 emit_insn (gen_nsbsi (scratch, discratch));
13121 last = emit_insn (gen_subsi3 (operands[0],
13122 force_reg (SImode, GEN_INT (63)), scratch));
13124 = gen_rtx_EXPR_LIST (REG_EQUAL,
13125 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13129 (define_insn "byterev"
13130 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13131 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13132 (parallel [(const_int 7) (const_int 6) (const_int 5)
13133 (const_int 4) (const_int 3) (const_int 2)
13134 (const_int 1) (const_int 0)])))]
13137 [(set_attr "type" "arith_media")])
13139 (define_insn "*prefetch_media"
13140 [(prefetch (match_operand:QI 0 "address_operand" "p")
13141 (match_operand:SI 1 "const_int_operand" "n")
13142 (match_operand:SI 2 "const_int_operand" "n"))]
13146 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13147 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13150 [(set_attr "type" "other")])
13152 (define_insn "*prefetch_i4"
13153 [(prefetch (match_operand:SI 0 "register_operand" "r")
13154 (match_operand:SI 1 "const_int_operand" "n")
13155 (match_operand:SI 2 "const_int_operand" "n"))]
13156 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13159 return \"pref @%0\";
13161 [(set_attr "type" "other")])
13163 (define_expand "prefetch"
13164 [(prefetch (match_operand 0 "address_operand" "p")
13165 (match_operand:SI 1 "const_int_operand" "n")
13166 (match_operand:SI 2 "const_int_operand" "n"))]
13167 "TARGET_HARD_SH4 || TARGET_SH5"
13170 if (GET_MODE (operands[0]) != Pmode
13171 || GET_CODE (operands[1]) != CONST_INT
13172 || GET_CODE (operands[2]) != CONST_INT)
13174 if (! TARGET_SHMEDIA)
13175 operands[0] = force_reg (Pmode, operands[0]);
13178 (define_insn "alloco_i"
13179 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13180 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13186 if (GET_CODE (operands[0]) == PLUS)
13188 xops[0] = XEXP (operands[0], 0);
13189 xops[1] = XEXP (operands[0], 1);
13193 xops[0] = operands[0];
13194 xops[1] = const0_rtx;
13196 output_asm_insn (\"alloco %0, %1\", xops);
13199 [(set_attr "type" "other")])
13202 [(set (match_operand 0 "any_register_operand" "")
13203 (match_operand 1 "" ""))]
13204 "TARGET_SHMEDIA && reload_completed"
13205 [(set (match_dup 0) (match_dup 1))]
13210 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13215 ; Stack Protector Patterns
13217 (define_expand "stack_protect_set"
13218 [(set (match_operand 0 "memory_operand" "")
13219 (match_operand 1 "memory_operand" ""))]
13222 if (TARGET_SHMEDIA)
13224 if (TARGET_SHMEDIA64)
13225 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13227 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13230 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13235 (define_insn "stack_protect_set_si"
13236 [(set (match_operand:SI 0 "memory_operand" "=m")
13237 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13238 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13240 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13241 [(set_attr "type" "other")
13242 (set_attr "length" "6")])
13244 (define_insn "stack_protect_set_si_media"
13245 [(set (match_operand:SI 0 "memory_operand" "=m")
13246 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13247 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13249 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13250 [(set_attr "type" "other")
13251 (set_attr "length" "12")])
13253 (define_insn "stack_protect_set_di_media"
13254 [(set (match_operand:DI 0 "memory_operand" "=m")
13255 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13256 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13258 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13259 [(set_attr "type" "other")
13260 (set_attr "length" "12")])
13262 (define_expand "stack_protect_test"
13263 [(match_operand 0 "memory_operand" "")
13264 (match_operand 1 "memory_operand" "")
13265 (match_operand 2 "" "")]
13268 if (TARGET_SHMEDIA)
13270 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13272 if (TARGET_SHMEDIA64)
13273 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13276 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13279 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13283 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13284 emit_jump_insn (gen_branch_true (operands[2]));
13290 (define_insn "stack_protect_test_si"
13291 [(set (reg:SI T_REG)
13292 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13293 (match_operand:SI 1 "memory_operand" "m")]
13295 (set (match_scratch:SI 2 "=&r") (const_int 0))
13296 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13298 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13299 [(set_attr "type" "other")
13300 (set_attr "length" "10")])
13302 (define_insn "stack_protect_test_si_media"
13303 [(set (match_operand:SI 0 "register_operand" "=&r")
13304 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13305 (match_operand:SI 2 "memory_operand" "m")]
13307 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13309 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13310 [(set_attr "type" "other")
13311 (set_attr "length" "16")])
13313 (define_insn "stack_protect_test_di_media"
13314 [(set (match_operand:DI 0 "register_operand" "=&r")
13315 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13316 (match_operand:DI 2 "memory_operand" "m")]
13318 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13320 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13321 [(set_attr "type" "other")
13322 (set_attr "length" "16")])