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 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1098 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1099 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1100 && (REGNO_REG_CLASS (REGNO (operands[0]))
1101 == REGNO_REG_CLASS (REGNO (operands[2])))
1102 && (REGNO_REG_CLASS (REGNO (operands[1]))
1103 == REGNO_REG_CLASS (REGNO (operands[0])))"
1104 [(set (match_dup 0) (match_dup 3))
1105 (set (match_dup 4) (match_dup 5))]
1109 rtx replacements[4];
1111 /* We want to replace occurrences of operands[0] with operands[1] and
1112 operands[2] with operands[0] in operands[4]/operands[5].
1113 Doing just two replace_rtx calls naively would result in the second
1114 replacement undoing all that the first did if operands[1] and operands[2]
1115 are identical, so we must do this simultaneously. */
1116 replacements[0] = operands[0];
1117 replacements[1] = operands[1];
1118 replacements[2] = operands[2];
1119 replacements[3] = operands[0];
1120 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1121 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1122 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1125 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1126 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1127 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1128 /* The operands array is aliased to recog_data.operand, which gets
1129 clobbered by extract_insn, so finish with it now. */
1130 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1131 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1132 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1133 always uses emit_insn. */
1134 /* Check that we don't violate matching constraints or earlyclobbers. */
1135 extract_insn (emit_insn (set1));
1136 if (! constrain_operands (1))
1138 extract_insn (emit (set2));
1139 if (! constrain_operands (1))
1143 tmp = replacements[0];
1144 replacements[0] = replacements[1];
1145 replacements[1] = tmp;
1146 tmp = replacements[2];
1147 replacements[2] = replacements[3];
1148 replacements[3] = tmp;
1149 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1150 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1151 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1157 ;; The register allocator is rather clumsy in handling multi-way conditional
1158 ;; moves, so allow the combiner to make them, and we split them up after
1160 (define_insn_and_split "*movsicc_umin"
1161 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1162 (umin:SI (if_then_else:SI
1163 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1165 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1166 (match_operand:SI 3 "register_operand" "0"))
1167 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1168 (clobber (match_scratch:SI 5 "=&r"))]
1169 "TARGET_SHMEDIA && no_new_pseudos"
1171 "TARGET_SHMEDIA && reload_completed"
1175 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1177 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1178 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1183 (define_insn "*movsicc_t_false"
1184 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1185 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1186 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1187 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1188 "TARGET_PRETEND_CMOVE
1189 && (arith_reg_operand (operands[1], SImode)
1190 || (immediate_operand (operands[1], SImode)
1191 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1192 "bt 0f\;mov %1,%0\\n0:"
1193 [(set_attr "type" "mt_group,arith") ;; poor approximation
1194 (set_attr "length" "4")])
1196 (define_insn "*movsicc_t_true"
1197 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1198 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1199 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1200 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1201 "TARGET_PRETEND_CMOVE
1202 && (arith_reg_operand (operands[1], SImode)
1203 || (immediate_operand (operands[1], SImode)
1204 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1205 "bf 0f\;mov %1,%0\\n0:"
1206 [(set_attr "type" "mt_group,arith") ;; poor approximation
1207 (set_attr "length" "4")])
1209 (define_expand "movsicc"
1210 [(set (match_operand:SI 0 "arith_reg_dest" "")
1211 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1212 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1213 (match_operand:SI 3 "arith_reg_operand" "")))]
1214 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1217 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1218 && GET_MODE (sh_compare_op0) == SImode
1220 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1221 && sh_compare_op1 == const0_rtx)
1222 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1223 sh_compare_op0, sh_compare_op1);
1224 else if (TARGET_PRETEND_CMOVE)
1226 enum rtx_code code = GET_CODE (operands[1]);
1227 enum rtx_code new_code = code;
1230 if (! currently_expanding_to_rtl)
1234 case LT: case LE: case LEU: case LTU:
1235 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1238 new_code = reverse_condition (code);
1240 case EQ: case GT: case GE: case GEU: case GTU:
1245 tmp = prepare_scc_operands (new_code);
1246 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1256 tmp = gen_reg_rtx (SImode);
1258 switch (GET_CODE (operands[1]))
1261 emit_insn (gen_seq (tmp));
1262 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1266 emit_insn (gen_seq (tmp));
1267 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1271 emit_insn (gen_sgt (tmp));
1272 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1276 emit_insn (gen_slt (tmp));
1277 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1281 emit_insn (gen_slt (tmp));
1282 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1286 emit_insn (gen_sgt (tmp));
1287 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1291 emit_insn (gen_sgtu (tmp));
1292 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1296 emit_insn (gen_sltu (tmp));
1297 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1301 emit_insn (gen_sltu (tmp));
1302 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1306 emit_insn (gen_sgtu (tmp));
1307 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1311 emit_insn (gen_sunordered (tmp));
1312 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1316 emit_insn (gen_sunordered (tmp));
1317 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1334 (define_expand "movqicc"
1335 [(set (match_operand:QI 0 "register_operand" "")
1336 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1337 (match_operand:QI 2 "register_operand" "")
1338 (match_operand:QI 3 "register_operand" "")))]
1342 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1343 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1344 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1345 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1349 ;; -------------------------------------------------------------------------
1350 ;; Addition instructions
1351 ;; -------------------------------------------------------------------------
1353 (define_expand "adddi3"
1354 [(set (match_operand:DI 0 "arith_reg_operand" "")
1355 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1356 (match_operand:DI 2 "arith_operand" "")))]
1362 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1364 operands[2] = force_reg (DImode, operands[2]);
1365 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1370 (define_insn "*adddi3_media"
1371 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1372 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1373 (match_operand:DI 2 "arith_operand" "r,I10")))]
1378 [(set_attr "type" "arith_media")])
1380 (define_insn "*adddisi3_media"
1381 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1382 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1383 (match_operand:DI 2 "arith_operand" "r,I10")))]
1388 [(set_attr "type" "arith_media")
1389 (set_attr "highpart" "ignore")])
1391 (define_insn "adddi3z_media"
1392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1394 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1395 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1397 "addz.l %1, %N2, %0"
1398 [(set_attr "type" "arith_media")
1399 (set_attr "highpart" "ignore")])
1401 (define_insn "adddi3_compact"
1402 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1403 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1404 (match_operand:DI 2 "arith_reg_operand" "r")))
1405 (clobber (reg:SI T_REG))]
1408 [(set_attr "length" "6")])
1411 [(set (match_operand:DI 0 "arith_reg_dest" "")
1412 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1413 (match_operand:DI 2 "arith_reg_operand" "")))
1414 (clobber (reg:SI T_REG))]
1415 "TARGET_SH1 && reload_completed"
1419 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1420 high0 = gen_rtx_REG (SImode,
1421 true_regnum (operands[0])
1422 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1423 high2 = gen_rtx_REG (SImode,
1424 true_regnum (operands[2])
1425 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1426 emit_insn (gen_clrt ());
1427 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1428 emit_insn (gen_addc1 (high0, high0, high2));
1433 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1434 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1435 (match_operand:SI 2 "arith_reg_operand" "r"))
1438 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1441 [(set_attr "type" "arith")])
1443 (define_insn "addc1"
1444 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1445 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1446 (match_operand:SI 2 "arith_reg_operand" "r"))
1448 (clobber (reg:SI T_REG))]
1451 [(set_attr "type" "arith")])
1453 (define_expand "addsi3"
1454 [(set (match_operand:SI 0 "arith_reg_operand" "")
1455 (plus:SI (match_operand:SI 1 "arith_operand" "")
1456 (match_operand:SI 2 "arith_operand" "")))]
1461 operands[1] = force_reg (SImode, operands[1]);
1464 (define_insn "addsi3_media"
1465 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1466 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1467 (match_operand:SI 2 "arith_operand" "r,I10")))]
1472 [(set_attr "type" "arith_media")
1473 (set_attr "highpart" "ignore")])
1475 (define_insn "addsidi3_media"
1476 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1477 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1479 (match_operand:SI 2 "arith_operand"
1485 [(set_attr "type" "arith_media")
1486 (set_attr "highpart" "ignore")])
1488 (define_insn "*addsi3_compact"
1489 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1490 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1491 (match_operand:SI 2 "arith_operand" "rI08")))]
1494 [(set_attr "type" "arith")])
1496 ;; -------------------------------------------------------------------------
1497 ;; Subtraction instructions
1498 ;; -------------------------------------------------------------------------
1500 (define_expand "subdi3"
1501 [(set (match_operand:DI 0 "arith_reg_operand" "")
1502 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1503 (match_operand:DI 2 "arith_reg_operand" "")))]
1509 operands[1] = force_reg (DImode, operands[1]);
1510 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1515 (define_insn "*subdi3_media"
1516 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1517 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1518 (match_operand:DI 2 "arith_reg_operand" "r")))]
1521 [(set_attr "type" "arith_media")])
1523 (define_insn "subdisi3_media"
1524 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1525 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1526 (match_operand:DI 2 "arith_reg_operand" "r")))]
1529 [(set_attr "type" "arith_media")
1530 (set_attr "highpart" "ignore")])
1532 (define_insn "subdi3_compact"
1533 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1534 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1535 (match_operand:DI 2 "arith_reg_operand" "r")))
1536 (clobber (reg:SI T_REG))]
1539 [(set_attr "length" "6")])
1542 [(set (match_operand:DI 0 "arith_reg_dest" "")
1543 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1544 (match_operand:DI 2 "arith_reg_operand" "")))
1545 (clobber (reg:SI T_REG))]
1546 "TARGET_SH1 && reload_completed"
1550 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1551 high0 = gen_rtx_REG (SImode,
1552 true_regnum (operands[0])
1553 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1554 high2 = gen_rtx_REG (SImode,
1555 true_regnum (operands[2])
1556 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1557 emit_insn (gen_clrt ());
1558 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1559 emit_insn (gen_subc1 (high0, high0, high2));
1564 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1565 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1566 (match_operand:SI 2 "arith_reg_operand" "r"))
1569 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1574 [(set_attr "type" "arith")])
1576 (define_insn "subc1"
1577 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1578 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1579 (match_operand:SI 2 "arith_reg_operand" "r"))
1581 (clobber (reg:SI T_REG))]
1584 [(set_attr "type" "arith")])
1586 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1587 ;; pattern for this case. This helps multimedia applications that compute
1588 ;; the sum of absolute differences.
1589 (define_insn "mov_neg_si_t"
1590 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1593 [(set_attr "type" "arith")])
1595 (define_insn "*subsi3_internal"
1596 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1597 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1598 (match_operand:SI 2 "arith_reg_operand" "r")))]
1601 [(set_attr "type" "arith")])
1603 (define_insn_and_split "*subsi3_media"
1604 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1605 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1606 (match_operand:SI 2 "extend_reg_operand" "r")))]
1608 && (operands[1] != constm1_rtx
1609 || (GET_CODE (operands[2]) != TRUNCATE
1610 && GET_CODE (operands[2]) != SUBREG))"
1612 "operands[1] == constm1_rtx"
1613 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1615 [(set_attr "type" "arith_media")
1616 (set_attr "highpart" "ignore")])
1619 [(set (match_operand:SI 0 "arith_reg_dest" "")
1620 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1621 "general_extend_operand"
1623 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1624 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1625 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1629 [(set (match_operand:SI 0 "arith_reg_dest" "")
1630 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1631 "general_extend_operand"
1633 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1634 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1635 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1637 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1638 ;; will sometimes save one instruction. Otherwise we might get
1639 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1642 (define_expand "subsi3"
1643 [(set (match_operand:SI 0 "arith_reg_operand" "")
1644 (minus:SI (match_operand:SI 1 "arith_operand" "")
1645 (match_operand:SI 2 "arith_reg_operand" "")))]
1649 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1651 emit_insn (gen_negsi2 (operands[0], operands[2]));
1652 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1657 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1659 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1660 operands[1] = force_reg (SImode, operands[1]);
1664 ;; -------------------------------------------------------------------------
1665 ;; Division instructions
1666 ;; -------------------------------------------------------------------------
1668 ;; We take advantage of the library routines which don't clobber as many
1669 ;; registers as a normal function call would.
1671 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1672 ;; also has an effect on the register that holds the address of the sfunc.
1673 ;; To make this work, we have an extra dummy insn that shows the use
1674 ;; of this register for reorg.
1676 (define_insn "use_sfunc_addr"
1677 [(set (reg:SI PR_REG)
1678 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1679 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1681 [(set_attr "length" "0")])
1683 (define_insn "udivsi3_sh2a"
1684 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1685 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1686 (match_operand:SI 2 "arith_reg_operand" "z")))]
1689 [(set_attr "type" "arith")
1690 (set_attr "in_delay_slot" "no")])
1692 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1693 ;; hard register 0. If we used hard register 0, then the next instruction
1694 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1695 ;; gets allocated to a stack slot that needs its address reloaded, then
1696 ;; there is nothing to prevent reload from using r0 to reload the address.
1697 ;; This reload would clobber the value in r0 we are trying to store.
1698 ;; If we let reload allocate r0, then this problem can never happen.
1700 (define_insn "udivsi3_i1"
1701 [(set (match_operand:SI 0 "register_operand" "=z")
1702 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1703 (clobber (reg:SI T_REG))
1704 (clobber (reg:SI PR_REG))
1705 (clobber (reg:SI R4_REG))
1706 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1707 "TARGET_SH1 && ! TARGET_SH4"
1709 [(set_attr "type" "sfunc")
1710 (set_attr "needs_delay_slot" "yes")])
1712 ; Since shmedia-nofpu code could be linked against shcompact code, and
1713 ; the udivsi3 libcall has the same name, we must consider all registers
1714 ; clobbered that are in the union of the registers clobbered by the
1715 ; shmedia and the shcompact implementation. Note, if the shcompact
1716 ; implementation actually used shcompact code, we'd need to clobber
1717 ; also r23 and fr23.
1718 (define_insn "udivsi3_i1_media"
1719 [(set (match_operand:SI 0 "register_operand" "=z")
1720 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1721 (clobber (reg:SI T_MEDIA_REG))
1722 (clobber (reg:SI PR_MEDIA_REG))
1723 (clobber (reg:SI R20_REG))
1724 (clobber (reg:SI R21_REG))
1725 (clobber (reg:SI R22_REG))
1726 (clobber (reg:DI TR0_REG))
1727 (clobber (reg:DI TR1_REG))
1728 (clobber (reg:DI TR2_REG))
1729 (use (match_operand 1 "target_operand" "b"))]
1730 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1732 [(set_attr "type" "sfunc")
1733 (set_attr "needs_delay_slot" "yes")])
1735 (define_expand "udivsi3_i4_media"
1737 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1739 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1740 (set (match_dup 5) (float:DF (match_dup 3)))
1741 (set (match_dup 6) (float:DF (match_dup 4)))
1742 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1743 (set (match_dup 8) (fix:DI (match_dup 7)))
1744 (set (match_operand:SI 0 "register_operand" "")
1745 (truncate:SI (match_dup 8)))]
1746 "TARGET_SHMEDIA_FPU"
1749 operands[3] = gen_reg_rtx (DImode);
1750 operands[4] = gen_reg_rtx (DImode);
1751 operands[5] = gen_reg_rtx (DFmode);
1752 operands[6] = gen_reg_rtx (DFmode);
1753 operands[7] = gen_reg_rtx (DFmode);
1754 operands[8] = gen_reg_rtx (DImode);
1757 (define_insn "udivsi3_i4"
1758 [(set (match_operand:SI 0 "register_operand" "=y")
1759 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760 (clobber (reg:SI T_REG))
1761 (clobber (reg:SI PR_REG))
1762 (clobber (reg:DF DR0_REG))
1763 (clobber (reg:DF DR2_REG))
1764 (clobber (reg:DF DR4_REG))
1765 (clobber (reg:SI R0_REG))
1766 (clobber (reg:SI R1_REG))
1767 (clobber (reg:SI R4_REG))
1768 (clobber (reg:SI R5_REG))
1769 (use (reg:PSI FPSCR_REG))
1770 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1771 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1773 [(set_attr "type" "sfunc")
1774 (set_attr "fp_mode" "double")
1775 (set_attr "needs_delay_slot" "yes")])
1777 (define_insn "udivsi3_i4_single"
1778 [(set (match_operand:SI 0 "register_operand" "=y")
1779 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1780 (clobber (reg:SI T_REG))
1781 (clobber (reg:SI PR_REG))
1782 (clobber (reg:DF DR0_REG))
1783 (clobber (reg:DF DR2_REG))
1784 (clobber (reg:DF DR4_REG))
1785 (clobber (reg:SI R0_REG))
1786 (clobber (reg:SI R1_REG))
1787 (clobber (reg:SI R4_REG))
1788 (clobber (reg:SI R5_REG))
1789 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1790 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1792 [(set_attr "type" "sfunc")
1793 (set_attr "needs_delay_slot" "yes")])
1795 (define_insn "udivsi3_i4_int"
1796 [(set (match_operand:SI 0 "register_operand" "=z")
1797 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1798 (clobber (reg:SI T_REG))
1799 (clobber (reg:SI R1_REG))
1800 (clobber (reg:SI PR_REG))
1801 (clobber (reg:SI MACH_REG))
1802 (clobber (reg:SI MACL_REG))
1803 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1806 [(set_attr "type" "sfunc")
1807 (set_attr "needs_delay_slot" "yes")])
1810 (define_expand "udivsi3"
1811 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1812 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1813 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1814 (parallel [(set (match_operand:SI 0 "register_operand" "")
1815 (udiv:SI (reg:SI R4_REG)
1817 (clobber (reg:SI T_REG))
1818 (clobber (reg:SI PR_REG))
1819 (clobber (reg:SI R4_REG))
1820 (use (match_dup 3))])]
1826 operands[3] = gen_reg_rtx (Pmode);
1827 /* Emit the move of the address to a pseudo outside of the libcall. */
1828 if (TARGET_DIVIDE_CALL_TABLE)
1830 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1831 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1833 else if (TARGET_DIVIDE_CALL_FP)
1835 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1836 if (TARGET_FPU_SINGLE)
1837 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1839 last = gen_udivsi3_i4 (operands[0], operands[3]);
1841 else if (TARGET_SHMEDIA_FPU)
1843 operands[1] = force_reg (SImode, operands[1]);
1844 operands[2] = force_reg (SImode, operands[2]);
1845 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1848 else if (TARGET_SH2A)
1850 operands[1] = force_reg (SImode, operands[1]);
1851 operands[2] = force_reg (SImode, operands[2]);
1852 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1855 else if (TARGET_SH5)
1857 function_symbol (operands[3],
1858 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1862 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1863 else if (TARGET_FPU_ANY)
1864 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1866 last = gen_udivsi3_i1 (operands[0], operands[3]);
1870 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1871 last = gen_udivsi3_i1 (operands[0], operands[3]);
1873 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1874 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1875 last = emit_insn (last);
1876 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1877 invariant code motion can move it. */
1878 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1879 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1883 (define_insn "divsi3_sh2a"
1884 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1885 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1886 (match_operand:SI 2 "arith_reg_operand" "z")))]
1889 [(set_attr "type" "arith")
1890 (set_attr "in_delay_slot" "no")])
1892 (define_insn "divsi3_i1"
1893 [(set (match_operand:SI 0 "register_operand" "=z")
1894 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1895 (clobber (reg:SI T_REG))
1896 (clobber (reg:SI PR_REG))
1897 (clobber (reg:SI R1_REG))
1898 (clobber (reg:SI R2_REG))
1899 (clobber (reg:SI R3_REG))
1900 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1901 "TARGET_SH1 && ! TARGET_SH4"
1903 [(set_attr "type" "sfunc")
1904 (set_attr "needs_delay_slot" "yes")])
1906 (define_insn "divsi3_i1_media"
1907 [(set (match_operand:SI 0 "register_operand" "=z")
1908 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1909 (clobber (reg:SI T_MEDIA_REG))
1910 (clobber (reg:SI PR_MEDIA_REG))
1911 (clobber (reg:SI R1_REG))
1912 (clobber (reg:SI R20_REG))
1913 (clobber (reg:SI R21_REG))
1914 (clobber (reg:SI TR0_REG))
1915 (use (match_operand 1 "target_operand" "b"))]
1916 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1918 [(set_attr "type" "sfunc")])
1920 (define_insn "divsi3_media_2"
1921 [(set (match_operand:SI 0 "register_operand" "=z")
1922 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1923 (clobber (reg:SI T_MEDIA_REG))
1924 (clobber (reg:SI PR_MEDIA_REG))
1925 (clobber (reg:SI R1_REG))
1926 (clobber (reg:SI R21_REG))
1927 (clobber (reg:SI TR0_REG))
1928 (use (reg:SI R20_REG))
1929 (use (match_operand 1 "target_operand" "b"))]
1930 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1932 [(set_attr "type" "sfunc")])
1934 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1935 ;; hard reg clobbers and data dependencies that we need when we want
1936 ;; to rematerialize the division into a call.
1937 (define_insn_and_split "divsi_inv_call"
1938 [(set (match_operand:SI 0 "register_operand" "=r")
1939 (div:SI (match_operand:SI 1 "register_operand" "r")
1940 (match_operand:SI 2 "register_operand" "r")))
1941 (clobber (reg:SI R4_REG))
1942 (clobber (reg:SI R5_REG))
1943 (clobber (reg:SI T_MEDIA_REG))
1944 (clobber (reg:SI PR_MEDIA_REG))
1945 (clobber (reg:SI R1_REG))
1946 (clobber (reg:SI R21_REG))
1947 (clobber (reg:SI TR0_REG))
1948 (clobber (reg:SI R20_REG))
1949 (use (match_operand:SI 3 "register_operand" "r"))]
1952 "&& (high_life_started || reload_completed)"
1953 [(set (match_dup 0) (match_dup 3))]
1955 [(set_attr "highpart" "must_split")])
1957 ;; This is the combiner pattern for -mdiv=inv:call .
1958 (define_insn_and_split "*divsi_inv_call_combine"
1959 [(set (match_operand:SI 0 "register_operand" "=z")
1960 (div:SI (match_operand:SI 1 "register_operand" "r")
1961 (match_operand:SI 2 "register_operand" "r")))
1962 (clobber (reg:SI R4_REG))
1963 (clobber (reg:SI R5_REG))
1964 (clobber (reg:SI T_MEDIA_REG))
1965 (clobber (reg:SI PR_MEDIA_REG))
1966 (clobber (reg:SI R1_REG))
1967 (clobber (reg:SI R21_REG))
1968 (clobber (reg:SI TR0_REG))
1969 (clobber (reg:SI R20_REG))
1970 (use (unspec:SI [(match_dup 1)
1971 (match_operand:SI 3 "" "")
1972 (unspec:SI [(match_operand:SI 4 "" "")
1974 (match_operand:DI 5 "" "")]
1976 (match_operand:DI 6 "" "")
1979 UNSPEC_DIV_INV_M3))]
1982 "&& (high_life_started || reload_completed)"
1986 const char *name = sh_divsi3_libfunc;
1987 enum sh_function_kind kind = SFUNC_GOT;
1990 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1991 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1992 while (TARGET_DIVIDE_INV_CALL2)
1994 rtx x = operands[3];
1996 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1998 x = XVECEXP (x, 0, 0);
1999 name = \"__sdivsi3_2\";
2000 kind = SFUNC_STATIC;
2001 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2004 sym = function_symbol (NULL, name, kind);
2005 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2008 [(set_attr "highpart" "must_split")])
2010 (define_expand "divsi3_i4_media"
2011 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2012 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2013 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2014 (set (match_operand:SI 0 "register_operand" "=r")
2015 (fix:SI (match_dup 5)))]
2016 "TARGET_SHMEDIA_FPU"
2019 operands[3] = gen_reg_rtx (DFmode);
2020 operands[4] = gen_reg_rtx (DFmode);
2021 operands[5] = gen_reg_rtx (DFmode);
2024 (define_insn "divsi3_i4"
2025 [(set (match_operand:SI 0 "register_operand" "=y")
2026 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2027 (clobber (reg:SI PR_REG))
2028 (clobber (reg:DF DR0_REG))
2029 (clobber (reg:DF DR2_REG))
2030 (use (reg:PSI FPSCR_REG))
2031 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2032 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2034 [(set_attr "type" "sfunc")
2035 (set_attr "fp_mode" "double")
2036 (set_attr "needs_delay_slot" "yes")])
2038 (define_insn "divsi3_i4_single"
2039 [(set (match_operand:SI 0 "register_operand" "=y")
2040 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2041 (clobber (reg:SI PR_REG))
2042 (clobber (reg:DF DR0_REG))
2043 (clobber (reg:DF DR2_REG))
2044 (clobber (reg:SI R2_REG))
2045 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2046 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2048 [(set_attr "type" "sfunc")
2049 (set_attr "needs_delay_slot" "yes")])
2051 (define_insn "divsi3_i4_int"
2052 [(set (match_operand:SI 0 "register_operand" "=z")
2053 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2054 (clobber (reg:SI T_REG))
2055 (clobber (reg:SI PR_REG))
2056 (clobber (reg:SI R1_REG))
2057 (clobber (reg:SI MACH_REG))
2058 (clobber (reg:SI MACL_REG))
2059 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2062 [(set_attr "type" "sfunc")
2063 (set_attr "needs_delay_slot" "yes")])
2065 (define_expand "divsi3"
2066 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2067 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2068 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2069 (parallel [(set (match_operand:SI 0 "register_operand" "")
2070 (div:SI (reg:SI R4_REG)
2072 (clobber (reg:SI T_REG))
2073 (clobber (reg:SI PR_REG))
2074 (clobber (reg:SI R1_REG))
2075 (clobber (reg:SI R2_REG))
2076 (clobber (reg:SI R3_REG))
2077 (use (match_dup 3))])]
2083 operands[3] = gen_reg_rtx (Pmode);
2084 /* Emit the move of the address to a pseudo outside of the libcall. */
2085 if (TARGET_DIVIDE_CALL_TABLE)
2087 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2088 last = gen_divsi3_i4_int (operands[0], operands[3]);
2090 else if (TARGET_DIVIDE_CALL_FP)
2092 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2093 if (TARGET_FPU_SINGLE)
2094 last = gen_divsi3_i4_single (operands[0], operands[3]);
2096 last = gen_divsi3_i4 (operands[0], operands[3]);
2098 else if (TARGET_SH2A)
2100 operands[1] = force_reg (SImode, operands[1]);
2101 operands[2] = force_reg (SImode, operands[2]);
2102 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2105 else if (TARGET_DIVIDE_INV)
2107 rtx dividend = operands[1];
2108 rtx divisor = operands[2];
2110 rtx nsb_res = gen_reg_rtx (DImode);
2111 rtx norm64 = gen_reg_rtx (DImode);
2112 rtx tab_ix = gen_reg_rtx (DImode);
2113 rtx norm32 = gen_reg_rtx (SImode);
2114 rtx i92 = force_reg (DImode, GEN_INT (92));
2115 rtx scratch0a = gen_reg_rtx (DImode);
2116 rtx scratch0b = gen_reg_rtx (DImode);
2117 rtx inv0 = gen_reg_rtx (SImode);
2118 rtx scratch1a = gen_reg_rtx (DImode);
2119 rtx scratch1b = gen_reg_rtx (DImode);
2120 rtx shift = gen_reg_rtx (DImode);
2122 rtx inv1 = gen_reg_rtx (SImode);
2123 rtx scratch2a = gen_reg_rtx (DImode);
2124 rtx scratch2b = gen_reg_rtx (SImode);
2125 rtx inv2 = gen_reg_rtx (SImode);
2126 rtx scratch3a = gen_reg_rtx (DImode);
2127 rtx scratch3b = gen_reg_rtx (DImode);
2128 rtx scratch3c = gen_reg_rtx (DImode);
2129 rtx scratch3d = gen_reg_rtx (SImode);
2130 rtx scratch3e = gen_reg_rtx (DImode);
2131 rtx result = gen_reg_rtx (SImode);
2133 if (! arith_reg_or_0_operand (dividend, SImode))
2134 dividend = force_reg (SImode, dividend);
2135 if (! arith_reg_operand (divisor, SImode))
2136 divisor = force_reg (SImode, divisor);
2137 if (flag_pic && Pmode != DImode)
2139 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2140 tab_base = gen_datalabel_ref (tab_base);
2141 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2145 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2146 tab_base = gen_datalabel_ref (tab_base);
2147 tab_base = force_reg (DImode, tab_base);
2149 if (TARGET_DIVIDE_INV20U)
2150 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2152 i2p27 = GEN_INT (0);
2153 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2154 i43 = force_reg (DImode, GEN_INT (43));
2157 emit_insn (gen_nsbdi (nsb_res,
2158 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2159 emit_insn (gen_ashldi3_media (norm64,
2160 gen_rtx_SUBREG (DImode, divisor, 0),
2162 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2163 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2164 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2165 inv0, scratch0a, scratch0b,
2166 scratch1a, scratch1b));
2167 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2168 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2170 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2172 scratch3a, scratch3b, scratch3c,
2173 scratch2a, scratch2b, scratch3d, scratch3e));
2174 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2175 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2176 else if (TARGET_DIVIDE_INV_FP)
2177 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2178 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2179 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2180 gen_reg_rtx (DFmode)));
2182 emit_move_insn (operands[0], result);
2185 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2187 operands[1] = force_reg (SImode, operands[1]);
2188 operands[2] = force_reg (SImode, operands[2]);
2189 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2192 else if (TARGET_SH5)
2194 if (TARGET_DIVIDE_CALL2)
2196 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2197 tab_base = gen_datalabel_ref (tab_base);
2198 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2200 if (TARGET_FPU_ANY && TARGET_SH1)
2201 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2202 else if (TARGET_DIVIDE_CALL2)
2203 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2205 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2208 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2209 (operands[0], operands[3]));
2210 else if (TARGET_FPU_ANY)
2211 last = gen_divsi3_i4_single (operands[0], operands[3]);
2213 last = gen_divsi3_i1 (operands[0], operands[3]);
2217 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2218 last = gen_divsi3_i1 (operands[0], operands[3]);
2220 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2221 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2222 last = emit_insn (last);
2223 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2224 invariant code motion can move it. */
2225 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2226 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2230 ;; operands: inv0, tab_base, tab_ix, norm32
2231 ;; scratch equiv in sdivsi3_2: r19, r21
2232 (define_expand "divsi_inv_m0"
2233 [(set (match_operand:SI 0 "register_operand" "=r")
2234 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2235 (match_operand:DI 2 "register_operand" "r")
2236 (match_operand:SI 3 "register_operand" "r")]
2238 (clobber (match_operand:DI 4 "register_operand" "=r"))
2239 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2247 ldx.ub r20, r21, r19 // u0.8
2249 muls.l r25, r19, r19 // s2.38
2250 ldx.w r20, r21, r21 // s2.14
2251 shari r19, 24, r19 // truncate to s2.14
2252 sub r21, r19, r19 // some 11 bit inverse in s1.14
2255 rtx inv0 = operands[0];
2256 rtx tab_base = operands[1];
2257 rtx tab_ix = operands[2];
2258 rtx norm32 = operands[3];
2259 rtx scratch0 = operands[4];
2260 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2261 rtx scratch1 = operands[5];
2264 mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2265 emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2266 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2267 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2268 mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2269 emit_insn (gen_extendhidi2 (scratch1, mem));
2270 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2271 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2275 ;; operands: inv1, tab_base, tab_ix, norm32
2276 (define_insn_and_split "divsi_inv_m1"
2277 [(set (match_operand:SI 0 "register_operand" "=r")
2278 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2279 (match_operand:DI 2 "register_operand" "r")
2280 (match_operand:SI 3 "register_operand" "r")]
2282 (clobber (match_operand:SI 4 "register_operand" "=r"))
2283 (clobber (match_operand:DI 5 "register_operand" "=r"))
2284 (clobber (match_operand:DI 6 "register_operand" "=r"))
2285 (clobber (match_operand:DI 7 "register_operand" "=r"))
2286 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2294 muls.l r19, r19, r18 // u0.28
2295 muls.l r25, r18, r18 // s2.58
2296 shlli r19, 45, r0 // multiply by two and convert to s2.58
2298 shari r18, 28, r18 // some 18 bit inverse in s1.30
2301 rtx inv1 = operands[0];
2302 rtx tab_base = operands[1];
2303 rtx tab_ix = operands[2];
2304 rtx norm32 = operands[3];
2305 rtx inv0 = operands[4];
2306 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2307 rtx scratch0a = operands[5];
2308 rtx scratch0b = operands[6];
2309 rtx scratch0 = operands[7];
2310 rtx scratch1 = operands[8];
2311 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2313 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2314 scratch0a, scratch0b));
2315 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2316 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2317 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2318 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2319 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2323 ;; operands: inv2, norm32, inv1, i92
2324 (define_insn_and_split "divsi_inv_m2"
2325 [(set (match_operand:SI 0 "register_operand" "=r")
2326 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2327 (match_operand:SI 2 "register_operand" "r")
2328 (match_operand:DI 3 "register_operand" "r")]
2330 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2338 muls.l r18, r25, r0 // s2.60
2339 shari r0, 16, r0 // s-16.44
2341 muls.l r0, r18, r19 // s-16.74
2342 shari r19, 30, r19 // s-16.44
2344 rtx inv2 = operands[0];
2345 rtx norm32 = operands[1];
2346 rtx inv1 = operands[2];
2347 rtx i92 = operands[3];
2348 rtx scratch0 = operands[4];
2349 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2351 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2352 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2353 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2354 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2355 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2359 (define_insn_and_split "divsi_inv_m3"
2360 [(set (match_operand:SI 0 "register_operand" "=r")
2361 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2362 (match_operand:SI 2 "register_operand" "r")
2363 (match_operand:SI 3 "register_operand" "r")
2364 (match_operand:DI 4 "register_operand" "r")
2365 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2366 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2368 (clobber (match_operand:DI 7 "register_operand" "=r"))
2369 (clobber (match_operand:DI 8 "register_operand" "=r"))
2370 (clobber (match_operand:DI 9 "register_operand" "=r"))
2371 (clobber (match_operand:DI 10 "register_operand" "=r"))
2372 (clobber (match_operand:SI 11 "register_operand" "=r"))
2373 (clobber (match_operand:SI 12 "register_operand" "=r"))
2374 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2382 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2383 r0: scratch0 r19: scratch1 r21: scratch2
2385 muls.l r18, r4, r25 // s32.30
2386 muls.l r19, r4, r19 // s15.30
2388 shari r19, 14, r19 // s18.-14
2394 rtx result = operands[0];
2395 rtx dividend = operands[1];
2396 rtx inv1 = operands[2];
2397 rtx inv2 = operands[3];
2398 rtx shift = operands[4];
2399 rtx scratch0 = operands[7];
2400 rtx scratch1 = operands[8];
2401 rtx scratch2 = operands[9];
2403 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2404 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2405 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2406 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2407 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2408 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2409 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2413 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2414 ;; inv1: tab_base, tab_ix, norm32
2415 ;; inv2: norm32, inv1, i92
2416 (define_insn_and_split "divsi_inv_m1_3"
2417 [(set (match_operand:SI 0 "register_operand" "=r")
2418 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2419 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2420 (match_operand:DI 3 "register_operand" "r")
2421 (match_operand:SI 4 "register_operand" "r")]
2423 (unspec:SI [(match_dup 4)
2424 (unspec:SI [(match_dup 2)
2426 (match_dup 4)] UNSPEC_DIV_INV_M1)
2427 (match_operand:SI 5 "" "")]
2429 (match_operand:DI 6 "register_operand" "r")
2430 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2431 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2433 (clobber (match_operand:DI 9 "register_operand" "=r"))
2434 (clobber (match_operand:DI 10 "register_operand" "=r"))
2435 (clobber (match_operand:DI 11 "register_operand" "=r"))
2436 (clobber (match_operand:DI 12 "register_operand" "=r"))
2437 (clobber (match_operand:SI 13 "register_operand" "=r"))
2438 (clobber (match_operand:SI 14 "register_operand" "=r"))
2439 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2441 && (TARGET_DIVIDE_INV_MINLAT
2442 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2448 rtx result = operands[0];
2449 rtx dividend = operands[1];
2450 rtx tab_base = operands[2];
2451 rtx tab_ix = operands[3];
2452 rtx norm32 = operands[4];
2453 /* rtx i92 = operands[5]; */
2454 rtx shift = operands[6];
2455 rtx i2p27 = operands[7];
2456 rtx i43 = operands[8];
2457 rtx scratch0 = operands[9];
2458 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2459 rtx scratch1 = operands[10];
2460 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2461 rtx scratch2 = operands[11];
2462 rtx scratch3 = operands[12];
2463 rtx scratch4 = operands[13];
2464 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2465 rtx scratch5 = operands[14];
2466 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2467 rtx scratch6 = operands[15];
2469 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2470 scratch0, scratch1));
2471 /* inv0 == scratch4 */
2472 if (! TARGET_DIVIDE_INV20U)
2474 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2476 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2480 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2481 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2483 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2484 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2485 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2486 /* inv1 == scratch4 */
2488 if (TARGET_DIVIDE_INV_MINLAT)
2490 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2491 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2492 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2493 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2494 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2495 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2496 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2497 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2498 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2499 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2500 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2504 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2505 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2506 emit_insn (gen_nsbdi (scratch6,
2507 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2508 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2509 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2510 emit_insn (gen_divsi_inv20 (scratch2,
2511 norm32, scratch4, dividend,
2512 scratch6, scratch3, i43,
2513 /* scratch0 may be shared with i2p27. */
2514 scratch0, scratch1, scratch5,
2515 label, label, i2p27));
2517 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2518 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2522 (define_insn "divsi_inv20"
2523 [(set (match_operand:DI 0 "register_operand" "=&r")
2524 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2525 (match_operand:SI 2 "register_operand" "r")
2526 (match_operand:SI 3 "register_operand" "r")
2527 (match_operand:DI 4 "register_operand" "r")
2528 (match_operand:DI 5 "register_operand" "r")
2529 (match_operand:DI 6 "register_operand" "r")
2530 (match_operand:DI 12 "register_operand" "r")
2531 (match_operand 10 "target_operand" "b")
2532 (match_operand 11 "immediate_operand" "i")]
2534 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2535 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2536 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2538 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2541 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2542 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2543 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2544 %10 label (tr), %11 label (imm)
2546 muls.l inv1, norm32, scratch0 // s2.60
2547 muls.l inv1, dividend, result // s32.30
2548 xor i2p27, result_sign, round_scratch
2549 bge/u dividend_nsb, i43, tr.. (label)
2550 shari scratch0, 16, scratch0 // s-16.44
2551 muls.l sratch0_si, inv1, scratch0 // s-16.74
2552 sub result, round_scratch, result
2553 shari dividend, 14, scratch1 // s19.-14
2554 shari scratch0, 30, scratch0 // s-16.44
2555 muls.l scratch0, scratch1, round_scratch // s15.30
2557 sub result, round_scratch, result */
2559 int likely = TARGET_DIVIDE_INV20L;
2561 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2562 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2563 output_asm_insn (likely
2564 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2565 : \"bge/u\t%4, %6, %10\", operands);
2566 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2567 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2568 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2570 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2571 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2574 (define_insn_and_split "divsi_inv_fp"
2575 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2576 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2577 (match_operand:SI 2 "register_operand" "rf")))
2578 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2579 (clobber (match_operand:SI 4 "register_operand" "=r"))
2580 (clobber (match_operand:SI 5 "register_operand" "=r"))
2581 (clobber (match_operand:DF 6 "register_operand" "=r"))
2582 (clobber (match_operand:DF 7 "register_operand" "=r"))
2583 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2584 "TARGET_SHMEDIA_FPU"
2586 "&& (high_life_started || reload_completed)"
2587 [(set (match_dup 0) (match_dup 3))]
2589 [(set_attr "highpart" "must_split")])
2591 ;; If a matching group of divide-by-inverse instructions is in the same
2592 ;; basic block after gcse & loop optimizations, we want to transform them
2593 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2594 (define_insn_and_split "*divsi_inv_fp_combine"
2595 [(set (match_operand:SI 0 "register_operand" "=f")
2596 (div:SI (match_operand:SI 1 "register_operand" "f")
2597 (match_operand:SI 2 "register_operand" "f")))
2598 (use (unspec:SI [(match_dup 1)
2599 (match_operand:SI 3 "" "")
2600 (unspec:SI [(match_operand:SI 4 "" "")
2602 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2603 (match_operand:DI 6 "" "")
2605 (const_int 0)] UNSPEC_DIV_INV_M3))
2606 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2607 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2608 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2609 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2610 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2611 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2614 [(set (match_dup 9) (float:DF (match_dup 1)))
2615 (set (match_dup 10) (float:DF (match_dup 2)))
2616 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2618 (fix:SI (match_dup 11)))
2619 (set (match_dup 0) (match_dup 8))]
2622 if (! fp_arith_reg_operand (operands[1], SImode))
2624 emit_move_insn (operands[7], operands[1]);
2625 operands[1] = operands[7];
2627 if (! fp_arith_reg_operand (operands[2], SImode))
2629 emit_move_insn (operands[8], operands[2]);
2630 operands[2] = operands[8];
2633 [(set_attr "highpart" "must_split")])
2635 ;; -------------------------------------------------------------------------
2636 ;; Multiplication instructions
2637 ;; -------------------------------------------------------------------------
2639 (define_insn "umulhisi3_i"
2640 [(set (reg:SI MACL_REG)
2641 (mult:SI (zero_extend:SI
2642 (match_operand:HI 0 "arith_reg_operand" "r"))
2644 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2647 [(set_attr "type" "smpy")])
2649 (define_insn "mulhisi3_i"
2650 [(set (reg:SI MACL_REG)
2651 (mult:SI (sign_extend:SI
2652 (match_operand:HI 0 "arith_reg_operand" "r"))
2654 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2657 [(set_attr "type" "smpy")])
2659 (define_expand "mulhisi3"
2660 [(set (reg:SI MACL_REG)
2661 (mult:SI (sign_extend:SI
2662 (match_operand:HI 1 "arith_reg_operand" ""))
2664 (match_operand:HI 2 "arith_reg_operand" ""))))
2665 (set (match_operand:SI 0 "arith_reg_operand" "")
2672 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2673 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2674 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2675 invariant code motion can move it. */
2676 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2677 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2678 /* expand_binop can't find a suitable code in umul_widen_optab to
2679 make a REG_EQUAL note from, so make one here.
2680 See also smulsi3_highpart.
2681 ??? Alternatively, we could put this at the calling site of expand_binop,
2682 i.e. expand_expr. */
2684 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2689 (define_expand "umulhisi3"
2690 [(set (reg:SI MACL_REG)
2691 (mult:SI (zero_extend:SI
2692 (match_operand:HI 1 "arith_reg_operand" ""))
2694 (match_operand:HI 2 "arith_reg_operand" ""))))
2695 (set (match_operand:SI 0 "arith_reg_operand" "")
2702 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2703 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2704 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2705 invariant code motion can move it. */
2706 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2707 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2708 /* expand_binop can't find a suitable code in umul_widen_optab to
2709 make a REG_EQUAL note from, so make one here.
2710 See also smulsi3_highpart.
2711 ??? Alternatively, we could put this at the calling site of expand_binop,
2712 i.e. expand_expr. */
2714 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2719 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2720 ;; a call to a routine which clobbers known registers.
2723 [(set (match_operand:SI 1 "register_operand" "=z")
2724 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2725 (clobber (reg:SI MACL_REG))
2726 (clobber (reg:SI T_REG))
2727 (clobber (reg:SI PR_REG))
2728 (clobber (reg:SI R3_REG))
2729 (clobber (reg:SI R2_REG))
2730 (clobber (reg:SI R1_REG))
2731 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2734 [(set_attr "type" "sfunc")
2735 (set_attr "needs_delay_slot" "yes")])
2737 (define_expand "mulsi3_call"
2738 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2739 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2740 (parallel[(set (match_operand:SI 0 "register_operand" "")
2741 (mult:SI (reg:SI R4_REG)
2743 (clobber (reg:SI MACL_REG))
2744 (clobber (reg:SI T_REG))
2745 (clobber (reg:SI PR_REG))
2746 (clobber (reg:SI R3_REG))
2747 (clobber (reg:SI R2_REG))
2748 (clobber (reg:SI R1_REG))
2749 (use (match_operand:SI 3 "register_operand" ""))])]
2753 (define_insn "mul_r"
2754 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2755 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2756 (match_operand:SI 2 "arith_reg_operand" "z")))]
2759 [(set_attr "type" "dmpy")])
2761 (define_insn "mul_l"
2762 [(set (reg:SI MACL_REG)
2763 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2764 (match_operand:SI 1 "arith_reg_operand" "r")))]
2767 [(set_attr "type" "dmpy")])
2769 (define_expand "mulsi3"
2770 [(set (reg:SI MACL_REG)
2771 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2772 (match_operand:SI 2 "arith_reg_operand" "")))
2773 (set (match_operand:SI 0 "arith_reg_operand" "")
2782 /* The address must be set outside the libcall,
2783 since it goes into a pseudo. */
2784 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2785 rtx addr = force_reg (SImode, sym);
2786 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2789 last = emit_insn (insns);
2793 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2795 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2796 /* consec_sets_giv can only recognize the first insn that sets a
2797 giv as the giv insn. So we must tag this also with a REG_EQUAL
2799 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2801 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2802 invariant code motion can move it. */
2803 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2804 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2808 (define_insn "mulsidi3_i"
2809 [(set (reg:SI MACH_REG)
2813 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2814 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2816 (set (reg:SI MACL_REG)
2817 (mult:SI (match_dup 0)
2821 [(set_attr "type" "dmpy")])
2823 (define_expand "mulsidi3"
2824 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2825 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2826 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2827 "TARGET_SH2 || TARGET_SHMEDIA"
2832 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2838 (define_insn "mulsidi3_media"
2839 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2840 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2841 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2844 [(set_attr "type" "dmpy_media")
2845 (set_attr "highpart" "ignore")])
2847 (define_insn "mulsidi3_compact"
2848 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2850 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2851 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2852 (clobber (reg:SI MACH_REG))
2853 (clobber (reg:SI MACL_REG))]
2858 [(set (match_operand:DI 0 "arith_reg_dest" "")
2860 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2861 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2862 (clobber (reg:SI MACH_REG))
2863 (clobber (reg:SI MACL_REG))]
2868 rtx low_dst = gen_lowpart (SImode, operands[0]);
2869 rtx high_dst = gen_highpart (SImode, operands[0]);
2871 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2873 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2874 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2875 /* We need something to tag the possible REG_EQUAL notes on to. */
2876 emit_move_insn (operands[0], operands[0]);
2880 (define_insn "umulsidi3_i"
2881 [(set (reg:SI MACH_REG)
2885 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2886 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2888 (set (reg:SI MACL_REG)
2889 (mult:SI (match_dup 0)
2893 [(set_attr "type" "dmpy")])
2895 (define_expand "umulsidi3"
2896 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2897 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2898 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2899 "TARGET_SH2 || TARGET_SHMEDIA"
2904 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2910 (define_insn "umulsidi3_media"
2911 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2912 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2913 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2916 [(set_attr "type" "dmpy_media")
2917 (set_attr "highpart" "ignore")])
2919 (define_insn "umulsidi3_compact"
2920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2922 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2923 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2924 (clobber (reg:SI MACH_REG))
2925 (clobber (reg:SI MACL_REG))]
2930 [(set (match_operand:DI 0 "arith_reg_dest" "")
2931 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2932 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2933 (clobber (reg:SI MACH_REG))
2934 (clobber (reg:SI MACL_REG))]
2939 rtx low_dst = gen_lowpart (SImode, operands[0]);
2940 rtx high_dst = gen_highpart (SImode, operands[0]);
2942 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2944 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2945 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2946 /* We need something to tag the possible REG_EQUAL notes on to. */
2947 emit_move_insn (operands[0], operands[0]);
2951 (define_insn "smulsi3_highpart_i"
2952 [(set (reg:SI MACH_REG)
2956 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2957 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2959 (clobber (reg:SI MACL_REG))]
2962 [(set_attr "type" "dmpy")])
2964 (define_expand "smulsi3_highpart"
2966 [(set (reg:SI MACH_REG)
2970 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2971 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2973 (clobber (reg:SI MACL_REG))])
2974 (set (match_operand:SI 0 "arith_reg_operand" "")
2981 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2982 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2983 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2984 invariant code motion can move it. */
2985 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2986 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2987 /* expand_binop can't find a suitable code in mul_highpart_optab to
2988 make a REG_EQUAL note from, so make one here.
2989 See also {,u}mulhisi.
2990 ??? Alternatively, we could put this at the calling site of expand_binop,
2991 i.e. expand_mult_highpart. */
2993 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2998 (define_insn "umulsi3_highpart_i"
2999 [(set (reg:SI MACH_REG)
3003 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3004 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3006 (clobber (reg:SI MACL_REG))]
3009 [(set_attr "type" "dmpy")])
3011 (define_expand "umulsi3_highpart"
3013 [(set (reg:SI MACH_REG)
3017 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3018 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3020 (clobber (reg:SI MACL_REG))])
3021 (set (match_operand:SI 0 "arith_reg_operand" "")
3028 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3029 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3030 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3031 invariant code motion can move it. */
3032 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3033 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3037 (define_insn_and_split "muldi3"
3038 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3039 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3040 (match_operand:DI 2 "arith_reg_operand" "r")))
3041 (clobber (match_scratch:DI 3 "=&r"))
3042 (clobber (match_scratch:DI 4 "=r"))]
3049 rtx op3_v2si, op2_v2si;
3051 op3_v2si = operands[3];
3052 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3054 op3_v2si = XEXP (op3_v2si, 0);
3055 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3057 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3058 op2_v2si = operands[2];
3059 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3061 op2_v2si = XEXP (op2_v2si, 0);
3062 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3064 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3065 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3066 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3067 emit_insn (gen_umulsidi3_media (operands[4],
3068 sh_gen_truncate (SImode, operands[1], 0),
3069 sh_gen_truncate (SImode, operands[2], 0)));
3070 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3071 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3072 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3073 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3078 ;; -------------------------------------------------------------------------
3079 ;; Logical operations
3080 ;; -------------------------------------------------------------------------
3082 (define_insn "*andsi3_compact"
3083 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3084 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3085 (match_operand:SI 2 "logical_operand" "r,K08")))]
3088 [(set_attr "type" "arith")])
3090 (define_insn "*andsi3_media"
3091 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3092 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3093 (match_operand:SI 2 "logical_operand" "r,I10")))]
3098 [(set_attr "type" "arith_media")])
3100 ;; If the constant is 255, then emit an extu.b instruction instead of an
3101 ;; and, since that will give better code.
3103 (define_expand "andsi3"
3104 [(set (match_operand:SI 0 "arith_reg_operand" "")
3105 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3106 (match_operand:SI 2 "logical_operand" "")))]
3111 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3113 emit_insn (gen_zero_extendqisi2 (operands[0],
3114 gen_lowpart (QImode, operands[1])));
3119 (define_insn_and_split "anddi3"
3120 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3121 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3122 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3129 && ! logical_operand (operands[2], DImode)"
3133 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3134 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3136 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3139 [(set_attr "type" "arith_media")])
3141 (define_insn "andcsi3"
3142 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3143 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3144 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3147 [(set_attr "type" "arith_media")])
3149 (define_insn "andcdi3"
3150 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3151 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3152 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3155 [(set_attr "type" "arith_media")])
3157 (define_expand "iorsi3"
3158 [(set (match_operand:SI 0 "arith_reg_operand" "")
3159 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3160 (match_operand:SI 2 "logical_operand" "")))]
3164 (define_insn "*iorsi3_compact"
3165 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3166 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3167 (match_operand:SI 2 "logical_operand" "r,K08")))]
3170 [(set_attr "type" "arith")])
3172 (define_insn "*iorsi3_media"
3173 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3174 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3175 (match_operand:SI 2 "logical_operand" "r,I10")))]
3180 [(set_attr "type" "arith_media")])
3182 (define_insn "iordi3"
3183 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3184 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3185 (match_operand:DI 2 "logical_operand" "r,I10")))]
3190 [(set_attr "type" "arith_media")])
3192 (define_insn_and_split "*logical_sidi3"
3193 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3194 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3195 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3196 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3199 "&& reload_completed"
3200 [(set (match_dup 0) (match_dup 3))]
3204 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3205 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3206 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3209 (define_insn_and_split "*logical_sidisi3"
3210 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3211 (truncate:SI (sign_extend:DI
3212 (match_operator:SI 3 "logical_operator"
3213 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3214 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3218 [(set (match_dup 0) (match_dup 3))])
3220 (define_insn_and_split "*logical_sidi3_2"
3221 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3222 (sign_extend:DI (truncate:SI (sign_extend:DI
3223 (match_operator:SI 3 "logical_operator"
3224 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3225 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3229 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3231 (define_expand "xorsi3"
3232 [(set (match_operand:SI 0 "arith_reg_operand" "")
3233 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3234 (match_operand:SI 2 "xor_operand" "")))]
3238 (define_insn "*xorsi3_compact"
3239 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3240 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3241 (match_operand:SI 2 "logical_operand" "K08,r")))]
3244 [(set_attr "type" "arith")])
3246 (define_insn "*xorsi3_media"
3247 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3248 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3249 (match_operand:SI 2 "xor_operand" "r,I06")))]
3254 [(set_attr "type" "arith_media")])
3256 (define_insn "xordi3"
3257 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3258 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3259 (match_operand:DI 2 "xor_operand" "r,I06")))]
3264 [(set_attr "type" "arith_media")])
3266 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3267 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3269 [(set (match_operand:DI 0 "arith_reg_dest" "")
3270 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3271 [(match_operand 1 "any_register_operand" "")
3272 (match_operand 2 "any_register_operand" "")])))]
3274 [(set (match_dup 5) (match_dup 4))
3275 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3278 enum machine_mode inmode = GET_MODE (operands[1]);
3281 if (GET_CODE (operands[0]) == SUBREG)
3283 offset = SUBREG_BYTE (operands[0]);
3284 operands[0] = SUBREG_REG (operands[0]);
3286 gcc_assert (GET_CODE (operands[0]) == REG);
3287 if (! TARGET_LITTLE_ENDIAN)
3288 offset += 8 - GET_MODE_SIZE (inmode);
3289 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3292 ;; -------------------------------------------------------------------------
3293 ;; Shifts and rotates
3294 ;; -------------------------------------------------------------------------
3296 (define_expand "rotldi3"
3297 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3298 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3299 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3301 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3303 (define_insn "rotldi3_mextr"
3304 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3305 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3306 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3310 static char templ[16];
3312 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3313 8 - (int) (INTVAL (operands[2]) >> 3));
3316 [(set_attr "type" "arith_media")])
3318 (define_expand "rotrdi3"
3319 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3320 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3321 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3323 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3325 (define_insn "rotrdi3_mextr"
3326 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3327 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3328 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3332 static char templ[16];
3334 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3337 [(set_attr "type" "arith_media")])
3340 [(set (match_operand:DI 0 "arith_reg_dest" "")
3341 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3342 "ua_address_operand" "")))
3343 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3345 (clobber (match_operand:DI 3 "register_operand" ""))]
3347 [(match_dup 4) (match_dup 5)]
3350 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3351 (operands[3], operands[1]));
3352 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3353 GEN_INT (56), GEN_INT (8));
3356 (define_insn "rotlsi3_1"
3357 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3358 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3361 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3364 [(set_attr "type" "arith")])
3366 (define_insn "rotlsi3_31"
3367 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3368 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3370 (clobber (reg:SI T_REG))]
3373 [(set_attr "type" "arith")])
3375 (define_insn "rotlsi3_16"
3376 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3377 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3381 [(set_attr "type" "arith")])
3383 (define_expand "rotlsi3"
3384 [(set (match_operand:SI 0 "arith_reg_dest" "")
3385 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3386 (match_operand:SI 2 "immediate_operand" "")))]
3390 static const char rot_tab[] = {
3391 000, 000, 000, 000, 000, 000, 010, 001,
3392 001, 001, 011, 013, 003, 003, 003, 003,
3393 003, 003, 003, 003, 003, 013, 012, 002,
3394 002, 002, 010, 000, 000, 000, 000, 000,
3399 if (GET_CODE (operands[2]) != CONST_INT)
3401 count = INTVAL (operands[2]);
3402 choice = rot_tab[count];
3403 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3409 emit_move_insn (operands[0], operands[1]);
3410 count -= (count & 16) * 2;
3413 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3420 parts[0] = gen_reg_rtx (SImode);
3421 parts[1] = gen_reg_rtx (SImode);
3422 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3423 emit_move_insn (parts[choice-1], operands[1]);
3424 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3425 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3426 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3427 count = (count & ~16) - 8;
3431 for (; count > 0; count--)
3432 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3433 for (; count < 0; count++)
3434 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3439 (define_insn "*rotlhi3_8"
3440 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3441 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3445 [(set_attr "type" "arith")])
3447 (define_expand "rotlhi3"
3448 [(set (match_operand:HI 0 "arith_reg_operand" "")
3449 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3450 (match_operand:HI 2 "immediate_operand" "")))]
3454 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3461 (define_insn "ashlsi3_sh2a"
3462 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3463 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3464 (match_operand:SI 2 "arith_reg_operand" "r")))]
3467 [(set_attr "type" "arith")
3468 (set_attr "length" "4")])
3470 ;; This pattern is used by init_expmed for computing the costs of shift
3473 (define_insn_and_split "ashlsi3_std"
3474 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3475 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3476 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3477 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3479 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3480 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3488 && GET_CODE (operands[2]) == CONST_INT
3489 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3490 [(set (match_dup 3) (match_dup 2))
3492 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3493 (clobber (match_dup 4))])]
3494 "operands[4] = gen_rtx_SCRATCH (SImode);"
3495 [(set_attr "length" "*,*,*,4")
3496 (set_attr "type" "dyn_shift,arith,arith,arith")])
3498 (define_insn "ashlhi3_k"
3499 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3500 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3501 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3502 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3506 [(set_attr "type" "arith")])
3508 (define_insn "ashlsi3_n"
3509 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3510 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3511 (match_operand:SI 2 "const_int_operand" "n")))
3512 (clobber (reg:SI T_REG))]
3513 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3515 [(set (attr "length")
3516 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3518 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3520 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3522 (const_string "8")))
3523 (set_attr "type" "arith")])
3526 [(set (match_operand:SI 0 "arith_reg_dest" "")
3527 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3528 (match_operand:SI 2 "const_int_operand" "")))
3529 (clobber (reg:SI T_REG))]
3530 "TARGET_SH1 && reload_completed"
3531 [(use (reg:SI R0_REG))]
3534 gen_shifty_op (ASHIFT, operands);
3538 (define_insn "ashlsi3_media"
3539 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3540 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3541 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3546 [(set_attr "type" "arith_media")
3547 (set_attr "highpart" "ignore")])
3549 (define_expand "ashlsi3"
3550 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3551 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3552 (match_operand:SI 2 "nonmemory_operand" "")))
3553 (clobber (reg:SI T_REG))])]
3559 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3562 if (GET_CODE (operands[2]) == CONST_INT
3563 && sh_dynamicalize_shift_p (operands[2]))
3564 operands[2] = force_reg (SImode, operands[2]);
3567 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3570 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3574 (define_insn "*ashlhi3_n"
3575 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3576 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3577 (match_operand:HI 2 "const_int_operand" "n")))
3578 (clobber (reg:SI T_REG))]
3581 [(set (attr "length")
3582 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3584 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3586 (const_string "6")))
3587 (set_attr "type" "arith")])
3589 (define_expand "ashlhi3"
3590 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3591 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3592 (match_operand:SI 2 "nonmemory_operand" "")))
3593 (clobber (reg:SI T_REG))])]
3597 if (GET_CODE (operands[2]) != CONST_INT)
3599 /* It may be possible to call gen_ashlhi3 directly with more generic
3600 operands. Make sure operands[1] is a HImode register here. */
3601 if (!arith_reg_operand (operands[1], HImode))
3602 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3606 [(set (match_operand:HI 0 "arith_reg_dest" "")
3607 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3608 (match_operand:HI 2 "const_int_operand" "")))
3609 (clobber (reg:SI T_REG))]
3610 "TARGET_SH1 && reload_completed"
3611 [(use (reg:SI R0_REG))]
3614 gen_shifty_hi_op (ASHIFT, operands);
3619 ; arithmetic shift right
3622 (define_insn "ashrsi3_sh2a"
3623 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3624 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3625 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3628 [(set_attr "type" "dyn_shift")
3629 (set_attr "length" "4")])
3631 (define_insn "ashrsi3_k"
3632 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3633 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3634 (match_operand:SI 2 "const_int_operand" "M")))
3635 (clobber (reg:SI T_REG))]
3636 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3638 [(set_attr "type" "arith")])
3640 ;; We can't do HImode right shifts correctly unless we start out with an
3641 ;; explicit zero / sign extension; doing that would result in worse overall
3642 ;; code, so just let the machine independent code widen the mode.
3643 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3646 ;; ??? This should be a define expand.
3648 (define_insn "ashrsi2_16"
3649 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3650 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3654 [(set_attr "length" "4")])
3657 [(set (match_operand:SI 0 "arith_reg_dest" "")
3658 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3661 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3662 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3663 "operands[2] = gen_lowpart (HImode, operands[0]);")
3665 ;; ??? This should be a define expand.
3667 (define_insn "ashrsi2_31"
3668 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3669 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3671 (clobber (reg:SI T_REG))]
3674 [(set_attr "length" "4")])
3677 [(set (match_operand:SI 0 "arith_reg_dest" "")
3678 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3680 (clobber (reg:SI T_REG))]
3685 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3686 emit_insn (gen_mov_neg_si_t (operands[0]));
3691 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3693 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3695 && peep2_reg_dead_p (2, operands[0])
3696 && peep2_reg_dead_p (2, operands[1])"
3700 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3704 (define_insn "ashlsi_c"
3705 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3706 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3708 (lt:SI (match_dup 1) (const_int 0)))]
3711 [(set_attr "type" "arith")])
3713 (define_insn "*ashlsi_c_void"
3714 [(set (reg:SI T_REG)
3715 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3716 (clobber (match_scratch:SI 1 "=0"))]
3717 "TARGET_SH1 && cse_not_expected"
3719 [(set_attr "type" "arith")])
3721 (define_insn "ashrsi3_d"
3722 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3723 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3724 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3727 [(set_attr "type" "dyn_shift")])
3729 (define_insn "ashrsi3_n"
3730 [(set (reg:SI R4_REG)
3731 (ashiftrt:SI (reg:SI R4_REG)
3732 (match_operand:SI 0 "const_int_operand" "i")))
3733 (clobber (reg:SI T_REG))
3734 (clobber (reg:SI PR_REG))
3735 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3738 [(set_attr "type" "sfunc")
3739 (set_attr "needs_delay_slot" "yes")])
3741 (define_insn "ashrsi3_media"
3742 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3743 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3744 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3749 [(set_attr "type" "arith_media")
3750 (set_attr "highpart" "ignore")])
3752 (define_expand "ashrsi3"
3753 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3754 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3755 (match_operand:SI 2 "nonmemory_operand" "")))
3756 (clobber (reg:SI T_REG))])]
3762 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3765 if (expand_ashiftrt (operands))
3771 ;; logical shift right
3773 (define_insn "lshrsi3_sh2a"
3774 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3776 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3779 [(set_attr "type" "dyn_shift")
3780 (set_attr "length" "4")])
3782 (define_insn "lshrsi3_d"
3783 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3784 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3785 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3788 [(set_attr "type" "dyn_shift")])
3790 ;; Only the single bit shift clobbers the T bit.
3792 (define_insn "lshrsi3_m"
3793 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3794 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3795 (match_operand:SI 2 "const_int_operand" "M")))
3796 (clobber (reg:SI T_REG))]
3797 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3799 [(set_attr "type" "arith")])
3801 (define_insn "lshrsi3_k"
3802 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3803 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3804 (match_operand:SI 2 "const_int_operand" "P27")))]
3805 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3806 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3808 [(set_attr "type" "arith")])
3810 (define_insn "lshrsi3_n"
3811 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3812 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3813 (match_operand:SI 2 "const_int_operand" "n")))
3814 (clobber (reg:SI T_REG))]
3815 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3817 [(set (attr "length")
3818 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3820 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3822 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3824 (const_string "8")))
3825 (set_attr "type" "arith")])
3828 [(set (match_operand:SI 0 "arith_reg_dest" "")
3829 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3830 (match_operand:SI 2 "const_int_operand" "")))
3831 (clobber (reg:SI T_REG))]
3832 "TARGET_SH1 && reload_completed"
3833 [(use (reg:SI R0_REG))]
3836 gen_shifty_op (LSHIFTRT, operands);
3840 (define_insn "lshrsi3_media"
3841 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3842 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3843 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3848 [(set_attr "type" "arith_media")
3849 (set_attr "highpart" "ignore")])
3851 (define_expand "lshrsi3"
3852 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3853 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3854 (match_operand:SI 2 "nonmemory_operand" "")))
3855 (clobber (reg:SI T_REG))])]
3861 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3864 if (GET_CODE (operands[2]) == CONST_INT
3865 && sh_dynamicalize_shift_p (operands[2]))
3866 operands[2] = force_reg (SImode, operands[2]);
3867 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3869 rtx count = copy_to_mode_reg (SImode, operands[2]);
3870 emit_insn (gen_negsi2 (count, count));
3871 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3874 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3878 ;; ??? This should be a define expand.
3880 (define_insn "ashldi3_k"
3881 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3882 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3884 (clobber (reg:SI T_REG))]
3886 "shll %R0\;rotcl %S0"
3887 [(set_attr "length" "4")
3888 (set_attr "type" "arith")])
3890 (define_insn "ashldi3_media"
3891 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3892 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3893 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3898 [(set_attr "type" "arith_media")])
3900 (define_insn "*ashldisi3_media"
3901 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3902 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3903 (match_operand:DI 2 "const_int_operand" "n")))]
3904 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3905 "shlli.l %1, %2, %0"
3906 [(set_attr "type" "arith_media")
3907 (set_attr "highpart" "ignore")])
3909 (define_expand "ashldi3"
3910 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3911 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3912 (match_operand:DI 2 "immediate_operand" "")))
3913 (clobber (reg:SI T_REG))])]
3919 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3922 if (GET_CODE (operands[2]) != CONST_INT
3923 || INTVAL (operands[2]) != 1)
3927 ;; ??? This should be a define expand.
3929 (define_insn "lshrdi3_k"
3930 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3931 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3933 (clobber (reg:SI T_REG))]
3935 "shlr %S0\;rotcr %R0"
3936 [(set_attr "length" "4")
3937 (set_attr "type" "arith")])
3939 (define_insn "lshrdi3_media"
3940 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3941 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3942 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3944 && (arith_reg_dest (operands[0], DImode)
3945 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3949 [(set_attr "type" "arith_media")])
3951 (define_insn "*lshrdisi3_media"
3952 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3953 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3954 (match_operand:DI 2 "const_int_operand" "n")))]
3955 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3956 "shlri.l %1, %2, %0"
3957 [(set_attr "type" "arith_media")
3958 (set_attr "highpart" "ignore")])
3960 (define_expand "lshrdi3"
3961 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3962 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3963 (match_operand:DI 2 "immediate_operand" "")))
3964 (clobber (reg:SI T_REG))])]
3970 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3973 if (GET_CODE (operands[2]) != CONST_INT
3974 || INTVAL (operands[2]) != 1)
3978 ;; ??? This should be a define expand.
3980 (define_insn "ashrdi3_k"
3981 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3982 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3984 (clobber (reg:SI T_REG))]
3986 "shar %S0\;rotcr %R0"
3987 [(set_attr "length" "4")
3988 (set_attr "type" "arith")])
3990 (define_insn "ashrdi3_media"
3991 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3992 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3993 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3995 && (arith_reg_dest (operands[0], DImode)
3996 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4000 [(set_attr "type" "arith_media")])
4002 (define_insn "*ashrdisi3_media"
4003 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4004 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4005 (match_operand:DI 2 "const_int_operand" "n")))]
4006 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4007 "shari.l %1, %2, %0"
4008 [(set_attr "type" "arith_media")
4009 (set_attr "highpart" "ignore")])
4011 (define_insn "ashrdisi3_media_high"
4012 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4014 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4015 (match_operand:DI 2 "const_int_operand" "n"))))]
4016 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4018 [(set_attr "type" "arith_media")])
4020 (define_insn "ashrdisi3_media_opaque"
4021 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4022 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4023 (match_operand:DI 2 "const_int_operand" "n")]
4027 [(set_attr "type" "arith_media")])
4029 (define_expand "ashrdi3"
4030 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4031 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4032 (match_operand:DI 2 "immediate_operand" "")))
4033 (clobber (reg:SI T_REG))])]
4039 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4042 if (GET_CODE (operands[2]) != CONST_INT
4043 || INTVAL (operands[2]) != 1)
4047 ;; combined left/right shift
4050 [(set (match_operand:SI 0 "register_operand" "")
4051 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4052 (match_operand:SI 2 "const_int_operand" ""))
4053 (match_operand:SI 3 "const_int_operand" "")))]
4054 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4055 [(use (reg:SI R0_REG))]
4056 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4060 [(set (match_operand:SI 0 "register_operand" "")
4061 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4062 (match_operand:SI 2 "const_int_operand" ""))
4063 (match_operand:SI 3 "const_int_operand" "")))
4064 (clobber (reg:SI T_REG))]
4065 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4066 [(use (reg:SI R0_REG))]
4067 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4071 [(set (match_operand:SI 0 "register_operand" "=r")
4072 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4073 (match_operand:SI 2 "const_int_operand" "n"))
4074 (match_operand:SI 3 "const_int_operand" "n")))
4075 (clobber (reg:SI T_REG))]
4076 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4078 [(set (attr "length")
4079 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4081 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4083 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4085 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4087 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4089 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4091 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4092 (const_string "16")]
4093 (const_string "18")))
4094 (set_attr "type" "arith")])
4097 [(set (match_operand:SI 0 "register_operand" "=z")
4098 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4099 (match_operand:SI 2 "const_int_operand" "n"))
4100 (match_operand:SI 3 "const_int_operand" "n")))
4101 (clobber (reg:SI T_REG))]
4102 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4104 [(set (attr "length")
4105 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4107 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4109 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4111 (const_string "10")))
4112 (set_attr "type" "arith")])
4114 ;; shift left / and combination with a scratch register: The combine pass
4115 ;; does not accept the individual instructions, even though they are
4116 ;; cheap. But it needs a precise description so that it is usable after
4118 (define_insn "and_shl_scratch"
4119 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4123 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4124 (match_operand:SI 2 "const_int_operand" "N,n"))
4125 (match_operand:SI 3 "" "0,r"))
4126 (match_operand:SI 4 "const_int_operand" "n,n"))
4127 (match_operand:SI 5 "const_int_operand" "n,n")))
4128 (clobber (reg:SI T_REG))]
4131 [(set (attr "length")
4132 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4134 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4136 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4138 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4139 (const_string "10")]
4140 (const_string "12")))
4141 (set_attr "type" "arith")])
4144 [(set (match_operand:SI 0 "register_operand" "")
4148 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4149 (match_operand:SI 2 "const_int_operand" ""))
4150 (match_operand:SI 3 "register_operand" ""))
4151 (match_operand:SI 4 "const_int_operand" ""))
4152 (match_operand:SI 5 "const_int_operand" "")))
4153 (clobber (reg:SI T_REG))]
4155 [(use (reg:SI R0_REG))]
4158 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4160 if (INTVAL (operands[2]))
4162 gen_shifty_op (LSHIFTRT, operands);
4164 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4165 operands[2] = operands[4];
4166 gen_shifty_op (ASHIFT, operands);
4167 if (INTVAL (operands[5]))
4169 operands[2] = operands[5];
4170 gen_shifty_op (LSHIFTRT, operands);
4175 ;; signed left/right shift combination.
4177 [(set (match_operand:SI 0 "register_operand" "")
4179 (ashift:SI (match_operand:SI 1 "register_operand" "")
4180 (match_operand:SI 2 "const_int_operand" ""))
4181 (match_operand:SI 3 "const_int_operand" "")
4183 (clobber (reg:SI T_REG))]
4185 [(use (reg:SI R0_REG))]
4186 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4189 (define_insn "shl_sext_ext"
4190 [(set (match_operand:SI 0 "register_operand" "=r")
4192 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4193 (match_operand:SI 2 "const_int_operand" "n"))
4194 (match_operand:SI 3 "const_int_operand" "n")
4196 (clobber (reg:SI T_REG))]
4197 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4199 [(set (attr "length")
4200 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4202 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4204 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4206 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4208 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4210 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4212 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4214 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4215 (const_string "16")]
4216 (const_string "18")))
4217 (set_attr "type" "arith")])
4219 (define_insn "shl_sext_sub"
4220 [(set (match_operand:SI 0 "register_operand" "=z")
4222 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4223 (match_operand:SI 2 "const_int_operand" "n"))
4224 (match_operand:SI 3 "const_int_operand" "n")
4226 (clobber (reg:SI T_REG))]
4227 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4229 [(set (attr "length")
4230 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4232 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4234 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4236 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4237 (const_string "12")]
4238 (const_string "14")))
4239 (set_attr "type" "arith")])
4241 ;; These patterns are found in expansions of DImode shifts by 16, and
4242 ;; allow the xtrct instruction to be generated from C source.
4244 (define_insn "xtrct_left"
4245 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4246 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4248 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4252 [(set_attr "type" "arith")])
4254 (define_insn "xtrct_right"
4255 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4256 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4258 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4262 [(set_attr "type" "arith")])
4264 ;; -------------------------------------------------------------------------
4266 ;; -------------------------------------------------------------------------
4269 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4270 (neg:SI (plus:SI (reg:SI T_REG)
4271 (match_operand:SI 1 "arith_reg_operand" "r"))))
4273 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4277 [(set_attr "type" "arith")])
4279 (define_insn "*negdi_media"
4280 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4281 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4284 [(set_attr "type" "arith_media")])
4286 (define_expand "negdi2"
4287 [(set (match_operand:DI 0 "arith_reg_operand" "")
4288 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4294 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4295 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4297 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4298 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4300 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4301 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4303 emit_insn (gen_clrt ());
4304 emit_insn (gen_negc (low_dst, low_src));
4305 emit_insn (gen_negc (high_dst, high_src));
4310 (define_insn "negsi2"
4311 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4312 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4315 [(set_attr "type" "arith")])
4317 (define_insn "one_cmplsi2"
4318 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4319 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4322 [(set_attr "type" "arith")])
4324 (define_expand "one_cmpldi2"
4325 [(set (match_operand:DI 0 "arith_reg_dest" "")
4326 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4328 "TARGET_SHMEDIA" "")
4330 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4331 This can be used as some kind of conditional execution, which is useful
4334 [(set (match_operand:SI 0 "arith_reg_dest" "")
4335 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4336 (match_operand:SI 1 "arith_reg_operand" ""))
4340 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4341 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4345 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4346 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4347 (match_operand:SI 1 "arith_reg_operand" "0")
4348 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4350 "bf 0f\;neg %2,%0\\n0:"
4351 [(set_attr "type" "arith") ;; poor approximation
4352 (set_attr "length" "4")])
4355 ;; -------------------------------------------------------------------------
4356 ;; Zero extension instructions
4357 ;; -------------------------------------------------------------------------
4359 (define_insn "zero_extendsidi2"
4360 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4361 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4363 "addz.l %1, r63, %0"
4364 [(set_attr "type" "arith_media")
4365 (set_attr "highpart" "extend")])
4367 (define_insn "zero_extendhidi2"
4368 [(set (match_operand:DI 0 "register_operand" "=r,r")
4369 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4374 [(set_attr "type" "*,load_media")
4375 (set (attr "highpart")
4376 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4377 (const_string "user")]
4378 (const_string "ignore")))])
4381 [(set (match_operand:DI 0 "register_operand" "")
4382 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4383 "TARGET_SHMEDIA && reload_completed"
4384 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4385 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4388 if (GET_CODE (operands[1]) == TRUNCATE)
4389 operands[1] = XEXP (operands[1], 0);
4392 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4393 ;; reload the entire truncate expression.
4394 (define_insn_and_split "*loaddi_trunc"
4395 [(set (match_operand 0 "any_register_operand" "=r")
4396 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4397 "TARGET_SHMEDIA && reload_completed"
4399 "TARGET_SHMEDIA && reload_completed"
4400 [(set (match_dup 0) (match_dup 1))]
4401 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4403 (define_insn "zero_extendqidi2"
4404 [(set (match_operand:DI 0 "register_operand" "=r,r")
4405 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4410 [(set_attr "type" "arith_media,load_media")
4411 (set (attr "highpart")
4412 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4413 (const_string "user")]
4414 (const_string "ignore")))])
4416 (define_expand "zero_extendhisi2"
4417 [(set (match_operand:SI 0 "arith_reg_operand" "")
4418 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4422 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4423 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4426 (define_insn "*zero_extendhisi2_compact"
4427 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4428 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4431 [(set_attr "type" "arith")])
4433 (define_insn "*zero_extendhisi2_media"
4434 [(set (match_operand:SI 0 "register_operand" "=r,r")
4435 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4440 [(set_attr "type" "arith_media,load_media")
4441 (set (attr "highpart")
4442 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4443 (const_string "user")]
4444 (const_string "ignore")))])
4447 [(set (match_operand:SI 0 "register_operand" "")
4448 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4449 "TARGET_SHMEDIA && reload_completed"
4450 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4451 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4454 rtx op1 = operands[1];
4456 if (GET_CODE (op1) == TRUNCATE)
4457 op1 = XEXP (op1, 0);
4459 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4460 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4463 (define_expand "zero_extendqisi2"
4464 [(set (match_operand:SI 0 "arith_reg_operand" "")
4465 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4469 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4470 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4473 (define_insn "*zero_extendqisi2_compact"
4474 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4475 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4478 [(set_attr "type" "arith")])
4480 (define_insn "*zero_extendqisi2_media"
4481 [(set (match_operand:SI 0 "register_operand" "=r,r")
4482 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4487 [(set_attr "type" "arith_media,load_media")
4488 (set (attr "highpart")
4489 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4490 (const_string "user")]
4491 (const_string "ignore")))])
4493 (define_insn "zero_extendqihi2"
4494 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4495 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4498 [(set_attr "type" "arith")])
4500 ;; -------------------------------------------------------------------------
4501 ;; Sign extension instructions
4502 ;; -------------------------------------------------------------------------
4504 ;; ??? This should be a define expand.
4505 ;; ??? Or perhaps it should be dropped?
4507 ;; convert_move generates good code for SH[1-4].
4508 (define_insn "extendsidi2"
4509 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4510 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4516 [(set_attr "type" "arith_media,load_media,fpconv_media")
4517 (set (attr "highpart")
4518 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4519 (const_string "user")]
4520 (const_string "extend")))])
4522 (define_insn "extendhidi2"
4523 [(set (match_operand:DI 0 "register_operand" "=r,r")
4524 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4529 [(set_attr "type" "*,load_media")
4530 (set (attr "highpart")
4531 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4532 (const_string "user")]
4533 (const_string "ignore")))])
4536 [(set (match_operand:DI 0 "register_operand" "")
4537 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4538 "TARGET_SHMEDIA && reload_completed"
4539 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4540 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4543 if (GET_CODE (operands[1]) == TRUNCATE)
4544 operands[1] = XEXP (operands[1], 0);
4547 (define_insn "extendqidi2"
4548 [(set (match_operand:DI 0 "register_operand" "=r,r")
4549 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4554 [(set_attr "type" "*,load_media")
4555 (set (attr "highpart")
4556 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4557 (const_string "user")]
4558 (const_string "ignore")))])
4561 [(set (match_operand:DI 0 "register_operand" "")
4562 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4563 "TARGET_SHMEDIA && reload_completed"
4564 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4565 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4568 if (GET_CODE (operands[1]) == TRUNCATE)
4569 operands[1] = XEXP (operands[1], 0);
4572 (define_expand "extendhisi2"
4573 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4574 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4578 (define_insn "*extendhisi2_compact"
4579 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4580 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4585 [(set_attr "type" "arith,load")])
4587 (define_insn "*extendhisi2_media"
4588 [(set (match_operand:SI 0 "register_operand" "=r,r")
4589 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4594 [(set_attr "type" "arith_media,load_media")
4595 (set (attr "highpart")
4596 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4597 (const_string "user")]
4598 (const_string "ignore")))])
4601 [(set (match_operand:SI 0 "register_operand" "")
4602 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4603 "TARGET_SHMEDIA && reload_completed"
4604 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4605 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4608 rtx op1 = operands[1];
4609 if (GET_CODE (op1) == TRUNCATE)
4610 op1 = XEXP (op1, 0);
4612 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4613 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4616 (define_expand "extendqisi2"
4617 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4618 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4622 (define_insn "*extendqisi2_compact"
4623 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4624 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4629 [(set_attr "type" "arith,load")])
4631 (define_insn "*extendqisi2_media"
4632 [(set (match_operand:SI 0 "register_operand" "=r,r")
4633 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4638 [(set_attr "type" "arith_media,load_media")
4639 (set (attr "highpart")
4640 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4641 (const_string "user")]
4642 (const_string "ignore")))])
4645 [(set (match_operand:SI 0 "register_operand" "")
4646 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4647 "TARGET_SHMEDIA && reload_completed"
4648 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4649 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4652 rtx op1 = operands[1];
4653 if (GET_CODE (op1) == TRUNCATE)
4654 op1 = XEXP (op1, 0);
4656 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4657 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4660 (define_insn "extendqihi2"
4661 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4662 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4667 [(set_attr "type" "arith,load")])
4669 /* It would seem useful to combine the truncXi patterns into the movXi
4670 patterns, but unary operators are ignored when matching constraints,
4671 so we need separate patterns. */
4672 (define_insn "truncdisi2"
4673 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4674 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4683 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4684 (set (attr "highpart")
4685 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4686 (const_string "user")]
4687 (const_string "extend")))])
4689 (define_insn "truncdihi2"
4690 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4691 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4694 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4696 [(set_attr "type" "arith_media,store_media")
4697 (set_attr "length" "8,4")
4698 (set (attr "highpart")
4699 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4700 (const_string "user")]
4701 (const_string "extend")))])
4703 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4704 ; Because we use zero extension, we can't provide signed QImode compares
4705 ; using a simple compare or conditional banch insn.
4706 (define_insn "truncdiqi2"
4707 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4708 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4713 [(set_attr "type" "arith_media,store")
4714 (set (attr "highpart")
4715 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4716 (const_string "user")]
4717 (const_string "extend")))])
4718 ;; -------------------------------------------------------------------------
4719 ;; Move instructions
4720 ;; -------------------------------------------------------------------------
4722 ;; define push and pop so it is easy for sh.c
4723 ;; We can't use push and pop on SHcompact because the stack must always
4724 ;; be 8-byte aligned.
4726 (define_expand "push"
4727 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4728 (match_operand:SI 0 "register_operand" "r,l,x"))]
4729 "TARGET_SH1 && ! TARGET_SH5"
4732 (define_expand "pop"
4733 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4734 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4735 "TARGET_SH1 && ! TARGET_SH5"
4738 (define_expand "push_e"
4739 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4740 (match_operand:SF 0 "" ""))
4741 (use (reg:PSI FPSCR_REG))
4742 (clobber (scratch:SI))])]
4743 "TARGET_SH1 && ! TARGET_SH5"
4746 (define_insn "push_fpul"
4747 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4748 "TARGET_SH2E && ! TARGET_SH5"
4750 [(set_attr "type" "store")
4751 (set_attr "late_fp_use" "yes")
4752 (set_attr "hit_stack" "yes")])
4754 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4756 (define_expand "push_4"
4757 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4758 (match_operand:DF 0 "" ""))
4759 (use (reg:PSI FPSCR_REG))
4760 (clobber (scratch:SI))])]
4761 "TARGET_SH1 && ! TARGET_SH5"
4764 (define_expand "pop_e"
4765 [(parallel [(set (match_operand:SF 0 "" "")
4766 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4767 (use (reg:PSI FPSCR_REG))
4768 (clobber (scratch:SI))])]
4769 "TARGET_SH1 && ! TARGET_SH5"
4772 (define_insn "pop_fpul"
4773 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4774 "TARGET_SH2E && ! TARGET_SH5"
4776 [(set_attr "type" "load")
4777 (set_attr "hit_stack" "yes")])
4779 (define_expand "pop_4"
4780 [(parallel [(set (match_operand:DF 0 "" "")
4781 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4782 (use (reg:PSI FPSCR_REG))
4783 (clobber (scratch:SI))])]
4784 "TARGET_SH1 && ! TARGET_SH5"
4787 (define_expand "push_fpscr"
4792 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4793 gen_rtx_PRE_DEC (Pmode,
4794 stack_pointer_rtx)),
4796 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4800 (define_expand "pop_fpscr"
4805 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4806 gen_frame_mem (PSImode,
4807 gen_rtx_POST_INC (Pmode,
4808 stack_pointer_rtx))));
4809 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4813 ;; These two patterns can happen as the result of optimization, when
4814 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4815 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4818 [(set (reg:SI T_REG) (const_int 0))]
4823 [(set (reg:SI T_REG) (const_int 1))]
4827 ;; t/r must come after r/r, lest reload will try to reload stuff like
4828 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4829 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4830 (define_insn "movsi_i"
4831 [(set (match_operand:SI 0 "general_movdst_operand"
4832 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4833 (match_operand:SI 1 "general_movsrc_operand"
4834 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4838 && (register_operand (operands[0], SImode)
4839 || register_operand (operands[1], SImode))"
4856 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4857 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4859 ;; t/r must come after r/r, lest reload will try to reload stuff like
4860 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4861 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4862 ;; will require a reload.
4863 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4864 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4865 (define_insn "movsi_ie"
4866 [(set (match_operand:SI 0 "general_movdst_operand"
4867 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4868 (match_operand:SI 1 "general_movsrc_operand"
4869 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4870 "(TARGET_SH2E || TARGET_SH2A)
4871 && (register_operand (operands[0], SImode)
4872 || register_operand (operands[1], SImode))"
4897 ! move optimized away"
4898 [(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")
4899 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4900 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4902 (define_insn "movsi_i_lowpart"
4903 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4904 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4906 && (register_operand (operands[0], SImode)
4907 || register_operand (operands[1], SImode))"
4917 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4919 (define_insn_and_split "load_ra"
4920 [(set (match_operand:SI 0 "general_movdst_operand" "")
4921 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4924 "&& ! currently_expanding_to_rtl"
4925 [(set (match_dup 0) (match_dup 1))]
4928 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4929 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4932 ;; The '?'s in the following constraints may not reflect the time taken
4933 ;; to perform the move. They are there to discourage the use of floating-
4934 ;; point registers for storing integer values.
4935 (define_insn "*movsi_media"
4936 [(set (match_operand:SI 0 "general_movdst_operand"
4937 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4938 (match_operand:SI 1 "general_movsrc_operand"
4939 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4941 && (register_operand (operands[0], SImode)
4942 || sh_register_operand (operands[1], SImode)
4943 || GET_CODE (operands[1]) == TRUNCATE)"
4958 [(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")
4959 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4960 (set (attr "highpart")
4961 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4962 (const_string "user")]
4963 (const_string "ignore")))])
4965 (define_insn "*movsi_media_nofpu"
4966 [(set (match_operand:SI 0 "general_movdst_operand"
4967 "=r,r,r,r,m,*b,r,*b")
4968 (match_operand:SI 1 "general_movsrc_operand"
4969 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
4971 && (register_operand (operands[0], SImode)
4972 || sh_register_operand (operands[1], SImode)
4973 || GET_CODE (operands[1]) == TRUNCATE)"
4983 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4984 (set_attr "length" "4,4,8,4,4,4,4,12")
4985 (set (attr "highpart")
4986 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4987 (const_string "user")]
4988 (const_string "ignore")))])
4990 (define_expand "movsi_const"
4991 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4992 (const:SI (sign_extend:SI
4995 (match_operand:DI 1 "immediate_operand" "s")
4998 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5001 (truncate:HI (match_dup 1))))))]
5002 "TARGET_SHMEDIA && reload_completed
5003 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5006 if (GET_CODE (operands[1]) == LABEL_REF
5007 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5008 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5009 else if (GOTOFF_P (operands[1]))
5011 rtx unspec = XEXP (operands[1], 0);
5013 if (! UNSPEC_GOTOFF_P (unspec))
5015 unspec = XEXP (unspec, 0);
5016 if (! UNSPEC_GOTOFF_P (unspec))
5019 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5020 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5021 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5025 (define_expand "movsi_const_16bit"
5026 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5027 (const:SI (sign_extend:SI
5029 (match_operand:DI 1 "immediate_operand" "s")))))]
5030 "TARGET_SHMEDIA && flag_pic && reload_completed
5031 && GET_CODE (operands[1]) == SYMBOL_REF"
5035 [(set (match_operand:SI 0 "arith_reg_dest" "")
5036 (match_operand:SI 1 "immediate_operand" ""))]
5037 "TARGET_SHMEDIA && reload_completed
5038 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5042 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5044 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5051 [(set (match_operand:SI 0 "register_operand" "")
5052 (match_operand:SI 1 "immediate_operand" ""))]
5053 "TARGET_SHMEDIA && reload_completed
5054 && ((GET_CODE (operands[1]) == CONST_INT
5055 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5056 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5057 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5059 (define_expand "movsi"
5060 [(set (match_operand:SI 0 "general_movdst_operand" "")
5061 (match_operand:SI 1 "general_movsrc_operand" ""))]
5063 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5065 (define_expand "ic_invalidate_line"
5066 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5067 (match_dup 1)] UNSPEC_ICACHE)
5068 (clobber (scratch:SI))])]
5069 "TARGET_HARD_SH4 || TARGET_SH5"
5074 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5077 else if (TARGET_SHCOMPACT)
5079 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5080 operands[1] = force_reg (Pmode, operands[1]);
5081 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5084 else if (TARGET_SH4A_ARCH)
5086 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5089 operands[0] = force_reg (Pmode, operands[0]);
5090 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5094 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5095 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5096 ;; the requirement *1*00 for associative address writes. The alignment of
5097 ;; %0 implies that its least significant bit is cleared,
5098 ;; thus we clear the V bit of a matching entry if there is one.
5099 (define_insn "ic_invalidate_line_i"
5100 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5101 (match_operand:SI 1 "register_operand" "r")]
5103 (clobber (match_scratch:SI 2 "=&r"))]
5105 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5106 [(set_attr "length" "8")
5107 (set_attr "type" "cwb")])
5109 (define_insn "ic_invalidate_line_sh4a"
5110 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5113 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5114 [(set_attr "length" "16")
5115 (set_attr "type" "cwb")])
5117 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5118 ;; an add in the code that calculates the address.
5119 (define_insn "ic_invalidate_line_media"
5120 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5123 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5124 [(set_attr "length" "16")
5125 (set_attr "type" "invalidate_line_media")])
5127 (define_insn "ic_invalidate_line_compact"
5128 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5129 (match_operand:SI 1 "register_operand" "r")]
5131 (clobber (reg:SI PR_REG))]
5134 [(set_attr "type" "sfunc")
5135 (set_attr "needs_delay_slot" "yes")])
5137 (define_expand "initialize_trampoline"
5138 [(match_operand:SI 0 "" "")
5139 (match_operand:SI 1 "" "")
5140 (match_operand:SI 2 "" "")]
5146 tramp = force_reg (Pmode, operands[0]);
5147 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5149 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5150 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5152 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5156 (define_insn "initialize_trampoline_compact"
5157 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5158 (match_operand:SI 1 "register_operand" "r")
5159 (reg:SI R2_REG) (reg:SI R3_REG)]
5162 (clobber (reg:SI PR_REG))]
5165 [(set_attr "type" "sfunc")
5166 (set_attr "needs_delay_slot" "yes")])
5168 (define_insn "movqi_i"
5169 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5170 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
5172 && (arith_reg_operand (operands[0], QImode)
5173 || arith_reg_operand (operands[1], QImode))"
5181 [(set_attr "type" "move,load,store,move,move,move")])
5183 (define_insn "*movqi_media"
5184 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5185 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5187 && (arith_reg_operand (operands[0], QImode)
5188 || extend_reg_or_0_operand (operands[1], QImode))"
5194 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5195 (set (attr "highpart")
5196 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5197 (const_string "user")]
5198 (const_string "ignore")))])
5200 (define_expand "movqi"
5201 [(set (match_operand:QI 0 "general_operand" "")
5202 (match_operand:QI 1 "general_operand" ""))]
5204 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5206 (define_expand "reload_inqi"
5207 [(set (match_operand:SI 2 "" "=&r")
5208 (match_operand:QI 1 "inqhi_operand" ""))
5209 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5210 (truncate:QI (match_dup 3)))]
5214 rtx inner = XEXP (operands[1], 0);
5215 int regno = REGNO (inner);
5217 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5218 operands[1] = gen_rtx_REG (SImode, regno);
5219 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5222 /* When storing r0, we have to avoid reg+reg addressing. */
5223 (define_insn "movhi_i"
5224 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5225 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5227 && (arith_reg_operand (operands[0], HImode)
5228 || arith_reg_operand (operands[1], HImode))
5229 && (GET_CODE (operands[0]) != MEM
5230 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5231 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5232 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5242 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5244 (define_insn "*movhi_media"
5245 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5246 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5248 && (arith_reg_operand (operands[0], HImode)
5249 || arith_reg_or_0_operand (operands[1], HImode))"
5256 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5257 (set (attr "highpart")
5258 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5259 (const_string "user")]
5260 (const_string "ignore")))])
5263 [(set (match_operand:HI 0 "register_operand" "")
5264 (match_operand:HI 1 "immediate_operand" ""))]
5265 "TARGET_SHMEDIA && reload_completed
5266 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5267 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5269 (define_expand "movhi"
5270 [(set (match_operand:HI 0 "general_movdst_operand" "")
5271 (match_operand:HI 1 "general_movsrc_operand" ""))]
5273 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5275 (define_expand "reload_inhi"
5276 [(set (match_operand:SI 2 "" "=&r")
5277 (match_operand:HI 1 "inqhi_operand" ""))
5278 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5279 (truncate:HI (match_dup 3)))]
5283 rtx inner = XEXP (operands[1], 0);
5284 int regno = REGNO (inner);
5286 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5287 operands[1] = gen_rtx_REG (SImode, regno);
5288 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5291 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5292 ;; compiled with -m2 -ml -O3 -funroll-loops
5293 (define_insn "*movdi_i"
5294 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5295 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5297 && (arith_reg_operand (operands[0], DImode)
5298 || arith_reg_operand (operands[1], DImode))"
5299 "* return output_movedouble (insn, operands, DImode);"
5300 [(set_attr "length" "4")
5301 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5303 ;; If the output is a register and the input is memory or a register, we have
5304 ;; to be careful and see which word needs to be loaded first.
5307 [(set (match_operand:DI 0 "general_movdst_operand" "")
5308 (match_operand:DI 1 "general_movsrc_operand" ""))]
5309 "TARGET_SH1 && reload_completed"
5310 [(set (match_dup 2) (match_dup 3))
5311 (set (match_dup 4) (match_dup 5))]
5316 if ((GET_CODE (operands[0]) == MEM
5317 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5318 || (GET_CODE (operands[1]) == MEM
5319 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5322 switch (GET_CODE (operands[0]))
5325 regno = REGNO (operands[0]);
5328 regno = subreg_regno (operands[0]);
5338 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5340 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5341 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5342 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5343 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5347 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5348 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5349 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5350 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5353 if (operands[2] == 0 || operands[3] == 0
5354 || operands[4] == 0 || operands[5] == 0)
5358 ;; The '?'s in the following constraints may not reflect the time taken
5359 ;; to perform the move. They are there to discourage the use of floating-
5360 ;; point registers for storing integer values.
5361 (define_insn "*movdi_media"
5362 [(set (match_operand:DI 0 "general_movdst_operand"
5363 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5364 (match_operand:DI 1 "general_movsrc_operand"
5365 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5367 && (register_operand (operands[0], DImode)
5368 || sh_register_operand (operands[1], DImode))"
5383 [(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")
5384 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5386 (define_insn "*movdi_media_nofpu"
5387 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5388 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5390 && (register_operand (operands[0], DImode)
5391 || sh_register_operand (operands[1], DImode))"
5401 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5402 (set_attr "length" "4,4,16,4,4,4,4,*")])
5404 (define_insn "*movdi_media_I16"
5405 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5406 (match_operand:DI 1 "const_int_operand" "I16"))]
5407 "TARGET_SHMEDIA && reload_completed"
5409 [(set_attr "type" "arith_media")
5410 (set_attr "length" "4")])
5413 [(set (match_operand:DI 0 "arith_reg_dest" "")
5414 (match_operand:DI 1 "immediate_operand" ""))]
5415 "TARGET_SHMEDIA && reload_completed
5416 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5417 [(set (match_dup 0) (match_dup 1))]
5422 if (TARGET_SHMEDIA64)
5423 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5425 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5427 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5433 (define_expand "movdi_const"
5434 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5435 (const:DI (sign_extend:DI
5438 (match_operand:DI 1 "immediate_operand" "s")
5441 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5447 (const_int 32)))))))
5449 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5455 (const_int 16)))))))
5457 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5462 "TARGET_SHMEDIA64 && reload_completed
5463 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5466 sh_mark_label (operands[1], 4);
5469 (define_expand "movdi_const_32bit"
5470 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5471 (const:DI (sign_extend:DI
5474 (match_operand:DI 1 "immediate_operand" "s")
5477 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5482 "TARGET_SHMEDIA32 && reload_completed
5483 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5486 sh_mark_label (operands[1], 2);
5489 (define_expand "movdi_const_16bit"
5490 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5491 (const:DI (sign_extend:DI
5493 (match_operand:DI 1 "immediate_operand" "s")))))]
5494 "TARGET_SHMEDIA && flag_pic && reload_completed
5495 && GET_CODE (operands[1]) == SYMBOL_REF"
5499 [(set (match_operand:DI 0 "ext_dest_operand" "")
5500 (match_operand:DI 1 "immediate_operand" ""))]
5501 "TARGET_SHMEDIA && reload_completed
5502 && GET_CODE (operands[1]) == CONST_INT
5503 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5504 [(set (match_dup 0) (match_dup 2))
5508 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5509 unsigned HOST_WIDE_INT low = val;
5510 unsigned HOST_WIDE_INT high = val;
5511 unsigned HOST_WIDE_INT sign;
5512 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5514 /* Zero-extend the 16 least-significant bits. */
5517 /* Arithmetic shift right the word by 16 bits. */
5519 if (GET_CODE (operands[0]) == SUBREG
5520 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5529 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5535 /* If we can't generate the constant with a two-insn movi / shori
5536 sequence, try some other strategies. */
5537 if (! CONST_OK_FOR_I16 (high))
5539 /* Try constant load / left shift. We know VAL != 0. */
5540 val2 = val ^ (val-1);
5543 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5545 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5546 || (! CONST_OK_FOR_I16 (high >> 16)
5547 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5549 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5550 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5551 GEN_INT (trailing_zeroes));
5555 /* Try constant load / right shift. */
5556 val2 = (val >> 15) + 1;
5557 if (val2 == (val2 & -val2))
5559 int shift = 49 - exact_log2 (val2);
5561 val2 = trunc_int_for_mode (val << shift, DImode);
5562 if (CONST_OK_FOR_I16 (val2))
5564 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5570 val2 = val & 0xffff;
5571 if ((val >> 16 & 0xffff) == val2
5572 && (val >> 32 & 0xffff) == val2
5573 && (val >> 48 & 0xffff) == val2)
5575 val2 = (HOST_WIDE_INT) val >> 48;
5576 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5577 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5580 /* Try movi / mshflo.l */
5581 val2 = (HOST_WIDE_INT) val >> 32;
5582 if (val2 == ((unsigned HOST_WIDE_INT)
5583 trunc_int_for_mode (val, SImode)))
5585 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5589 /* Try movi / mshflo.l w/ r63. */
5590 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5591 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5593 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5599 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5602 operands[2] = GEN_INT (val2);
5606 [(set (match_operand:DI 0 "ext_dest_operand" "")
5607 (match_operand:DI 1 "immediate_operand" ""))]
5608 "TARGET_SHMEDIA && reload_completed
5609 && GET_CODE (operands[1]) == CONST_DOUBLE"
5610 [(set (match_dup 0) (match_dup 2))
5612 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5615 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5616 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5617 unsigned HOST_WIDE_INT val = low;
5618 unsigned HOST_WIDE_INT sign;
5620 /* Zero-extend the 16 least-significant bits. */
5622 operands[1] = GEN_INT (val);
5624 /* Arithmetic shift right the double-word by 16 bits. */
5626 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5629 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5633 /* This will only be true if high is a sign-extension of low, i.e.,
5634 it must be either 0 or (unsigned)-1, and be zero iff the
5635 most-significant bit of low is set. */
5636 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5637 operands[2] = GEN_INT (low);
5639 operands[2] = immed_double_const (low, high, DImode);
5642 (define_insn "shori_media"
5643 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5644 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5646 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5647 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5651 [(set_attr "type" "arith_media,*")])
5653 (define_insn "*shori_media_si"
5654 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5655 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5657 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5661 (define_expand "movdi"
5662 [(set (match_operand:DI 0 "general_movdst_operand" "")
5663 (match_operand:DI 1 "general_movsrc_operand" ""))]
5665 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5667 (define_insn "movdf_media"
5668 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5669 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5671 && (register_operand (operands[0], DFmode)
5672 || sh_register_operand (operands[1], DFmode))"
5683 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5685 (define_insn "movdf_media_nofpu"
5686 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5687 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5689 && (register_operand (operands[0], DFmode)
5690 || sh_register_operand (operands[1], DFmode))"
5696 [(set_attr "type" "arith_media,*,load_media,store_media")])
5699 [(set (match_operand:DF 0 "arith_reg_dest" "")
5700 (match_operand:DF 1 "immediate_operand" ""))]
5701 "TARGET_SHMEDIA && reload_completed"
5702 [(set (match_dup 3) (match_dup 2))]
5705 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5707 REAL_VALUE_TYPE value;
5709 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5710 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5712 if (HOST_BITS_PER_WIDE_INT >= 64)
5713 operands[2] = immed_double_const ((unsigned long) values[endian]
5714 | ((HOST_WIDE_INT) values[1 - endian]
5718 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5719 operands[2] = immed_double_const (values[endian], values[1 - endian],
5723 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5726 ;; ??? This should be a define expand.
5728 (define_insn "movdf_k"
5729 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5730 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5732 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5733 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5734 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5735 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5736 && (arith_reg_operand (operands[0], DFmode)
5737 || arith_reg_operand (operands[1], DFmode))"
5738 "* return output_movedouble (insn, operands, DFmode);"
5739 [(set_attr "length" "4")
5740 (set_attr "type" "move,pcload,load,store")])
5742 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5743 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5744 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5745 ;; the d/m/c/X alternative, which is split later into single-precision
5746 ;; instructions. And when not optimizing, no splits are done before fixing
5747 ;; up pcloads, so we need usable length information for that.
5748 (define_insn "movdf_i4"
5749 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5750 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5751 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5752 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5753 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5754 && (arith_reg_operand (operands[0], DFmode)
5755 || arith_reg_operand (operands[1], DFmode))"
5767 [(set_attr_alternative "length"
5768 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5770 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5771 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5772 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5774 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5775 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5776 ;; increment or decrement r15 explicitly.
5778 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5779 (const_int 10) (const_int 8))
5781 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5782 (const_int 10) (const_int 8))])
5783 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5784 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5785 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5786 (const_string "double")
5787 (const_string "none")))])
5789 ;; Moving DFmode between fp/general registers through memory
5790 ;; (the top of the stack) is faster than moving through fpul even for
5791 ;; little endian. Because the type of an instruction is important for its
5792 ;; scheduling, it is beneficial to split these operations, rather than
5793 ;; emitting them in one single chunk, even if this will expose a stack
5794 ;; use that will prevent scheduling of other stack accesses beyond this
5797 [(set (match_operand:DF 0 "register_operand" "")
5798 (match_operand:DF 1 "register_operand" ""))
5799 (use (match_operand:PSI 2 "fpscr_operand" ""))
5800 (clobber (match_scratch:SI 3 "=X"))]
5801 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5802 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5808 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5810 emit_move_insn (stack_pointer_rtx,
5811 plus_constant (stack_pointer_rtx, -8));
5812 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5815 tos = gen_tmp_stack_mem (DFmode,
5816 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5817 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5818 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5819 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5820 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5821 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5823 tos = gen_tmp_stack_mem (DFmode,
5824 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5825 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5826 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5827 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5829 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5833 ;; local-alloc sometimes allocates scratch registers even when not required,
5834 ;; so we must be prepared to handle these.
5836 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5838 [(set (match_operand:DF 0 "general_movdst_operand" "")
5839 (match_operand:DF 1 "general_movsrc_operand" ""))
5840 (use (match_operand:PSI 2 "fpscr_operand" ""))
5841 (clobber (match_scratch:SI 3 ""))]
5842 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5844 && true_regnum (operands[0]) < 16
5845 && true_regnum (operands[1]) < 16"
5846 [(set (match_dup 0) (match_dup 1))]
5849 /* If this was a reg <-> mem operation with base + index reg addressing,
5850 we have to handle this in a special way. */
5851 rtx mem = operands[0];
5853 if (! memory_operand (mem, DFmode))
5858 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5859 mem = SUBREG_REG (mem);
5860 if (GET_CODE (mem) == MEM)
5862 rtx addr = XEXP (mem, 0);
5863 if (GET_CODE (addr) == PLUS
5864 && GET_CODE (XEXP (addr, 0)) == REG
5865 && GET_CODE (XEXP (addr, 1)) == REG)
5868 rtx reg0 = gen_rtx_REG (Pmode, 0);
5869 rtx regop = operands[store_p], word0 ,word1;
5871 if (GET_CODE (regop) == SUBREG)
5872 alter_subreg (®op);
5873 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5877 mem = copy_rtx (mem);
5878 PUT_MODE (mem, SImode);
5879 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5880 alter_subreg (&word0);
5881 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5882 alter_subreg (&word1);
5883 if (store_p || ! refers_to_regno_p (REGNO (word0),
5884 REGNO (word0) + 1, addr, 0))
5887 ? gen_movsi_ie (mem, word0)
5888 : gen_movsi_ie (word0, mem));
5889 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5890 mem = copy_rtx (mem);
5892 ? gen_movsi_ie (mem, word1)
5893 : gen_movsi_ie (word1, mem));
5894 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5898 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5899 emit_insn (gen_movsi_ie (word1, mem));
5900 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5901 mem = copy_rtx (mem);
5902 emit_insn (gen_movsi_ie (word0, mem));
5909 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5911 [(set (match_operand:DF 0 "register_operand" "")
5912 (match_operand:DF 1 "memory_operand" ""))
5913 (use (match_operand:PSI 2 "fpscr_operand" ""))
5914 (clobber (reg:SI R0_REG))]
5915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5916 [(parallel [(set (match_dup 0) (match_dup 1))
5918 (clobber (scratch:SI))])]
5921 (define_expand "reload_indf__frn"
5922 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5923 (match_operand:DF 1 "immediate_operand" "FQ"))
5924 (use (reg:PSI FPSCR_REG))
5925 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5929 (define_expand "reload_outdf__RnFRm"
5930 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5931 (match_operand:DF 1 "register_operand" "af,r"))
5932 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5936 ;; Simplify no-op moves.
5938 [(set (match_operand:SF 0 "register_operand" "")
5939 (match_operand:SF 1 "register_operand" ""))
5940 (use (match_operand:PSI 2 "fpscr_operand" ""))
5941 (clobber (match_scratch:SI 3 ""))]
5942 "TARGET_SH2E && reload_completed
5943 && true_regnum (operands[0]) == true_regnum (operands[1])"
5944 [(set (match_dup 0) (match_dup 0))]
5947 ;; fmovd substitute post-reload splits
5949 [(set (match_operand:DF 0 "register_operand" "")
5950 (match_operand:DF 1 "register_operand" ""))
5951 (use (match_operand:PSI 2 "fpscr_operand" ""))
5952 (clobber (match_scratch:SI 3 ""))]
5953 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5954 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5955 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5959 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5960 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5961 gen_rtx_REG (SFmode, src), operands[2]));
5962 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5963 gen_rtx_REG (SFmode, src + 1), operands[2]));
5968 [(set (match_operand:DF 0 "register_operand" "")
5969 (mem:DF (match_operand:SI 1 "register_operand" "")))
5970 (use (match_operand:PSI 2 "fpscr_operand" ""))
5971 (clobber (match_scratch:SI 3 ""))]
5972 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5973 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5974 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5978 int regno = true_regnum (operands[0]);
5980 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5982 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5983 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5984 regno + !! TARGET_LITTLE_ENDIAN),
5985 mem2, operands[2]));
5986 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5987 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5988 regno + ! TARGET_LITTLE_ENDIAN),
5989 change_address (mem, SFmode, NULL_RTX),
5995 [(set (match_operand:DF 0 "register_operand" "")
5996 (match_operand:DF 1 "memory_operand" ""))
5997 (use (match_operand:PSI 2 "fpscr_operand" ""))
5998 (clobber (match_scratch:SI 3 ""))]
5999 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6000 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6004 int regno = true_regnum (operands[0]);
6005 rtx addr, insn, adjust = NULL_RTX;
6006 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6007 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6008 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6010 operands[1] = copy_rtx (mem2);
6011 addr = XEXP (mem2, 0);
6012 if (GET_CODE (addr) != POST_INC)
6014 /* If we have to modify the stack pointer, the value that we have
6015 read with post-increment might be modified by an interrupt,
6016 so write it back. */
6017 if (REGNO (addr) == STACK_POINTER_REGNUM)
6018 adjust = gen_push_e (reg0);
6020 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6021 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6023 addr = XEXP (addr, 0);
6024 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6025 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6026 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6030 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6035 [(set (match_operand:DF 0 "memory_operand" "")
6036 (match_operand:DF 1 "register_operand" ""))
6037 (use (match_operand:PSI 2 "fpscr_operand" ""))
6038 (clobber (match_scratch:SI 3 ""))]
6039 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6040 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6044 int regno = true_regnum (operands[1]);
6045 rtx insn, addr, adjust = NULL_RTX;
6047 operands[0] = copy_rtx (operands[0]);
6048 PUT_MODE (operands[0], SFmode);
6049 insn = emit_insn (gen_movsf_ie (operands[0],
6050 gen_rtx_REG (SFmode,
6051 regno + ! TARGET_LITTLE_ENDIAN),
6053 operands[0] = copy_rtx (operands[0]);
6054 addr = XEXP (operands[0], 0);
6055 if (GET_CODE (addr) != PRE_DEC)
6057 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6058 emit_insn_before (adjust, insn);
6059 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6061 addr = XEXP (addr, 0);
6063 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6064 insn = emit_insn (gen_movsf_ie (operands[0],
6065 gen_rtx_REG (SFmode,
6066 regno + !! TARGET_LITTLE_ENDIAN),
6068 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6072 ;; If the output is a register and the input is memory or a register, we have
6073 ;; to be careful and see which word needs to be loaded first.
6076 [(set (match_operand:DF 0 "general_movdst_operand" "")
6077 (match_operand:DF 1 "general_movsrc_operand" ""))]
6078 "TARGET_SH1 && reload_completed"
6079 [(set (match_dup 2) (match_dup 3))
6080 (set (match_dup 4) (match_dup 5))]
6085 if ((GET_CODE (operands[0]) == MEM
6086 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6087 || (GET_CODE (operands[1]) == MEM
6088 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6091 switch (GET_CODE (operands[0]))
6094 regno = REGNO (operands[0]);
6097 regno = subreg_regno (operands[0]);
6107 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6109 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6110 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6111 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6112 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6116 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6117 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6118 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6119 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6122 if (operands[2] == 0 || operands[3] == 0
6123 || operands[4] == 0 || operands[5] == 0)
6127 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6128 ;; used only once, let combine add in the index again.
6131 [(set (match_operand:SI 0 "register_operand" "")
6132 (match_operand:SI 1 "" ""))
6133 (clobber (match_operand 2 "register_operand" ""))]
6134 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6135 && ALLOW_INDEXED_ADDRESS"
6136 [(use (reg:SI R0_REG))]
6139 rtx addr, reg, const_int;
6141 if (GET_CODE (operands[1]) != MEM)
6143 addr = XEXP (operands[1], 0);
6144 if (GET_CODE (addr) != PLUS)
6146 reg = XEXP (addr, 0);
6147 const_int = XEXP (addr, 1);
6148 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6149 && GET_CODE (const_int) == CONST_INT))
6151 emit_move_insn (operands[2], const_int);
6152 emit_move_insn (operands[0],
6153 change_address (operands[1], VOIDmode,
6154 gen_rtx_PLUS (SImode, reg, operands[2])));
6159 [(set (match_operand:SI 1 "" "")
6160 (match_operand:SI 0 "register_operand" ""))
6161 (clobber (match_operand 2 "register_operand" ""))]
6162 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6163 && ALLOW_INDEXED_ADDRESS"
6164 [(use (reg:SI R0_REG))]
6167 rtx addr, reg, const_int;
6169 if (GET_CODE (operands[1]) != MEM)
6171 addr = XEXP (operands[1], 0);
6172 if (GET_CODE (addr) != PLUS)
6174 reg = XEXP (addr, 0);
6175 const_int = XEXP (addr, 1);
6176 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6177 && GET_CODE (const_int) == CONST_INT))
6179 emit_move_insn (operands[2], const_int);
6180 emit_move_insn (change_address (operands[1], VOIDmode,
6181 gen_rtx_PLUS (SImode, reg, operands[2])),
6186 (define_expand "movdf"
6187 [(set (match_operand:DF 0 "general_movdst_operand" "")
6188 (match_operand:DF 1 "general_movsrc_operand" ""))]
6192 if (prepare_move_operands (operands, DFmode)) DONE;
6195 if (TARGET_SHMEDIA_FPU)
6196 emit_insn (gen_movdf_media (operands[0], operands[1]));
6198 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6201 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6203 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6208 ;;This is incompatible with the way gcc uses subregs.
6209 ;;(define_insn "movv2sf_i"
6210 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6211 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6212 ;; "TARGET_SHMEDIA_FPU
6213 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6214 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6218 ;; fst%M0.p %m0, %1"
6219 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6221 (define_insn_and_split "movv2sf_i"
6222 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6223 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6224 "TARGET_SHMEDIA_FPU"
6226 "TARGET_SHMEDIA_FPU && reload_completed"
6227 [(set (match_dup 0) (match_dup 1))]
6230 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6231 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6234 (define_expand "movv2sf"
6235 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6236 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6237 "TARGET_SHMEDIA_FPU"
6240 if (prepare_move_operands (operands, V2SFmode))
6244 (define_expand "addv2sf3"
6245 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6246 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6247 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6248 "TARGET_SHMEDIA_FPU"
6251 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6255 (define_expand "subv2sf3"
6256 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6257 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6258 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6259 "TARGET_SHMEDIA_FPU"
6262 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6266 (define_expand "mulv2sf3"
6267 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6268 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6269 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6270 "TARGET_SHMEDIA_FPU"
6273 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6277 (define_expand "divv2sf3"
6278 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6279 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6280 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6281 "TARGET_SHMEDIA_FPU"
6284 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6288 (define_insn_and_split "*movv4sf_i"
6289 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6290 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6291 "TARGET_SHMEDIA_FPU"
6293 "&& reload_completed"
6299 for (i = 0; i < 4/2; i++)
6303 if (GET_CODE (operands[0]) == MEM)
6304 x = adjust_address (operands[0], V2SFmode,
6305 i * GET_MODE_SIZE (V2SFmode));
6307 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6309 if (GET_CODE (operands[1]) == MEM)
6310 y = adjust_address (operands[1], V2SFmode,
6311 i * GET_MODE_SIZE (V2SFmode));
6313 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6315 emit_insn (gen_movv2sf_i (x, y));
6320 [(set_attr "length" "8")])
6322 (define_expand "movv4sf"
6323 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6324 (match_operand:V4SF 1 "general_operand" ""))]
6325 "TARGET_SHMEDIA_FPU"
6328 if (prepare_move_operands (operands, V4SFmode))
6332 (define_insn_and_split "*movv16sf_i"
6333 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6334 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6335 "TARGET_SHMEDIA_FPU"
6337 "&& reload_completed"
6343 for (i = 0; i < 16/2; i++)
6347 if (GET_CODE (operands[0]) == MEM)
6348 x = adjust_address (operands[0], V2SFmode,
6349 i * GET_MODE_SIZE (V2SFmode));
6352 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6356 if (GET_CODE (operands[1]) == MEM)
6357 y = adjust_address (operands[1], V2SFmode,
6358 i * GET_MODE_SIZE (V2SFmode));
6361 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6365 emit_insn (gen_movv2sf_i (x, y));
6370 [(set_attr "length" "32")])
6372 (define_expand "movv16sf"
6373 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6374 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6375 "TARGET_SHMEDIA_FPU"
6378 if (prepare_move_operands (operands, V16SFmode))
6382 (define_insn "movsf_media"
6383 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6384 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6386 && (register_operand (operands[0], SFmode)
6387 || sh_register_operand (operands[1], SFmode))"
6398 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6399 (set (attr "highpart")
6400 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6401 (const_string "user")]
6402 (const_string "ignore")))])
6404 (define_insn "movsf_media_nofpu"
6405 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6406 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6408 && (register_operand (operands[0], SFmode)
6409 || sh_register_operand (operands[1], SFmode))"
6415 [(set_attr "type" "arith_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")))])
6422 [(set (match_operand:SF 0 "arith_reg_dest" "")
6423 (match_operand:SF 1 "immediate_operand" ""))]
6424 "TARGET_SHMEDIA && reload_completed
6425 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6426 [(set (match_dup 3) (match_dup 2))]
6430 REAL_VALUE_TYPE value;
6432 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6433 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6434 operands[2] = GEN_INT (values);
6436 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6439 (define_insn "movsf_i"
6440 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6441 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6444 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6445 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6446 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6447 && (arith_reg_operand (operands[0], SFmode)
6448 || arith_reg_operand (operands[1], SFmode))"
6457 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6459 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6460 ;; update_flow_info would not know where to put REG_EQUAL notes
6461 ;; when the destination changes mode.
6462 (define_insn "movsf_ie"
6463 [(set (match_operand:SF 0 "general_movdst_operand"
6464 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6465 (match_operand:SF 1 "general_movsrc_operand"
6466 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6467 (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"))
6468 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6471 && (arith_reg_operand (operands[0], SFmode)
6472 || arith_reg_operand (operands[1], SFmode)
6473 || arith_reg_operand (operands[3], SImode)
6474 || (fpul_operand (operands[0], SFmode)
6475 && memory_operand (operands[1], SFmode)
6476 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6477 || (fpul_operand (operands[1], SFmode)
6478 && memory_operand (operands[0], SFmode)
6479 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6499 ! move optimized away"
6500 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6501 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6502 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6503 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6504 (const_string "single")
6505 (const_string "none")))])
6508 [(set (match_operand:SF 0 "register_operand" "")
6509 (match_operand:SF 1 "register_operand" ""))
6510 (use (match_operand:PSI 2 "fpscr_operand" ""))
6511 (clobber (reg:SI FPUL_REG))]
6513 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6515 (clobber (scratch:SI))])
6516 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6518 (clobber (scratch:SI))])]
6521 (define_expand "movsf"
6522 [(set (match_operand:SF 0 "general_movdst_operand" "")
6523 (match_operand:SF 1 "general_movsrc_operand" ""))]
6527 if (prepare_move_operands (operands, SFmode))
6531 if (TARGET_SHMEDIA_FPU)
6532 emit_insn (gen_movsf_media (operands[0], operands[1]));
6534 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6539 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6544 (define_insn "mov_nop"
6545 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6548 [(set_attr "length" "0")
6549 (set_attr "type" "nil")])
6551 (define_expand "reload_insf__frn"
6552 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6553 (match_operand:SF 1 "immediate_operand" "FQ"))
6554 (use (reg:PSI FPSCR_REG))
6555 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6559 (define_expand "reload_insi__i_fpul"
6560 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6561 (match_operand:SI 1 "immediate_operand" "i"))
6562 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6566 (define_expand "ptabs"
6567 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6571 if (!TARGET_PT_FIXED)
6573 rtx eq = operands[1];
6575 /* ??? For canonical RTL we really should remove any CONST from EQ
6576 before wrapping it in the AND, and finally wrap the EQ into a
6577 const if is constant. However, for reload we must expose the
6578 input register or symbolic constant, and we can't have
6579 different insn structures outside of the operands for different
6580 alternatives of the same pattern. */
6581 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6584 = (gen_rtx_IF_THEN_ELSE
6587 gen_rtx_MEM (PDImode, operands[1]),
6588 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6589 PDImode, operands[1])));
6593 ;; expanded by ptabs expander.
6594 (define_insn "*extendsipdi_media"
6595 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6596 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6600 (mem:PDI (match_dup 1))
6601 (sign_extend:PDI (match_dup 1))))]
6602 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6606 [(set_attr "type" "ptabs_media,pt_media")
6607 (set_attr "length" "4,*")])
6609 (define_insn "*truncdipdi_media"
6610 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6611 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6615 (mem:PDI (match_dup 1))
6616 (truncate:PDI (match_dup 1))))]
6617 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6621 [(set_attr "type" "ptabs_media,pt_media")
6622 (set_attr "length" "4,*")])
6624 (define_insn "*movsi_y"
6625 [(set (match_operand:SI 0 "register_operand" "=y,y")
6626 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6627 (clobber (match_scratch:SI 2 "=&z,r"))]
6629 && (reload_in_progress || reload_completed)"
6631 [(set_attr "length" "4")
6632 (set_attr "type" "pcload,move")])
6635 [(set (match_operand:SI 0 "register_operand" "")
6636 (match_operand:SI 1 "immediate_operand" ""))
6637 (clobber (match_operand:SI 2 "register_operand" ""))]
6639 [(set (match_dup 2) (match_dup 1))
6640 (set (match_dup 0) (match_dup 2))]
6644 [(set (match_operand:SI 0 "register_operand" "")
6645 (match_operand:SI 1 "memory_operand" ""))
6646 (clobber (reg:SI R0_REG))]
6648 [(set (match_dup 0) (match_dup 1))]
6651 ;; ------------------------------------------------------------------------
6652 ;; Define the real conditional branch instructions.
6653 ;; ------------------------------------------------------------------------
6655 (define_insn "branch_true"
6656 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6657 (label_ref (match_operand 0 "" ""))
6660 "* return output_branch (1, insn, operands);"
6661 [(set_attr "type" "cbranch")])
6663 (define_insn "branch_false"
6664 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6665 (label_ref (match_operand 0 "" ""))
6668 "* return output_branch (0, insn, operands);"
6669 [(set_attr "type" "cbranch")])
6671 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6672 ;; which destination is too far away.
6673 ;; The const_int_operand is distinct for each branch target; it avoids
6674 ;; unwanted matches with redundant_insn.
6675 (define_insn "block_branch_redirect"
6676 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6679 [(set_attr "length" "0")])
6681 ;; This one has the additional purpose to record a possible scratch register
6682 ;; for the following branch.
6683 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6684 ;; because the insn then might be deemed dead and deleted. And we can't
6685 ;; make the use in the jump insn explicit because that would disable
6686 ;; delay slot scheduling from the target.
6687 (define_insn "indirect_jump_scratch"
6688 [(set (match_operand:SI 0 "register_operand" "=r")
6689 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6690 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6693 [(set_attr "length" "0")])
6695 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6696 ;; being pulled into the delay slot of a condbranch that has been made to
6697 ;; jump around the unconditional jump because it was out of range.
6698 (define_insn "stuff_delay_slot"
6700 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6701 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6704 [(set_attr "length" "0")
6705 (set_attr "cond_delay_slot" "yes")])
6707 ;; Conditional branch insns
6709 (define_expand "beq_media"
6711 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6712 (match_operand:DI 2 "arith_operand" "r,I06"))
6713 (match_operand 0 "" "")
6716 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6718 (define_insn "*beq_media_i"
6720 (if_then_else (match_operator 3 "equality_comparison_operator"
6721 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6722 (match_operand:DI 2 "arith_operand" "r,I06")])
6723 (match_operand 0 "target_operand" "b,b")
6728 b%o3i%' %1, %2, %0%>"
6729 [(set_attr "type" "cbranch_media")])
6731 (define_insn "*beq_media_i32"
6733 (if_then_else (match_operator 3 "equality_comparison_operator"
6734 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6735 (match_operand:SI 2 "arith_operand" "r,I06")])
6736 (match_operand 0 "target_operand" "b,b")
6741 b%o3i%' %1, %2, %0%>"
6742 [(set_attr "type" "cbranch_media")])
6744 (define_expand "bne_media"
6746 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6747 (match_operand:DI 2 "arith_operand" "r,I06"))
6748 (match_operand 0 "" "")
6751 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6753 (define_expand "bgt_media"
6755 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6756 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6757 (match_operand 0 "" "")
6760 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6762 (define_expand "bge_media"
6764 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6765 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6766 (match_operand 0 "" "")
6769 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6771 (define_expand "bgtu_media"
6773 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6774 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6775 (match_operand 0 "" "")
6778 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6780 (define_expand "bgeu_media"
6782 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6783 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6784 (match_operand 0 "" "")
6787 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6789 (define_insn "*bgt_media_i"
6791 (if_then_else (match_operator 3 "greater_comparison_operator"
6792 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6793 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6794 (match_operand 0 "target_operand" "b")
6797 "b%o3%' %N1, %N2, %0%>"
6798 [(set_attr "type" "cbranch_media")])
6800 (define_insn "*bgt_media_i32"
6802 (if_then_else (match_operator 3 "greater_comparison_operator"
6803 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6804 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6805 (match_operand 0 "target_operand" "b")
6808 "b%o3%' %N1, %N2, %0%>"
6809 [(set_attr "type" "cbranch_media")])
6811 ;; These are only needed to make invert_jump() happy - otherwise, jump
6812 ;; optimization will be silently disabled.
6813 (define_insn "*blt_media_i"
6815 (if_then_else (match_operator 3 "less_comparison_operator"
6816 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6817 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6818 (match_operand 0 "target_operand" "b")
6821 "b%o3%' %N2, %N1, %0%>"
6822 [(set_attr "type" "cbranch_media")])
6824 (define_insn "*blt_media_i32"
6826 (if_then_else (match_operator 3 "less_comparison_operator"
6827 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6828 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6829 (match_operand 0 "target_operand" "b")
6832 "b%o3%' %N2, %N1, %0%>"
6833 [(set_attr "type" "cbranch_media")])
6835 (define_expand "beq"
6837 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6838 (label_ref (match_operand 0 "" ""))
6845 enum machine_mode mode = GET_MODE (sh_compare_op0);
6847 if (mode != DImode && mode != SImode)
6849 rtx tmp = gen_reg_rtx (DImode);
6851 emit_insn (gen_seq (tmp));
6852 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6856 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6857 if (CONSTANT_P (sh_compare_op1)
6858 && (GET_CODE (sh_compare_op1) != CONST_INT
6859 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6860 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6861 emit_jump_insn (gen_beq_media (operands[0],
6862 sh_compare_op0, sh_compare_op1));
6866 from_compare (operands, EQ);
6869 (define_expand "bne"
6871 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6872 (label_ref (match_operand 0 "" ""))
6879 enum machine_mode mode = GET_MODE (sh_compare_op0);
6881 if (mode != DImode && mode != SImode)
6883 rtx tmp = gen_reg_rtx (DImode);
6885 emit_insn (gen_seq (tmp));
6886 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6890 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6891 if (CONSTANT_P (sh_compare_op1)
6892 && (GET_CODE (sh_compare_op1) != CONST_INT
6893 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6894 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6895 emit_jump_insn (gen_bne_media (operands[0],
6896 sh_compare_op0, sh_compare_op1));
6900 from_compare (operands, EQ);
6903 (define_expand "bgt"
6905 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6906 (label_ref (match_operand 0 "" ""))
6913 enum machine_mode mode = GET_MODE (sh_compare_op0);
6915 if (mode != DImode && mode != SImode)
6917 rtx tmp = gen_reg_rtx (DImode);
6919 emit_insn (gen_sgt (tmp));
6920 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6924 if (sh_compare_op0 != const0_rtx)
6925 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6926 if (sh_compare_op1 != const0_rtx)
6927 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6928 emit_jump_insn (gen_bgt_media (operands[0],
6929 sh_compare_op0, sh_compare_op1));
6933 from_compare (operands, GT);
6936 (define_expand "blt"
6938 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6939 (label_ref (match_operand 0 "" ""))
6946 enum machine_mode mode = GET_MODE (sh_compare_op0);
6948 if (mode != DImode && mode != SImode)
6950 rtx tmp = gen_reg_rtx (DImode);
6952 emit_insn (gen_slt (tmp));
6953 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6957 if (sh_compare_op0 != const0_rtx)
6958 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6959 if (sh_compare_op1 != const0_rtx)
6960 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6961 emit_jump_insn (gen_bgt_media (operands[0],
6962 sh_compare_op1, sh_compare_op0));
6966 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6968 rtx tmp = sh_compare_op0;
6969 sh_compare_op0 = sh_compare_op1;
6970 sh_compare_op1 = tmp;
6971 emit_insn (gen_bgt (operands[0]));
6974 from_compare (operands, GE);
6977 (define_expand "ble"
6979 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6980 (label_ref (match_operand 0 "" ""))
6987 enum machine_mode mode = GET_MODE (sh_compare_op0);
6989 if (mode != DImode && mode != SImode)
6991 rtx tmp = gen_reg_rtx (DImode);
6993 emit_insn (gen_sle (tmp));
6994 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6998 if (sh_compare_op0 != const0_rtx)
6999 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7000 if (sh_compare_op1 != const0_rtx)
7001 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7002 emit_jump_insn (gen_bge_media (operands[0],
7003 sh_compare_op1, sh_compare_op0));
7009 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7011 rtx tmp = sh_compare_op0;
7012 sh_compare_op0 = sh_compare_op1;
7013 sh_compare_op1 = tmp;
7014 emit_insn (gen_bge (operands[0]));
7017 from_compare (operands, GT);
7020 (define_expand "bge"
7022 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7023 (label_ref (match_operand 0 "" ""))
7030 enum machine_mode mode = GET_MODE (sh_compare_op0);
7032 if (mode != DImode && mode != SImode)
7034 rtx tmp = gen_reg_rtx (DImode);
7036 emit_insn (gen_sge (tmp));
7037 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7041 if (sh_compare_op0 != const0_rtx)
7042 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7043 if (sh_compare_op1 != const0_rtx)
7044 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7045 emit_jump_insn (gen_bge_media (operands[0],
7046 sh_compare_op0, sh_compare_op1));
7052 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7054 rtx tmp = sh_compare_op0;
7055 sh_compare_op0 = sh_compare_op1;
7056 sh_compare_op1 = tmp;
7057 emit_insn (gen_ble (operands[0]));
7060 from_compare (operands, GE);
7063 (define_expand "bgtu"
7065 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7066 (label_ref (match_operand 0 "" ""))
7073 enum machine_mode mode = GET_MODE (sh_compare_op0);
7075 if (sh_compare_op0 != const0_rtx)
7076 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7077 if (sh_compare_op1 != const0_rtx)
7078 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7079 emit_jump_insn (gen_bgtu_media (operands[0],
7080 sh_compare_op0, sh_compare_op1));
7084 from_compare (operands, GTU);
7087 (define_expand "bltu"
7089 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7090 (label_ref (match_operand 0 "" ""))
7097 enum machine_mode mode = GET_MODE (sh_compare_op0);
7099 if (sh_compare_op0 != const0_rtx)
7100 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7101 if (sh_compare_op1 != const0_rtx)
7102 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7103 emit_jump_insn (gen_bgtu_media (operands[0],
7104 sh_compare_op1, sh_compare_op0));
7108 from_compare (operands, GEU);
7111 (define_expand "bgeu"
7113 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7114 (label_ref (match_operand 0 "" ""))
7121 enum machine_mode mode = GET_MODE (sh_compare_op0);
7123 if (sh_compare_op0 != const0_rtx)
7124 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7125 if (sh_compare_op1 != const0_rtx)
7126 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7127 emit_jump_insn (gen_bgeu_media (operands[0],
7128 sh_compare_op0, sh_compare_op1));
7132 from_compare (operands, GEU);
7135 (define_expand "bleu"
7137 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7138 (label_ref (match_operand 0 "" ""))
7145 enum machine_mode mode = GET_MODE (sh_compare_op0);
7147 if (sh_compare_op0 != const0_rtx)
7148 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7149 if (sh_compare_op1 != const0_rtx)
7150 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7151 emit_jump_insn (gen_bgeu_media (operands[0],
7152 sh_compare_op1, sh_compare_op0));
7156 from_compare (operands, GTU);
7159 (define_expand "bunordered"
7160 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7162 (if_then_else (ne (match_dup 1) (const_int 0))
7163 (match_operand 0 "" "")
7168 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7169 operands[1] = gen_reg_rtx (DImode);
7170 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7171 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7174 ;; combiner splitter for test-and-branch on single bit in register. This
7175 ;; is endian dependent because the non-paradoxical subreg looks different
7180 (match_operator 3 "equality_comparison_operator"
7181 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7182 "extend_reg_operand" "")
7186 "const_int_operand" "")) 0)
7188 (match_operand 0 "target_operand" "")
7190 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7191 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7192 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7193 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7197 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7198 operands[6] = (GET_CODE (operands[3]) == EQ
7199 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7200 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7203 ;; ------------------------------------------------------------------------
7204 ;; Jump and linkage insns
7205 ;; ------------------------------------------------------------------------
7207 (define_insn "jump_compact"
7209 (label_ref (match_operand 0 "" "")))]
7213 /* The length is 16 if the delay slot is unfilled. */
7214 if (get_attr_length(insn) > 4)
7215 return output_far_jump(insn, operands[0]);
7217 return \"bra %l0%#\";
7219 [(set_attr "type" "jump")
7220 (set_attr "needs_delay_slot" "yes")])
7222 ;; ??? It would be much saner to explicitly use the scratch register
7223 ;; in the jump insn, and have indirect_jump_scratch only set it,
7224 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7225 ;; from the target then, as it uses simplejump_p.
7226 ;;(define_insn "jump_compact_far"
7228 ;; (label_ref (match_operand 0 "" "")))
7229 ;; (use (match_operand 1 "register_operand" "r")]
7231 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7232 ;; [(set_attr "type" "jump")
7233 ;; (set_attr "needs_delay_slot" "yes")])
7235 (define_insn "jump_media"
7237 (match_operand 0 "target_operand" "b"))]
7240 [(set_attr "type" "jump_media")])
7242 (define_expand "jump"
7244 (label_ref (match_operand 0 "" "")))]
7249 emit_jump_insn (gen_jump_compact (operands[0]));
7250 else if (TARGET_SHMEDIA)
7252 if (reload_in_progress || reload_completed)
7254 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7260 (define_insn "force_mode_for_call"
7261 [(use (reg:PSI FPSCR_REG))]
7264 [(set_attr "length" "0")
7265 (set (attr "fp_mode")
7266 (if_then_else (eq_attr "fpu_single" "yes")
7267 (const_string "single") (const_string "double")))])
7269 (define_insn "calli"
7270 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7271 (match_operand 1 "" ""))
7272 (use (reg:PSI FPSCR_REG))
7273 (clobber (reg:SI PR_REG))]
7276 [(set_attr "type" "call")
7277 (set (attr "fp_mode")
7278 (if_then_else (eq_attr "fpu_single" "yes")
7279 (const_string "single") (const_string "double")))
7280 (set_attr "needs_delay_slot" "yes")
7281 (set_attr "fp_set" "unknown")])
7283 ;; This is a pc-rel call, using bsrf, for use with PIC.
7285 (define_insn "calli_pcrel"
7286 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7287 (match_operand 1 "" ""))
7288 (use (reg:PSI FPSCR_REG))
7289 (use (reg:SI PIC_REG))
7290 (use (match_operand 2 "" ""))
7291 (clobber (reg:SI PR_REG))]
7294 [(set_attr "type" "call")
7295 (set (attr "fp_mode")
7296 (if_then_else (eq_attr "fpu_single" "yes")
7297 (const_string "single") (const_string "double")))
7298 (set_attr "needs_delay_slot" "yes")
7299 (set_attr "fp_set" "unknown")])
7301 (define_insn_and_split "call_pcrel"
7302 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7303 (match_operand 1 "" ""))
7304 (use (reg:PSI FPSCR_REG))
7305 (use (reg:SI PIC_REG))
7306 (clobber (reg:SI PR_REG))
7307 (clobber (match_scratch:SI 2 "=r"))]
7314 rtx lab = PATTERN (gen_call_site ());
7316 if (SYMBOL_REF_LOCAL_P (operands[0]))
7317 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7319 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7320 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7323 [(set_attr "type" "call")
7324 (set (attr "fp_mode")
7325 (if_then_else (eq_attr "fpu_single" "yes")
7326 (const_string "single") (const_string "double")))
7327 (set_attr "needs_delay_slot" "yes")
7328 (set_attr "fp_set" "unknown")])
7330 (define_insn "call_compact"
7331 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7332 (match_operand 1 "" ""))
7333 (match_operand 2 "immediate_operand" "n")
7334 (use (reg:SI R0_REG))
7335 (use (reg:SI R1_REG))
7336 (use (reg:PSI FPSCR_REG))
7337 (clobber (reg:SI PR_REG))]
7338 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
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")])
7346 (define_insn "call_compact_rettramp"
7347 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7348 (match_operand 1 "" ""))
7349 (match_operand 2 "immediate_operand" "n")
7350 (use (reg:SI R0_REG))
7351 (use (reg:SI R1_REG))
7352 (use (reg:PSI FPSCR_REG))
7353 (clobber (reg:SI R10_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_media"
7364 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7365 (match_operand 1 "" ""))
7366 (clobber (reg:DI PR_MEDIA_REG))]
7369 [(set_attr "type" "jump_media")])
7371 (define_insn "call_valuei"
7372 [(set (match_operand 0 "" "=rf")
7373 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7374 (match_operand 2 "" "")))
7375 (use (reg:PSI FPSCR_REG))
7376 (clobber (reg:SI PR_REG))]
7379 [(set_attr "type" "call")
7380 (set (attr "fp_mode")
7381 (if_then_else (eq_attr "fpu_single" "yes")
7382 (const_string "single") (const_string "double")))
7383 (set_attr "needs_delay_slot" "yes")
7384 (set_attr "fp_set" "unknown")])
7386 (define_insn "call_valuei_pcrel"
7387 [(set (match_operand 0 "" "=rf")
7388 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7389 (match_operand 2 "" "")))
7390 (use (reg:PSI FPSCR_REG))
7391 (use (reg:SI PIC_REG))
7392 (use (match_operand 3 "" ""))
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_and_split "call_value_pcrel"
7404 [(set (match_operand 0 "" "=rf")
7405 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7406 (match_operand 2 "" "")))
7407 (use (reg:PSI FPSCR_REG))
7408 (use (reg:SI PIC_REG))
7409 (clobber (reg:SI PR_REG))
7410 (clobber (match_scratch:SI 3 "=r"))]
7417 rtx lab = PATTERN (gen_call_site ());
7419 if (SYMBOL_REF_LOCAL_P (operands[1]))
7420 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7422 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7423 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7427 [(set_attr "type" "call")
7428 (set (attr "fp_mode")
7429 (if_then_else (eq_attr "fpu_single" "yes")
7430 (const_string "single") (const_string "double")))
7431 (set_attr "needs_delay_slot" "yes")
7432 (set_attr "fp_set" "unknown")])
7434 (define_insn "call_value_compact"
7435 [(set (match_operand 0 "" "=rf")
7436 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7437 (match_operand 2 "" "")))
7438 (match_operand 3 "immediate_operand" "n")
7439 (use (reg:SI R0_REG))
7440 (use (reg:SI R1_REG))
7441 (use (reg:PSI FPSCR_REG))
7442 (clobber (reg:SI PR_REG))]
7443 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7445 [(set_attr "type" "call")
7446 (set (attr "fp_mode")
7447 (if_then_else (eq_attr "fpu_single" "yes")
7448 (const_string "single") (const_string "double")))
7449 (set_attr "needs_delay_slot" "yes")])
7451 (define_insn "call_value_compact_rettramp"
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 R10_REG))
7460 (clobber (reg:SI PR_REG))]
7461 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7463 [(set_attr "type" "call")
7464 (set (attr "fp_mode")
7465 (if_then_else (eq_attr "fpu_single" "yes")
7466 (const_string "single") (const_string "double")))
7467 (set_attr "needs_delay_slot" "yes")])
7469 (define_insn "call_value_media"
7470 [(set (match_operand 0 "" "=rf")
7471 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7472 (match_operand 2 "" "")))
7473 (clobber (reg:DI PR_MEDIA_REG))]
7476 [(set_attr "type" "jump_media")])
7478 (define_expand "call"
7479 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7480 (match_operand 1 "" ""))
7481 (match_operand 2 "" "")
7482 (use (reg:PSI FPSCR_REG))
7483 (clobber (reg:SI PR_REG))])]
7489 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7490 emit_call_insn (gen_call_media (operands[0], operands[1]));
7493 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7495 rtx cookie_rtx = operands[2];
7496 long cookie = INTVAL (cookie_rtx);
7497 rtx func = XEXP (operands[0], 0);
7502 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7504 rtx reg = gen_reg_rtx (Pmode);
7506 emit_insn (gen_symGOTPLT2reg (reg, func));
7510 func = legitimize_pic_address (func, Pmode, 0);
7513 r0 = gen_rtx_REG (SImode, R0_REG);
7514 r1 = gen_rtx_REG (SImode, R1_REG);
7516 /* Since such a call function may use all call-clobbered
7517 registers, we force a mode switch earlier, so that we don't
7518 run out of registers when adjusting fpscr for the call. */
7519 emit_insn (gen_force_mode_for_call ());
7522 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7524 operands[0] = force_reg (SImode, operands[0]);
7526 emit_move_insn (r0, func);
7527 emit_move_insn (r1, cookie_rtx);
7529 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7530 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7533 emit_call_insn (gen_call_compact (operands[0], operands[1],
7538 else if (TARGET_SHCOMPACT && flag_pic
7539 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7540 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7542 rtx reg = gen_reg_rtx (Pmode);
7544 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7545 XEXP (operands[0], 0) = reg;
7547 if (flag_pic && TARGET_SH2
7548 && GET_CODE (operands[0]) == MEM
7549 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7551 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7556 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7557 operands[1] = operands[2];
7560 emit_call_insn (gen_calli (operands[0], operands[1]));
7564 (define_insn "call_pop_compact"
7565 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7566 (match_operand 1 "" ""))
7567 (match_operand 2 "immediate_operand" "n")
7568 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7569 (match_operand 3 "immediate_operand" "n")))
7570 (use (reg:SI R0_REG))
7571 (use (reg:SI R1_REG))
7572 (use (reg:PSI FPSCR_REG))
7573 (clobber (reg:SI PR_REG))]
7574 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7576 [(set_attr "type" "call")
7577 (set (attr "fp_mode")
7578 (if_then_else (eq_attr "fpu_single" "yes")
7579 (const_string "single") (const_string "double")))
7580 (set_attr "needs_delay_slot" "yes")])
7582 (define_insn "call_pop_compact_rettramp"
7583 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7584 (match_operand 1 "" ""))
7585 (match_operand 2 "immediate_operand" "n")
7586 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7587 (match_operand 3 "immediate_operand" "n")))
7588 (use (reg:SI R0_REG))
7589 (use (reg:SI R1_REG))
7590 (use (reg:PSI FPSCR_REG))
7591 (clobber (reg:SI R10_REG))
7592 (clobber (reg:SI PR_REG))]
7593 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7595 [(set_attr "type" "call")
7596 (set (attr "fp_mode")
7597 (if_then_else (eq_attr "fpu_single" "yes")
7598 (const_string "single") (const_string "double")))
7599 (set_attr "needs_delay_slot" "yes")])
7601 (define_expand "call_pop"
7602 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7603 (match_operand 1 "" ""))
7604 (match_operand 2 "" "")
7605 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7606 (match_operand 3 "" "")))])]
7615 gcc_assert (operands[2] && INTVAL (operands[2]));
7616 cookie_rtx = operands[2];
7617 cookie = INTVAL (cookie_rtx);
7618 func = XEXP (operands[0], 0);
7622 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7624 rtx reg = gen_reg_rtx (Pmode);
7625 emit_insn (gen_symGOTPLT2reg (reg, func));
7629 func = legitimize_pic_address (func, Pmode, 0);
7632 r0 = gen_rtx_REG (SImode, R0_REG);
7633 r1 = gen_rtx_REG (SImode, R1_REG);
7635 /* Since such a call function may use all call-clobbered
7636 registers, we force a mode switch earlier, so that we don't
7637 run out of registers when adjusting fpscr for the call. */
7638 emit_insn (gen_force_mode_for_call ());
7640 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7642 operands[0] = force_reg (SImode, operands[0]);
7644 emit_move_insn (r0, func);
7645 emit_move_insn (r1, cookie_rtx);
7647 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7648 emit_call_insn (gen_call_pop_compact_rettramp
7649 (operands[0], operands[1], operands[2], operands[3]));
7651 emit_call_insn (gen_call_pop_compact
7652 (operands[0], operands[1], operands[2], operands[3]));
7657 (define_expand "call_value"
7658 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7659 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7660 (match_operand 2 "" "")))
7661 (match_operand 3 "" "")
7662 (use (reg:PSI FPSCR_REG))
7663 (clobber (reg:SI PR_REG))])]
7669 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7670 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7674 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7676 rtx cookie_rtx = operands[3];
7677 long cookie = INTVAL (cookie_rtx);
7678 rtx func = XEXP (operands[1], 0);
7683 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7685 rtx reg = gen_reg_rtx (Pmode);
7687 emit_insn (gen_symGOTPLT2reg (reg, func));
7691 func = legitimize_pic_address (func, Pmode, 0);
7694 r0 = gen_rtx_REG (SImode, R0_REG);
7695 r1 = gen_rtx_REG (SImode, R1_REG);
7697 /* Since such a call function may use all call-clobbered
7698 registers, we force a mode switch earlier, so that we don't
7699 run out of registers when adjusting fpscr for the call. */
7700 emit_insn (gen_force_mode_for_call ());
7703 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7705 operands[1] = force_reg (SImode, operands[1]);
7707 emit_move_insn (r0, func);
7708 emit_move_insn (r1, cookie_rtx);
7710 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7711 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7716 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7717 operands[2], operands[3]));
7721 else if (TARGET_SHCOMPACT && flag_pic
7722 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7723 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7725 rtx reg = gen_reg_rtx (Pmode);
7727 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7728 XEXP (operands[1], 0) = reg;
7730 if (flag_pic && TARGET_SH2
7731 && GET_CODE (operands[1]) == MEM
7732 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7734 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7739 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7741 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7745 (define_insn "sibcalli"
7746 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7747 (match_operand 1 "" ""))
7748 (use (reg:PSI FPSCR_REG))
7752 [(set_attr "needs_delay_slot" "yes")
7753 (set (attr "fp_mode")
7754 (if_then_else (eq_attr "fpu_single" "yes")
7755 (const_string "single") (const_string "double")))
7756 (set_attr "type" "jump_ind")])
7758 (define_insn "sibcalli_pcrel"
7759 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7760 (match_operand 1 "" ""))
7761 (use (match_operand 2 "" ""))
7762 (use (reg:PSI FPSCR_REG))
7766 [(set_attr "needs_delay_slot" "yes")
7767 (set (attr "fp_mode")
7768 (if_then_else (eq_attr "fpu_single" "yes")
7769 (const_string "single") (const_string "double")))
7770 (set_attr "type" "jump_ind")])
7772 ;; This uses an unspec to describe that the symbol_ref is very close.
7773 (define_insn "sibcalli_thunk"
7774 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7776 (match_operand 1 "" ""))
7777 (use (reg:PSI FPSCR_REG))
7781 [(set_attr "needs_delay_slot" "yes")
7782 (set (attr "fp_mode")
7783 (if_then_else (eq_attr "fpu_single" "yes")
7784 (const_string "single") (const_string "double")))
7785 (set_attr "type" "jump")
7786 (set_attr "length" "2")])
7788 (define_insn_and_split "sibcall_pcrel"
7789 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7790 (match_operand 1 "" ""))
7791 (use (reg:PSI FPSCR_REG))
7792 (clobber (match_scratch:SI 2 "=k"))
7800 rtx lab = PATTERN (gen_call_site ());
7803 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7804 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7806 SIBLING_CALL_P (call_insn) = 1;
7809 [(set_attr "needs_delay_slot" "yes")
7810 (set (attr "fp_mode")
7811 (if_then_else (eq_attr "fpu_single" "yes")
7812 (const_string "single") (const_string "double")))
7813 (set_attr "type" "jump_ind")])
7815 (define_insn "sibcall_compact"
7816 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7817 (match_operand 1 "" ""))
7819 (use (match_operand:SI 2 "register_operand" "z,x"))
7820 (use (reg:SI R1_REG))
7821 (use (reg:PSI FPSCR_REG))
7822 ;; We want to make sure the `x' above will only match MACH_REG
7823 ;; because sibcall_epilogue may clobber MACL_REG.
7824 (clobber (reg:SI MACL_REG))]
7828 jmp @%0\\n sts %2, r0"
7829 [(set_attr "needs_delay_slot" "yes,no")
7830 (set_attr "length" "2,4")
7831 (set (attr "fp_mode") (const_string "single"))
7832 (set_attr "type" "jump_ind")])
7834 (define_insn "sibcall_media"
7835 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7836 (match_operand 1 "" ""))
7837 (use (reg:SI PR_MEDIA_REG))
7841 [(set_attr "type" "jump_media")])
7843 (define_expand "sibcall"
7845 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7846 (match_operand 1 "" ""))
7847 (match_operand 2 "" "")
7848 (use (reg:PSI FPSCR_REG))
7855 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7856 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7859 else if (TARGET_SHCOMPACT && operands[2]
7860 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7862 rtx cookie_rtx = operands[2];
7863 long cookie = INTVAL (cookie_rtx);
7864 rtx func = XEXP (operands[0], 0);
7869 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7871 rtx reg = gen_reg_rtx (Pmode);
7873 emit_insn (gen_symGOT2reg (reg, func));
7877 func = legitimize_pic_address (func, Pmode, 0);
7880 /* FIXME: if we could tell whether all argument registers are
7881 already taken, we could decide whether to force the use of
7882 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7883 simple way to tell. We could use the CALL_COOKIE, but we
7884 can't currently tell a register used for regular argument
7885 passing from one that is unused. If we leave it up to reload
7886 to decide which register to use, it seems to always choose
7887 R0_REG, which leaves no available registers in SIBCALL_REGS
7888 to hold the address of the trampoline. */
7889 mach = gen_rtx_REG (SImode, MACH_REG);
7890 r1 = gen_rtx_REG (SImode, R1_REG);
7892 /* Since such a call function may use all call-clobbered
7893 registers, we force a mode switch earlier, so that we don't
7894 run out of registers when adjusting fpscr for the call. */
7895 emit_insn (gen_force_mode_for_call ());
7898 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7900 operands[0] = force_reg (SImode, operands[0]);
7902 /* We don't need a return trampoline, since the callee will
7903 return directly to the upper caller. */
7904 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7906 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7907 cookie_rtx = GEN_INT (cookie);
7910 emit_move_insn (mach, func);
7911 emit_move_insn (r1, cookie_rtx);
7913 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7916 else if (TARGET_SHCOMPACT && flag_pic
7917 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7918 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7920 rtx reg = gen_reg_rtx (Pmode);
7922 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7923 XEXP (operands[0], 0) = reg;
7925 if (flag_pic && TARGET_SH2
7926 && GET_CODE (operands[0]) == MEM
7927 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7928 /* The PLT needs the PIC register, but the epilogue would have
7929 to restore it, so we can only use PC-relative PIC calls for
7930 static functions. */
7931 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7933 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7937 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7939 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7943 (define_expand "sibcall_value"
7944 [(set (match_operand 0 "" "")
7945 (call (match_operand 1 "" "")
7946 (match_operand 2 "" "")))
7947 (match_operand 3 "" "")]
7951 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7955 (define_insn "call_value_pop_compact"
7956 [(set (match_operand 0 "" "=rf")
7957 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7958 (match_operand 2 "" "")))
7959 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7960 (match_operand 4 "immediate_operand" "n")))
7961 (match_operand 3 "immediate_operand" "n")
7962 (use (reg:SI R0_REG))
7963 (use (reg:SI R1_REG))
7964 (use (reg:PSI FPSCR_REG))
7965 (clobber (reg:SI PR_REG))]
7966 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7968 [(set_attr "type" "call")
7969 (set (attr "fp_mode")
7970 (if_then_else (eq_attr "fpu_single" "yes")
7971 (const_string "single") (const_string "double")))
7972 (set_attr "needs_delay_slot" "yes")])
7974 (define_insn "call_value_pop_compact_rettramp"
7975 [(set (match_operand 0 "" "=rf")
7976 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7977 (match_operand 2 "" "")))
7978 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7979 (match_operand 4 "immediate_operand" "n")))
7980 (match_operand 3 "immediate_operand" "n")
7981 (use (reg:SI R0_REG))
7982 (use (reg:SI R1_REG))
7983 (use (reg:PSI FPSCR_REG))
7984 (clobber (reg:SI R10_REG))
7985 (clobber (reg:SI PR_REG))]
7986 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7988 [(set_attr "type" "call")
7989 (set (attr "fp_mode")
7990 (if_then_else (eq_attr "fpu_single" "yes")
7991 (const_string "single") (const_string "double")))
7992 (set_attr "needs_delay_slot" "yes")])
7994 (define_expand "call_value_pop"
7995 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7996 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7997 (match_operand 2 "" "")))
7998 (match_operand 3 "" "")
7999 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8000 (match_operand 4 "" "")))])]
8009 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8010 cookie_rtx = operands[3];
8011 cookie = INTVAL (cookie_rtx);
8012 func = XEXP (operands[1], 0);
8016 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8018 rtx reg = gen_reg_rtx (Pmode);
8020 emit_insn (gen_symGOTPLT2reg (reg, func));
8024 func = legitimize_pic_address (func, Pmode, 0);
8027 r0 = gen_rtx_REG (SImode, R0_REG);
8028 r1 = gen_rtx_REG (SImode, R1_REG);
8030 /* Since such a call function may use all call-clobbered
8031 registers, we force a mode switch earlier, so that we don't
8032 run out of registers when adjusting fpscr for the call. */
8033 emit_insn (gen_force_mode_for_call ());
8035 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8037 operands[1] = force_reg (SImode, operands[1]);
8039 emit_move_insn (r0, func);
8040 emit_move_insn (r1, cookie_rtx);
8042 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8043 emit_call_insn (gen_call_value_pop_compact_rettramp
8044 (operands[0], operands[1], operands[2],
8045 operands[3], operands[4]));
8047 emit_call_insn (gen_call_value_pop_compact
8048 (operands[0], operands[1], operands[2],
8049 operands[3], operands[4]));
8054 (define_expand "sibcall_epilogue"
8059 sh_expand_epilogue (1);
8060 if (TARGET_SHCOMPACT)
8064 /* If epilogue clobbers r0, preserve it in macl. */
8065 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8066 if ((set = single_set (insn))
8067 && GET_CODE (SET_DEST (set)) == REG
8068 && REGNO (SET_DEST (set)) == R0_REG)
8070 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8071 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8074 /* We can't tell at this point whether the sibcall is a
8075 sibcall_compact and, if it is, whether it uses r0 or
8076 mach as operand 2, so let the instructions that
8077 preserve r0 be optimized away if r0 turns out to be
8079 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8080 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8082 i = emit_move_insn (r0, tmp);
8083 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8091 (define_insn "indirect_jump_compact"
8093 (match_operand:SI 0 "arith_reg_operand" "r"))]
8096 [(set_attr "needs_delay_slot" "yes")
8097 (set_attr "type" "jump_ind")])
8099 (define_expand "indirect_jump"
8101 (match_operand 0 "register_operand" ""))]
8105 if (GET_MODE (operands[0]) != Pmode)
8106 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8109 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8110 ;; which can be present in structured code from indirect jumps which can not
8111 ;; be present in structured code. This allows -fprofile-arcs to work.
8113 ;; For SH1 processors.
8114 (define_insn "casesi_jump_1"
8116 (match_operand:SI 0 "register_operand" "r"))
8117 (use (label_ref (match_operand 1 "" "")))]
8120 [(set_attr "needs_delay_slot" "yes")
8121 (set_attr "type" "jump_ind")])
8123 ;; For all later processors.
8124 (define_insn "casesi_jump_2"
8125 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8126 (label_ref (match_operand 1 "" ""))))
8127 (use (label_ref (match_operand 2 "" "")))]
8129 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8131 [(set_attr "needs_delay_slot" "yes")
8132 (set_attr "type" "jump_ind")])
8134 (define_insn "casesi_jump_media"
8135 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8136 (use (label_ref (match_operand 1 "" "")))]
8139 [(set_attr "type" "jump_media")])
8141 ;; Call subroutine returning any type.
8142 ;; ??? This probably doesn't work.
8144 (define_expand "untyped_call"
8145 [(parallel [(call (match_operand 0 "" "")
8147 (match_operand 1 "" "")
8148 (match_operand 2 "" "")])]
8149 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8154 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8156 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8158 rtx set = XVECEXP (operands[2], 0, i);
8159 emit_move_insn (SET_DEST (set), SET_SRC (set));
8162 /* The optimizer does not know that the call sets the function value
8163 registers we stored in the result block. We avoid problems by
8164 claiming that all hard registers are used and clobbered at this
8166 emit_insn (gen_blockage ());
8171 ;; ------------------------------------------------------------------------
8173 ;; ------------------------------------------------------------------------
8176 [(set (reg:SI T_REG)
8177 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8178 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8181 [(set_attr "type" "arith")])
8188 ;; Load address of a label. This is only generated by the casesi expand,
8189 ;; and by machine_dependent_reorg (fixing up fp moves).
8190 ;; This must use unspec, because this only works for labels that are
8194 [(set (reg:SI R0_REG)
8195 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8198 [(set_attr "in_delay_slot" "no")
8199 (set_attr "type" "arith")])
8201 ;; machine_dependent_reorg will make this a `mova'.
8202 (define_insn "mova_const"
8203 [(set (reg:SI R0_REG)
8204 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8207 [(set_attr "in_delay_slot" "no")
8208 (set_attr "type" "arith")])
8210 (define_expand "GOTaddr2picreg"
8211 [(set (reg:SI R0_REG)
8212 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8214 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8215 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8218 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8219 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8223 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8224 rtx pic = operands[0];
8225 rtx lab = PATTERN (gen_call_site ());
8228 equiv = operands[1];
8229 operands[1] = gen_rtx_MINUS (Pmode,
8233 gen_rtx_MINUS (Pmode,
8234 gen_rtx_CONST (Pmode,
8237 operands[1] = gen_sym2PIC (operands[1]);
8238 PUT_MODE (operands[1], Pmode);
8240 if (Pmode == SImode)
8242 emit_insn (gen_movsi_const (pic, operands[1]));
8243 emit_insn (gen_ptrel_si (tr, pic, lab));
8247 emit_insn (gen_movdi_const (pic, operands[1]));
8248 emit_insn (gen_ptrel_di (tr, pic, lab));
8251 insn = emit_move_insn (operands[0], tr);
8253 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8262 [(set (match_operand 0 "target_reg_operand" "=b")
8263 (const (unspec [(match_operand 1 "" "Csy")]
8264 UNSPEC_DATALABEL)))]
8265 "TARGET_SHMEDIA && flag_pic
8266 && EXTRA_CONSTRAINT_Csy (operands[1])"
8267 "ptb/u datalabel %1, %0"
8268 [(set_attr "type" "ptabs_media")
8269 (set_attr "length" "*")])
8271 (define_insn "ptrel_si"
8272 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8273 (plus:SI (match_operand:SI 1 "register_operand" "r")
8275 (match_operand:SI 2 "" "")]
8277 "%O2: ptrel/u %1, %0"
8278 [(set_attr "type" "ptabs_media")])
8280 (define_insn "ptrel_di"
8281 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8282 (plus:DI (match_operand:DI 1 "register_operand" "r")
8284 (match_operand:DI 2 "" "")]
8286 "%O2: ptrel/u %1, %0"
8287 [(set_attr "type" "ptabs_media")])
8289 (define_expand "builtin_setjmp_receiver"
8290 [(match_operand 0 "" "")]
8294 emit_insn (gen_GOTaddr2picreg ());
8298 (define_expand "call_site"
8299 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8303 static HOST_WIDE_INT i = 0;
8304 operands[0] = GEN_INT (i);
8308 (define_expand "sym_label2reg"
8309 [(set (match_operand:SI 0 "" "")
8312 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8315 (match_operand:SI 2 "" "")
8319 (define_expand "symGOT_load"
8320 [(set (match_dup 2) (match_operand 1 "" ""))
8321 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8322 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8328 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8329 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8333 rtx reg = operands[2];
8335 if (Pmode == DImode)
8338 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8340 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8345 emit_insn (gen_movsi_const (reg, operands[1]));
8347 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8351 emit_move_insn (operands[2], operands[1]);
8353 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8355 gen_rtx_REG (Pmode, PIC_REG)));
8357 /* N.B. This is not constant for a GOTPLT relocation. */
8358 mem = gen_rtx_MEM (Pmode, operands[3]);
8359 MEM_NOTRAP_P (mem) = 1;
8360 /* ??? Should we have a special alias set for the GOT? */
8361 insn = emit_move_insn (operands[0], mem);
8363 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8370 (define_expand "sym2GOT"
8371 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8375 (define_expand "symGOT2reg"
8376 [(match_operand 0 "" "") (match_operand 1 "" "")]
8382 gotsym = gen_sym2GOT (operands[1]);
8383 PUT_MODE (gotsym, Pmode);
8384 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8386 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8391 (define_expand "symGOTPLT2reg"
8392 [(match_operand 0 "" "") (match_operand 1 "" "")]
8396 rtx pltsym = gen_rtx_CONST (Pmode,
8397 gen_rtx_UNSPEC (Pmode,
8398 gen_rtvec (1, operands[1]),
8400 emit_insn (gen_symGOT_load (operands[0], pltsym));
8404 (define_expand "sym2GOTOFF"
8405 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8409 (define_expand "symGOTOFF2reg"
8410 [(match_operand 0 "" "") (match_operand 1 "" "")]
8414 rtx gotoffsym, insn;
8415 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8417 gotoffsym = gen_sym2GOTOFF (operands[1]);
8418 PUT_MODE (gotoffsym, Pmode);
8419 emit_move_insn (t, gotoffsym);
8420 insn = emit_move_insn (operands[0],
8421 gen_rtx_PLUS (Pmode, t,
8422 gen_rtx_REG (Pmode, PIC_REG)));
8424 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8430 (define_expand "symPLT_label2reg"
8431 [(set (match_operand:SI 0 "" "")
8434 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8438 (match_operand:SI 2 "" "")
8440 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8441 ;; Even though the PIC register is not really used by the call
8442 ;; sequence in which this is expanded, the PLT code assumes the PIC
8443 ;; register is set, so we must not skip its initialization. Since
8444 ;; we only use this expand as part of calling sequences, and never
8445 ;; to take the address of a function, this is the best point to
8446 ;; insert the (use). Using the PLT to take the address of a
8447 ;; function would be wrong, not only because the PLT entry could
8448 ;; then be called from a function that doesn't initialize the PIC
8449 ;; register to the proper GOT, but also because pointers to the
8450 ;; same function might not compare equal, should they be set by
8451 ;; different shared libraries.
8452 (use (reg:SI PIC_REG))]
8456 (define_expand "sym2PIC"
8457 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8461 ;; TLS code generation.
8462 ;; ??? this should be a define_insn_and_split
8463 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8464 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8467 (define_insn "tls_global_dynamic"
8468 [(set (match_operand:SI 0 "register_operand" "=&z")
8469 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8472 (use (reg:PSI FPSCR_REG))
8473 (use (reg:SI PIC_REG))
8474 (clobber (reg:SI PR_REG))
8475 (clobber (scratch:SI))]
8481 \\tmova\\t2f,r0\\n\\
8482 \\tmov.l\\t2f,r1\\n\\
8485 \\tadd\\tr12,r4\\n\\
8489 1:\\t.long\\t%a1@TLSGD\\n\\
8490 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8493 [(set_attr "type" "tls_load")
8494 (set_attr "length" "26")])
8496 (define_insn "tls_local_dynamic"
8497 [(set (match_operand:SI 0 "register_operand" "=&z")
8498 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8501 (use (reg:PSI FPSCR_REG))
8502 (use (reg:SI PIC_REG))
8503 (clobber (reg:SI PR_REG))
8504 (clobber (scratch:SI))]
8510 \\tmova\\t2f,r0\\n\\
8511 \\tmov.l\\t2f,r1\\n\\
8514 \\tadd\\tr12,r4\\n\\
8518 1:\\t.long\\t%a1@TLSLDM\\n\\
8519 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8522 [(set_attr "type" "tls_load")
8523 (set_attr "length" "26")])
8525 (define_expand "sym2DTPOFF"
8526 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8530 (define_expand "symDTPOFF2reg"
8531 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8535 rtx dtpoffsym, insn;
8536 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8538 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8539 PUT_MODE (dtpoffsym, Pmode);
8540 emit_move_insn (t, dtpoffsym);
8541 insn = emit_move_insn (operands[0],
8542 gen_rtx_PLUS (Pmode, t, operands[2]));
8546 (define_expand "sym2GOTTPOFF"
8547 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8551 (define_insn "tls_initial_exec"
8552 [(set (match_operand:SI 0 "register_operand" "=&r")
8553 (unspec:SI [(match_operand:SI 1 "" "")]
8555 (use (reg:SI GBR_REG))
8556 (use (reg:SI PIC_REG))
8557 (clobber (reg:SI R0_REG))]
8563 \\tstc\\tgbr,%0\\n\\
8564 \\tmov.l\\t@(r0,r12),r0\\n\\
8568 1:\\t.long\\t%a1\\n\\
8571 [(set_attr "type" "tls_load")
8572 (set_attr "length" "16")])
8574 (define_expand "sym2TPOFF"
8575 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8579 (define_expand "symTPOFF2reg"
8580 [(match_operand 0 "" "") (match_operand 1 "" "")]
8586 tpoffsym = gen_sym2TPOFF (operands[1]);
8587 PUT_MODE (tpoffsym, Pmode);
8588 insn = emit_move_insn (operands[0], tpoffsym);
8592 (define_insn "load_gbr"
8593 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8594 (use (reg:SI GBR_REG))]
8597 [(set_attr "type" "tls_load")])
8599 ;; case instruction for switch statements.
8601 ;; Operand 0 is index
8602 ;; operand 1 is the minimum bound
8603 ;; operand 2 is the maximum bound - minimum bound + 1
8604 ;; operand 3 is CODE_LABEL for the table;
8605 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8607 (define_expand "casesi"
8608 [(match_operand:SI 0 "arith_reg_operand" "")
8609 (match_operand:SI 1 "arith_reg_operand" "")
8610 (match_operand:SI 2 "arith_reg_operand" "")
8611 (match_operand 3 "" "") (match_operand 4 "" "")]
8615 rtx reg = gen_reg_rtx (SImode);
8616 rtx reg2 = gen_reg_rtx (SImode);
8619 rtx reg = gen_reg_rtx (DImode);
8620 rtx reg2 = gen_reg_rtx (DImode);
8621 rtx reg3 = gen_reg_rtx (Pmode);
8622 rtx reg4 = gen_reg_rtx (Pmode);
8623 rtx reg5 = gen_reg_rtx (Pmode);
8626 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8627 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8628 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8630 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8631 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8632 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8633 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8634 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8635 (Pmode, operands[3])));
8636 /* Messy: can we subreg to clean this up? */
8637 if (Pmode == DImode)
8638 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8640 load = gen_casesi_load_media (reg4,
8641 gen_rtx_SUBREG (DImode, reg3, 0),
8643 PUT_MODE (SET_SRC (load), Pmode);
8645 /* ??? The following add could be eliminated if we used ptrel. */
8646 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8647 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8651 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8652 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8653 /* If optimizing, casesi_worker depends on the mode of the instruction
8654 before label it 'uses' - operands[3]. */
8655 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8657 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8659 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8661 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8662 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8663 operands[3], but to lab. We will fix this up in
8664 machine_dependent_reorg. */
8669 (define_expand "casesi_0"
8670 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8671 (set (match_dup 4) (minus:SI (match_dup 4)
8672 (match_operand:SI 1 "arith_operand" "")))
8674 (gtu:SI (match_dup 4)
8675 (match_operand:SI 2 "arith_reg_operand" "")))
8677 (if_then_else (ne (reg:SI T_REG)
8679 (label_ref (match_operand 3 "" ""))
8684 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8685 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8686 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8688 (define_insn "casesi_worker_0"
8689 [(set (match_operand:SI 0 "register_operand" "=r,r")
8690 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8691 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8692 (clobber (match_scratch:SI 3 "=X,1"))
8693 (clobber (match_scratch:SI 4 "=&z,z"))]
8698 [(set (match_operand:SI 0 "register_operand" "")
8699 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8700 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8701 (clobber (match_scratch:SI 3 ""))
8702 (clobber (match_scratch:SI 4 ""))]
8703 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8704 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8705 (parallel [(set (match_dup 0)
8706 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8707 (label_ref (match_dup 2))] UNSPEC_CASESI))
8708 (clobber (match_dup 3))])
8709 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8710 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8713 [(set (match_operand:SI 0 "register_operand" "")
8714 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8715 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8716 (clobber (match_scratch:SI 3 ""))
8717 (clobber (match_scratch:SI 4 ""))]
8718 "TARGET_SH2 && reload_completed"
8719 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8720 (parallel [(set (match_dup 0)
8721 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8722 (label_ref (match_dup 2))] UNSPEC_CASESI))
8723 (clobber (match_dup 3))])]
8724 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8726 (define_insn "casesi_worker_1"
8727 [(set (match_operand:SI 0 "register_operand" "=r,r")
8728 (unspec:SI [(reg:SI R0_REG)
8729 (match_operand:SI 1 "register_operand" "0,r")
8730 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8731 (clobber (match_scratch:SI 3 "=X,1"))]
8735 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8737 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8739 switch (GET_MODE (diff_vec))
8742 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8744 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8746 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8747 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8748 return \"mov.b @(r0,%1),%0\";
8753 [(set_attr "length" "4")])
8755 (define_insn "casesi_worker_2"
8756 [(set (match_operand:SI 0 "register_operand" "=r,r")
8757 (unspec:SI [(reg:SI R0_REG)
8758 (match_operand:SI 1 "register_operand" "0,r")
8759 (label_ref (match_operand 2 "" ""))
8760 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8761 (clobber (match_operand:SI 4 "" "=X,1"))]
8762 "TARGET_SH2 && reload_completed && flag_pic"
8765 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8768 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8770 switch (GET_MODE (diff_vec))
8773 output_asm_insn (\"shll2 %1\", operands);
8774 load = \"mov.l @(r0,%1),%0\"; break;
8776 output_asm_insn (\"add %1,%1\", operands);
8777 load = \"mov.w @(r0,%1),%0\"; break;
8779 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8780 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8782 load = \"mov.b @(r0,%1),%0\";
8787 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8790 [(set_attr "length" "8")])
8792 (define_insn "casesi_shift_media"
8793 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8794 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8795 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8800 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8802 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8804 switch (GET_MODE (diff_vec))
8807 return \"shlli %1, 2, %0\";
8809 return \"shlli %1, 1, %0\";
8811 if (rtx_equal_p (operands[0], operands[1]))
8813 return \"add %1, r63, %0\";
8818 [(set_attr "type" "arith_media")])
8820 (define_insn "casesi_load_media"
8821 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8822 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8823 (match_operand:DI 2 "arith_reg_operand" "r")
8824 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8828 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8830 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8832 switch (GET_MODE (diff_vec))
8835 return \"ldx.l %1, %2, %0\";
8838 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8839 return \"ldx.uw %1, %2, %0\";
8841 return \"ldx.w %1, %2, %0\";
8843 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8844 return \"ldx.ub %1, %2, %0\";
8845 return \"ldx.b %1, %2, %0\";
8850 [(set_attr "type" "load_media")])
8852 (define_expand "return"
8854 "reload_completed && ! sh_need_epilogue ()"
8859 emit_jump_insn (gen_return_media ());
8863 if (TARGET_SHCOMPACT
8864 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8866 emit_jump_insn (gen_shcompact_return_tramp ());
8871 (define_insn "*return_i"
8873 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8874 && (current_function_args_info.call_cookie
8875 & CALL_COOKIE_RET_TRAMP (1)))
8877 && lookup_attribute (\"trap_exit\",
8878 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8880 [(set_attr "type" "return")
8881 (set_attr "needs_delay_slot" "yes")])
8883 ;; trapa has no delay slot.
8884 (define_insn "*return_trapa"
8886 "TARGET_SH1 && !TARGET_SHCOMPACT
8887 && reload_completed"
8889 [(set_attr "type" "return")])
8891 (define_expand "shcompact_return_tramp"
8894 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8897 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8899 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8900 emit_jump_insn (gen_shcompact_return_tramp_i ());
8904 (define_insn "shcompact_return_tramp_i"
8905 [(parallel [(return) (use (reg:SI R0_REG))])]
8907 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8909 [(set_attr "type" "jump_ind")
8910 (set_attr "needs_delay_slot" "yes")])
8912 (define_insn "return_media_i"
8913 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8914 "TARGET_SHMEDIA && reload_completed"
8916 [(set_attr "type" "jump_media")])
8918 (define_insn "return_media_rte"
8920 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8922 [(set_attr "type" "jump_media")])
8924 (define_expand "return_media"
8926 "TARGET_SHMEDIA && reload_completed"
8929 int tr_regno = sh_media_register_for_return ();
8932 if (current_function_interrupt)
8934 emit_jump_insn (gen_return_media_rte ());
8939 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8941 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8943 tr = gen_rtx_REG (Pmode, tr_regno);
8944 emit_move_insn (tr, r18);
8947 tr = gen_rtx_REG (Pmode, tr_regno);
8949 emit_jump_insn (gen_return_media_i (tr));
8953 (define_insn "shcompact_preserve_incoming_args"
8954 [(set (match_operand:SI 0 "register_operand" "+r")
8955 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8958 [(set_attr "length" "0")])
8960 (define_insn "shcompact_incoming_args"
8961 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8962 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8963 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8964 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8965 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8966 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8967 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8968 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8969 (set (mem:BLK (reg:SI MACL_REG))
8970 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8971 (use (reg:SI R0_REG))
8972 (clobber (reg:SI R0_REG))
8973 (clobber (reg:SI MACL_REG))
8974 (clobber (reg:SI MACH_REG))
8975 (clobber (reg:SI PR_REG))]
8978 [(set_attr "needs_delay_slot" "yes")])
8980 (define_insn "shmedia_save_restore_regs_compact"
8981 [(set (reg:SI SP_REG)
8982 (plus:SI (reg:SI SP_REG)
8983 (match_operand:SI 0 "immediate_operand" "i")))
8984 (use (reg:SI R0_REG))
8985 (clobber (reg:SI PR_REG))]
8987 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8988 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8990 [(set_attr "needs_delay_slot" "yes")])
8992 (define_expand "prologue"
8995 "sh_expand_prologue (); DONE;")
8997 (define_expand "epilogue"
9002 sh_expand_epilogue (0);
9003 emit_jump_insn (gen_return ());
9007 (define_expand "eh_return"
9008 [(use (match_operand 0 "register_operand" ""))]
9011 rtx ra = operands[0];
9013 if (TARGET_SHMEDIA64)
9014 emit_insn (gen_eh_set_ra_di (ra));
9016 emit_insn (gen_eh_set_ra_si (ra));
9021 ;; Clobber the return address on the stack. We can't expand this
9022 ;; until we know where it will be put in the stack frame.
9024 (define_insn "eh_set_ra_si"
9025 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9026 (clobber (match_scratch:SI 1 "=&r"))]
9027 "! TARGET_SHMEDIA64"
9030 (define_insn "eh_set_ra_di"
9031 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9032 (clobber (match_scratch:DI 1 "=&r"))]
9037 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9038 (clobber (match_scratch 1 ""))]
9043 sh_set_return_address (operands[0], operands[1]);
9047 (define_insn "blockage"
9048 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9051 [(set_attr "length" "0")])
9053 ;; ------------------------------------------------------------------------
9055 ;; ------------------------------------------------------------------------
9058 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9059 (eq:SI (reg:SI T_REG) (const_int 1)))]
9062 [(set_attr "type" "arith")])
9064 (define_expand "seq"
9065 [(set (match_operand:SI 0 "arith_reg_dest" "")
9072 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9073 if (sh_compare_op1 != const0_rtx)
9074 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9075 ? GET_MODE (sh_compare_op0)
9076 : GET_MODE (sh_compare_op1),
9078 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9080 if (GET_MODE (operands[0]) != SImode)
9081 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9083 switch (GET_MODE (sh_compare_op0))
9086 emit_insn (gen_cmpsieqsi_media (operands[0],
9087 sh_compare_op0, sh_compare_op1));
9091 emit_insn (gen_cmpsieqdi_media (operands[0],
9092 sh_compare_op0, sh_compare_op1));
9096 if (! TARGET_SHMEDIA_FPU)
9098 emit_insn (gen_cmpsieqsf_media (operands[0],
9099 sh_compare_op0, sh_compare_op1));
9103 if (! TARGET_SHMEDIA_FPU)
9105 emit_insn (gen_cmpsieqdf_media (operands[0],
9106 sh_compare_op0, sh_compare_op1));
9115 if (GET_MODE (operands[0]) != DImode)
9116 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9118 switch (GET_MODE (sh_compare_op0))
9121 emit_insn (gen_cmpeqsi_media (operands[0],
9122 sh_compare_op0, sh_compare_op1));
9126 emit_insn (gen_cmpeqdi_media (operands[0],
9127 sh_compare_op0, sh_compare_op1));
9131 if (! TARGET_SHMEDIA_FPU)
9133 emit_insn (gen_cmpeqsf_media (operands[0],
9134 sh_compare_op0, sh_compare_op1));
9138 if (! TARGET_SHMEDIA_FPU)
9140 emit_insn (gen_cmpeqdf_media (operands[0],
9141 sh_compare_op0, sh_compare_op1));
9149 if (sh_expand_t_scc (EQ, operands[0]))
9151 if (! currently_expanding_to_rtl)
9153 operands[1] = prepare_scc_operands (EQ);
9156 (define_expand "slt"
9157 [(set (match_operand:SI 0 "arith_reg_operand" "")
9164 if (GET_MODE (operands[0]) != DImode)
9165 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9166 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9167 if (sh_compare_op1 != const0_rtx)
9168 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9169 ? GET_MODE (sh_compare_op0)
9170 : GET_MODE (sh_compare_op1),
9173 switch (GET_MODE (sh_compare_op0))
9176 emit_insn (gen_cmpgtsi_media (operands[0],
9177 sh_compare_op1, sh_compare_op0));
9181 emit_insn (gen_cmpgtdi_media (operands[0],
9182 sh_compare_op1, sh_compare_op0));
9186 if (! TARGET_SHMEDIA_FPU)
9188 emit_insn (gen_cmpgtsf_media (operands[0],
9189 sh_compare_op1, sh_compare_op0));
9193 if (! TARGET_SHMEDIA_FPU)
9195 emit_insn (gen_cmpgtdf_media (operands[0],
9196 sh_compare_op1, sh_compare_op0));
9204 if (! currently_expanding_to_rtl)
9206 operands[1] = prepare_scc_operands (LT);
9209 (define_expand "sle"
9210 [(match_operand:SI 0 "arith_reg_operand" "")]
9214 rtx tmp = sh_compare_op0;
9218 if (GET_MODE (operands[0]) != DImode)
9219 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9220 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9221 if (sh_compare_op1 != const0_rtx)
9222 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9223 ? GET_MODE (sh_compare_op0)
9224 : GET_MODE (sh_compare_op1),
9227 switch (GET_MODE (sh_compare_op0))
9231 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9233 emit_insn (gen_cmpgtsi_media (tmp,
9234 sh_compare_op0, sh_compare_op1));
9235 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9241 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9243 emit_insn (gen_cmpgtdi_media (tmp,
9244 sh_compare_op0, sh_compare_op1));
9245 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9250 if (! TARGET_SHMEDIA_FPU)
9252 emit_insn (gen_cmpgesf_media (operands[0],
9253 sh_compare_op1, sh_compare_op0));
9257 if (! TARGET_SHMEDIA_FPU)
9259 emit_insn (gen_cmpgedf_media (operands[0],
9260 sh_compare_op1, sh_compare_op0));
9269 sh_compare_op0 = sh_compare_op1;
9270 sh_compare_op1 = tmp;
9271 emit_insn (gen_sge (operands[0]));
9275 (define_expand "sgt"
9276 [(set (match_operand:SI 0 "arith_reg_operand" "")
9283 if (GET_MODE (operands[0]) != DImode)
9284 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9285 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9286 if (sh_compare_op1 != const0_rtx)
9287 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9288 ? GET_MODE (sh_compare_op0)
9289 : GET_MODE (sh_compare_op1),
9292 switch (GET_MODE (sh_compare_op0))
9295 emit_insn (gen_cmpgtsi_media (operands[0],
9296 sh_compare_op0, sh_compare_op1));
9300 emit_insn (gen_cmpgtdi_media (operands[0],
9301 sh_compare_op0, sh_compare_op1));
9305 if (! TARGET_SHMEDIA_FPU)
9307 emit_insn (gen_cmpgtsf_media (operands[0],
9308 sh_compare_op0, sh_compare_op1));
9312 if (! TARGET_SHMEDIA_FPU)
9314 emit_insn (gen_cmpgtdf_media (operands[0],
9315 sh_compare_op0, sh_compare_op1));
9323 if (! currently_expanding_to_rtl)
9325 operands[1] = prepare_scc_operands (GT);
9328 (define_expand "sge"
9329 [(set (match_operand:SI 0 "arith_reg_operand" "")
9336 enum machine_mode mode = GET_MODE (sh_compare_op0);
9338 if ((mode) == VOIDmode)
9339 mode = GET_MODE (sh_compare_op1);
9340 if (GET_MODE (operands[0]) != DImode)
9341 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9342 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9343 if (sh_compare_op1 != const0_rtx)
9344 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9350 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9352 emit_insn (gen_cmpgtsi_media (tmp,
9353 sh_compare_op1, sh_compare_op0));
9354 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9360 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9362 emit_insn (gen_cmpgtdi_media (tmp,
9363 sh_compare_op1, sh_compare_op0));
9364 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9369 if (! TARGET_SHMEDIA_FPU)
9371 emit_insn (gen_cmpgesf_media (operands[0],
9372 sh_compare_op0, sh_compare_op1));
9376 if (! TARGET_SHMEDIA_FPU)
9378 emit_insn (gen_cmpgedf_media (operands[0],
9379 sh_compare_op0, sh_compare_op1));
9388 if (! currently_expanding_to_rtl)
9390 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9394 rtx lab = gen_label_rtx ();
9395 prepare_scc_operands (EQ);
9396 emit_jump_insn (gen_branch_true (lab));
9397 prepare_scc_operands (GT);
9399 emit_insn (gen_movt (operands[0]));
9402 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9405 operands[1] = prepare_scc_operands (GE);
9408 (define_expand "sgtu"
9409 [(set (match_operand:SI 0 "arith_reg_operand" "")
9416 if (GET_MODE (operands[0]) != DImode)
9417 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9418 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9419 if (sh_compare_op1 != const0_rtx)
9420 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9421 ? GET_MODE (sh_compare_op0)
9422 : GET_MODE (sh_compare_op1),
9425 emit_insn (gen_cmpgtudi_media (operands[0],
9426 sh_compare_op0, sh_compare_op1));
9429 if (! currently_expanding_to_rtl)
9431 operands[1] = prepare_scc_operands (GTU);
9434 (define_expand "sltu"
9435 [(set (match_operand:SI 0 "arith_reg_operand" "")
9442 if (GET_MODE (operands[0]) != DImode)
9443 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9444 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9445 if (sh_compare_op1 != const0_rtx)
9446 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9447 ? GET_MODE (sh_compare_op0)
9448 : GET_MODE (sh_compare_op1),
9451 emit_insn (gen_cmpgtudi_media (operands[0],
9452 sh_compare_op1, sh_compare_op0));
9455 if (! currently_expanding_to_rtl)
9457 operands[1] = prepare_scc_operands (LTU);
9460 (define_expand "sleu"
9461 [(set (match_operand:SI 0 "arith_reg_operand" "")
9470 if (GET_MODE (operands[0]) != DImode)
9471 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9472 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9473 if (sh_compare_op1 != const0_rtx)
9474 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9475 ? GET_MODE (sh_compare_op0)
9476 : GET_MODE (sh_compare_op1),
9479 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9481 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9482 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9486 if (! currently_expanding_to_rtl)
9488 operands[1] = prepare_scc_operands (LEU);
9491 (define_expand "sgeu"
9492 [(set (match_operand:SI 0 "arith_reg_operand" "")
9501 if (GET_MODE (operands[0]) != DImode)
9502 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9503 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9504 if (sh_compare_op1 != const0_rtx)
9505 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9506 ? GET_MODE (sh_compare_op0)
9507 : GET_MODE (sh_compare_op1),
9510 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9512 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9513 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9518 if (! currently_expanding_to_rtl)
9520 operands[1] = prepare_scc_operands (GEU);
9523 ;; sne moves the complement of the T reg to DEST like this:
9527 ;; This is better than xoring compare result with 1 because it does
9528 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9531 (define_expand "sne"
9532 [(set (match_dup 2) (const_int -1))
9533 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9534 (neg:SI (plus:SI (match_dup 1)
9537 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9546 if (GET_MODE (operands[0]) != DImode)
9547 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9549 if (! TARGET_SHMEDIA_FPU
9550 && GET_MODE (sh_compare_op0) != DImode
9551 && GET_MODE (sh_compare_op0) != SImode)
9554 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9555 if (sh_compare_op1 != const0_rtx)
9556 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9557 ? GET_MODE (sh_compare_op0)
9558 : GET_MODE (sh_compare_op1),
9561 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9563 emit_insn (gen_seq (tmp));
9564 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9569 if (sh_expand_t_scc (NE, operands[0]))
9571 if (! currently_expanding_to_rtl)
9573 operands[1] = prepare_scc_operands (EQ);
9574 operands[2] = gen_reg_rtx (SImode);
9577 (define_expand "sunordered"
9578 [(set (match_operand:DI 0 "arith_reg_operand" "")
9579 (unordered:DI (match_dup 1) (match_dup 2)))]
9580 "TARGET_SHMEDIA_FPU"
9583 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9584 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9587 ;; Use the same trick for FP sle / sge
9589 ;; Apart from the constant use and the T setting, this is like movt,
9590 ;; except that it uses the logically negated value of T, i.e.
9591 ;; operand[0] := T ? 0 : 1.
9592 (define_expand "movnegt"
9593 [(set (match_dup 2) (const_int -1))
9594 (parallel [(set (match_operand 0 "" "")
9595 (neg:SI (plus:SI (match_dup 1)
9598 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9601 "operands[2] = gen_reg_rtx (SImode);")
9603 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9604 ;; This prevents a regression that occurred when we switched from xor to
9608 [(set (match_operand:SI 0 "arith_reg_dest" "")
9609 (plus:SI (reg:SI T_REG)
9612 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9613 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9616 ;; -------------------------------------------------------------------------
9617 ;; Instructions to cope with inline literal tables
9618 ;; -------------------------------------------------------------------------
9620 ; 2 byte integer in line
9622 (define_insn "consttable_2"
9623 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9624 (match_operand 1 "" "")]
9629 if (operands[1] != const0_rtx)
9630 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9633 [(set_attr "length" "2")
9634 (set_attr "in_delay_slot" "no")])
9636 ; 4 byte integer in line
9638 (define_insn "consttable_4"
9639 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9640 (match_operand 1 "" "")]
9645 if (operands[1] != const0_rtx)
9646 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9649 [(set_attr "length" "4")
9650 (set_attr "in_delay_slot" "no")])
9652 ; 8 byte integer in line
9654 (define_insn "consttable_8"
9655 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9656 (match_operand 1 "" "")]
9661 if (operands[1] != const0_rtx)
9662 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9665 [(set_attr "length" "8")
9666 (set_attr "in_delay_slot" "no")])
9668 ; 4 byte floating point
9670 (define_insn "consttable_sf"
9671 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9672 (match_operand 1 "" "")]
9677 if (operands[1] != const0_rtx)
9680 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9681 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9685 [(set_attr "length" "4")
9686 (set_attr "in_delay_slot" "no")])
9688 ; 8 byte floating point
9690 (define_insn "consttable_df"
9691 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9692 (match_operand 1 "" "")]
9697 if (operands[1] != const0_rtx)
9700 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9701 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9705 [(set_attr "length" "8")
9706 (set_attr "in_delay_slot" "no")])
9708 ;; Alignment is needed for some constant tables; it may also be added for
9709 ;; Instructions at the start of loops, or after unconditional branches.
9710 ;; ??? We would get more accurate lengths if we did instruction
9711 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9712 ;; here is too conservative.
9714 ; align to a two byte boundary
9716 (define_expand "align_2"
9717 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9721 ; align to a four byte boundary
9722 ;; align_4 and align_log are instructions for the starts of loops, or
9723 ;; after unconditional branches, which may take up extra room.
9725 (define_expand "align_4"
9726 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9730 ; align to a cache line boundary
9732 (define_insn "align_log"
9733 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9736 [(set_attr "length" "0")
9737 (set_attr "in_delay_slot" "no")])
9739 ; emitted at the end of the literal table, used to emit the
9740 ; 32bit branch labels if needed.
9742 (define_insn "consttable_end"
9743 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9745 "* return output_jump_label_table ();"
9746 [(set_attr "in_delay_slot" "no")])
9748 ; emitted at the end of the window in the literal table.
9750 (define_insn "consttable_window_end"
9751 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9754 [(set_attr "length" "0")
9755 (set_attr "in_delay_slot" "no")])
9757 ;; -------------------------------------------------------------------------
9759 ;; -------------------------------------------------------------------------
9761 ;; String/block move insn.
9763 (define_expand "movmemsi"
9764 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9765 (mem:BLK (match_operand:BLK 1 "" "")))
9766 (use (match_operand:SI 2 "nonmemory_operand" ""))
9767 (use (match_operand:SI 3 "immediate_operand" ""))
9768 (clobber (reg:SI PR_REG))
9769 (clobber (reg:SI R4_REG))
9770 (clobber (reg:SI R5_REG))
9771 (clobber (reg:SI R0_REG))])]
9772 "TARGET_SH1 && ! TARGET_SH5"
9775 if(expand_block_move (operands))
9780 (define_insn "block_move_real"
9781 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9782 (mem:BLK (reg:SI R5_REG)))
9783 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9784 (clobber (reg:SI PR_REG))
9785 (clobber (reg:SI R0_REG))])]
9786 "TARGET_SH1 && ! TARGET_HARD_SH4"
9788 [(set_attr "type" "sfunc")
9789 (set_attr "needs_delay_slot" "yes")])
9791 (define_insn "block_lump_real"
9792 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9793 (mem:BLK (reg:SI R5_REG)))
9794 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9795 (use (reg:SI R6_REG))
9796 (clobber (reg:SI PR_REG))
9797 (clobber (reg:SI T_REG))
9798 (clobber (reg:SI R4_REG))
9799 (clobber (reg:SI R5_REG))
9800 (clobber (reg:SI R6_REG))
9801 (clobber (reg:SI R0_REG))])]
9802 "TARGET_SH1 && ! TARGET_HARD_SH4"
9804 [(set_attr "type" "sfunc")
9805 (set_attr "needs_delay_slot" "yes")])
9807 (define_insn "block_move_real_i4"
9808 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9809 (mem:BLK (reg:SI R5_REG)))
9810 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9811 (clobber (reg:SI PR_REG))
9812 (clobber (reg:SI R0_REG))
9813 (clobber (reg:SI R1_REG))
9814 (clobber (reg:SI R2_REG))])]
9817 [(set_attr "type" "sfunc")
9818 (set_attr "needs_delay_slot" "yes")])
9820 (define_insn "block_lump_real_i4"
9821 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9822 (mem:BLK (reg:SI R5_REG)))
9823 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9824 (use (reg:SI R6_REG))
9825 (clobber (reg:SI PR_REG))
9826 (clobber (reg:SI T_REG))
9827 (clobber (reg:SI R4_REG))
9828 (clobber (reg:SI R5_REG))
9829 (clobber (reg:SI R6_REG))
9830 (clobber (reg:SI R0_REG))
9831 (clobber (reg:SI R1_REG))
9832 (clobber (reg:SI R2_REG))
9833 (clobber (reg:SI R3_REG))])]
9836 [(set_attr "type" "sfunc")
9837 (set_attr "needs_delay_slot" "yes")])
9839 ;; -------------------------------------------------------------------------
9840 ;; Floating point instructions.
9841 ;; -------------------------------------------------------------------------
9843 ;; ??? All patterns should have a type attribute.
9845 (define_expand "movpsi"
9846 [(set (match_operand:PSI 0 "register_operand" "")
9847 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9848 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9851 ;; The c / m alternative is a fake to guide reload to load directly into
9852 ;; fpscr, since reload doesn't know how to use post-increment.
9853 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9854 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9855 ;; predicate after reload.
9856 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9857 ;; like a mac -> gpr move.
9858 (define_insn "fpu_switch"
9859 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9860 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9862 && (! reload_completed
9863 || true_regnum (operands[0]) != FPSCR_REG
9864 || GET_CODE (operands[1]) != MEM
9865 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9867 ! precision stays the same
9876 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9877 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9880 [(set (reg:PSI FPSCR_REG)
9881 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9882 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9885 rtx fpscr, mem, new_insn;
9887 fpscr = SET_DEST (PATTERN (curr_insn));
9888 mem = SET_SRC (PATTERN (curr_insn));
9889 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9891 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9892 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9897 [(set (reg:PSI FPSCR_REG)
9898 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9899 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9900 && (flag_peephole2 ? flow2_completed : reload_completed)"
9903 rtx fpscr, mem, new_insn;
9905 fpscr = SET_DEST (PATTERN (curr_insn));
9906 mem = SET_SRC (PATTERN (curr_insn));
9907 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9909 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9910 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9912 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9913 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9917 ;; ??? This uses the fp unit, but has no type indicating that.
9918 ;; If we did that, this would either give a bogus latency or introduce
9919 ;; a bogus FIFO constraint.
9920 ;; Since this insn is currently only used for prologues/epilogues,
9921 ;; it is probably best to claim no function unit, which matches the
9923 (define_insn "toggle_sz"
9924 [(set (reg:PSI FPSCR_REG)
9925 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9926 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9928 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9930 ;; There's no way we can use it today, since optimize mode switching
9931 ;; doesn't enable us to know from which mode we're switching to the
9932 ;; mode it requests, to tell whether we can use a relative mode switch
9933 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9935 (define_insn "toggle_pr"
9936 [(set (reg:PSI FPSCR_REG)
9937 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9938 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9940 [(set_attr "type" "fp")])
9942 (define_expand "addsf3"
9943 [(set (match_operand:SF 0 "arith_reg_operand" "")
9944 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9945 (match_operand:SF 2 "arith_reg_operand" "")))]
9946 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9951 expand_sf_binop (&gen_addsf3_i, operands);
9956 (define_insn "*addsf3_media"
9957 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9958 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9959 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9960 "TARGET_SHMEDIA_FPU"
9962 [(set_attr "type" "fparith_media")])
9964 (define_insn_and_split "unary_sf_op"
9965 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9970 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9971 (match_operator:SF 2 "unary_float_operator"
9972 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9973 (parallel [(match_operand 4
9974 "const_int_operand" "n")]))]))
9975 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9976 "TARGET_SHMEDIA_FPU"
9978 "TARGET_SHMEDIA_FPU && reload_completed"
9979 [(set (match_dup 5) (match_dup 6))]
9982 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9983 rtx op1 = gen_rtx_REG (SFmode,
9984 (true_regnum (operands[1])
9985 + (INTVAL (operands[4]) ^ endian)));
9987 operands[7] = gen_rtx_REG (SFmode,
9988 (true_regnum (operands[0])
9989 + (INTVAL (operands[3]) ^ endian)));
9990 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9992 [(set_attr "type" "fparith_media")])
9994 (define_insn_and_split "binary_sf_op"
9995 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10000 (parallel [(match_operand 7 "const_int_operand" "n")]))
10001 (match_operator:SF 3 "binary_float_operator"
10002 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10003 (parallel [(match_operand 5
10004 "const_int_operand" "n")]))
10005 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10006 (parallel [(match_operand 6
10007 "const_int_operand" "n")]))]))
10008 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10009 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10011 "&& reload_completed"
10012 [(set (match_dup 8) (match_dup 9))]
10015 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10016 rtx op1 = gen_rtx_REG (SFmode,
10017 (true_regnum (operands[1])
10018 + (INTVAL (operands[5]) ^ endian)));
10019 rtx op2 = gen_rtx_REG (SFmode,
10020 (true_regnum (operands[2])
10021 + (INTVAL (operands[6]) ^ endian)));
10023 operands[8] = gen_rtx_REG (SFmode,
10024 (true_regnum (operands[0])
10025 + (INTVAL (operands[4]) ^ endian)));
10026 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10028 [(set_attr "type" "fparith_media")])
10030 (define_insn "addsf3_i"
10031 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10032 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10033 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10034 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10037 [(set_attr "type" "fp")
10038 (set_attr "fp_mode" "single")])
10040 (define_expand "subsf3"
10041 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10042 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10043 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10044 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10049 expand_sf_binop (&gen_subsf3_i, operands);
10054 (define_insn "*subsf3_media"
10055 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10056 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10057 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10058 "TARGET_SHMEDIA_FPU"
10059 "fsub.s %1, %2, %0"
10060 [(set_attr "type" "fparith_media")])
10062 (define_insn "subsf3_i"
10063 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10064 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10065 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10066 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10069 [(set_attr "type" "fp")
10070 (set_attr "fp_mode" "single")])
10072 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10073 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
10074 ;; mixed-precision SH4 targets. To allow it to be still generated for the
10075 ;; SH3E, we use a separate insn for SH3E mulsf3.
10077 (define_expand "mulsf3"
10078 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10079 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10080 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10081 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10084 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10085 expand_sf_binop (&gen_mulsf3_i4, operands);
10086 else if (TARGET_SH2E)
10087 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10088 if (! TARGET_SHMEDIA)
10092 (define_insn "*mulsf3_media"
10093 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10094 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10095 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10096 "TARGET_SHMEDIA_FPU"
10097 "fmul.s %1, %2, %0"
10098 [(set_attr "type" "fparith_media")])
10100 (define_insn "mulsf3_i4"
10101 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10102 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10103 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10104 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10107 [(set_attr "type" "fp")
10108 (set_attr "fp_mode" "single")])
10110 (define_insn "mulsf3_ie"
10111 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10112 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10113 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10114 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10116 [(set_attr "type" "fp")])
10118 (define_insn "mac_media"
10119 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10120 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10121 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10122 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10123 "TARGET_SHMEDIA_FPU"
10124 "fmac.s %1, %2, %0"
10125 [(set_attr "type" "fparith_media")])
10127 (define_insn "*macsf3"
10128 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10129 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10130 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10131 (match_operand:SF 3 "arith_reg_operand" "0")))
10132 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10133 "TARGET_SH2E && ! TARGET_SH4"
10135 [(set_attr "type" "fp")
10136 (set_attr "fp_mode" "single")])
10138 (define_expand "divsf3"
10139 [(set (match_operand:SF 0 "arith_reg_operand" "")
10140 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10141 (match_operand:SF 2 "arith_reg_operand" "")))]
10142 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10147 expand_sf_binop (&gen_divsf3_i, operands);
10152 (define_insn "*divsf3_media"
10153 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10154 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10155 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10156 "TARGET_SHMEDIA_FPU"
10157 "fdiv.s %1, %2, %0"
10158 [(set_attr "type" "fdiv_media")])
10160 (define_insn "divsf3_i"
10161 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10162 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10163 (match_operand:SF 2 "arith_reg_operand" "f")))
10164 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10167 [(set_attr "type" "fdiv")
10168 (set_attr "fp_mode" "single")])
10170 (define_insn "floatdisf2"
10171 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10172 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10173 "TARGET_SHMEDIA_FPU"
10175 [(set_attr "type" "fpconv_media")])
10177 (define_expand "floatsisf2"
10178 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10179 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10180 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10183 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10185 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10190 (define_insn "*floatsisf2_media"
10191 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10192 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10193 "TARGET_SHMEDIA_FPU"
10195 [(set_attr "type" "fpconv_media")])
10197 (define_insn "floatsisf2_i4"
10198 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10199 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10200 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10201 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10203 [(set_attr "type" "fp")
10204 (set_attr "fp_mode" "single")])
10206 (define_insn "*floatsisf2_ie"
10207 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10208 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10209 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10211 [(set_attr "type" "fp")])
10213 (define_insn "fix_truncsfdi2"
10214 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10215 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10216 "TARGET_SHMEDIA_FPU"
10218 [(set_attr "type" "fpconv_media")])
10220 (define_expand "fix_truncsfsi2"
10221 [(set (match_operand:SI 0 "fpul_operand" "=y")
10222 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10223 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10226 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10228 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10233 (define_insn "*fix_truncsfsi2_media"
10234 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10235 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10236 "TARGET_SHMEDIA_FPU"
10238 [(set_attr "type" "fpconv_media")])
10240 (define_insn "fix_truncsfsi2_i4"
10241 [(set (match_operand:SI 0 "fpul_operand" "=y")
10242 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10243 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10244 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10246 [(set_attr "type" "ftrc_s")
10247 (set_attr "fp_mode" "single")])
10249 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10250 ;; fix_truncsfsi2_i4.
10251 ;; (define_insn "fix_truncsfsi2_i4_2"
10252 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10253 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10254 ;; (use (reg:PSI FPSCR_REG))
10255 ;; (clobber (reg:SI FPUL_REG))]
10258 ;; [(set_attr "length" "4")
10259 ;; (set_attr "fp_mode" "single")])
10262 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10263 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10264 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10265 ;; (clobber (reg:SI FPUL_REG))]
10267 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10268 ;; (use (match_dup 2))])
10269 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10271 (define_insn "*fixsfsi"
10272 [(set (match_operand:SI 0 "fpul_operand" "=y")
10273 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10274 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10276 [(set_attr "type" "fp")])
10278 (define_insn "cmpgtsf_t"
10279 [(set (reg:SI T_REG)
10280 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10281 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10282 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10284 [(set_attr "type" "fp")
10285 (set_attr "fp_mode" "single")])
10287 (define_insn "cmpeqsf_t"
10288 [(set (reg:SI T_REG)
10289 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10290 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10291 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10293 [(set_attr "type" "fp")
10294 (set_attr "fp_mode" "single")])
10296 (define_insn "ieee_ccmpeqsf_t"
10297 [(set (reg:SI T_REG)
10298 (ior:SI (reg:SI T_REG)
10299 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10300 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10301 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10302 "* return output_ieee_ccmpeq (insn, operands);"
10303 [(set_attr "length" "4")])
10306 (define_insn "cmpgtsf_t_i4"
10307 [(set (reg:SI T_REG)
10308 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10309 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10310 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10311 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10313 [(set_attr "type" "fp")
10314 (set_attr "fp_mode" "single")])
10316 (define_insn "cmpeqsf_t_i4"
10317 [(set (reg:SI T_REG)
10318 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10319 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10320 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10321 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10323 [(set_attr "type" "fp")
10324 (set_attr "fp_mode" "single")])
10326 (define_insn "*ieee_ccmpeqsf_t_4"
10327 [(set (reg:SI T_REG)
10328 (ior:SI (reg:SI T_REG)
10329 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10330 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10331 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10332 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10333 "* return output_ieee_ccmpeq (insn, operands);"
10334 [(set_attr "length" "4")
10335 (set_attr "fp_mode" "single")])
10337 (define_insn "cmpeqsf_media"
10338 [(set (match_operand:DI 0 "register_operand" "=r")
10339 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10340 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10341 "TARGET_SHMEDIA_FPU"
10342 "fcmpeq.s %1, %2, %0"
10343 [(set_attr "type" "fcmp_media")])
10345 (define_insn "cmpsieqsf_media"
10346 [(set (match_operand:SI 0 "register_operand" "=r")
10347 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10348 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10349 "TARGET_SHMEDIA_FPU"
10350 "fcmpeq.s %1, %2, %0"
10351 [(set_attr "type" "fcmp_media")])
10353 (define_insn "cmpgtsf_media"
10354 [(set (match_operand:DI 0 "register_operand" "=r")
10355 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10356 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10357 "TARGET_SHMEDIA_FPU"
10358 "fcmpgt.s %1, %2, %0"
10359 [(set_attr "type" "fcmp_media")])
10361 (define_insn "cmpgesf_media"
10362 [(set (match_operand:DI 0 "register_operand" "=r")
10363 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10364 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10365 "TARGET_SHMEDIA_FPU"
10366 "fcmpge.s %1, %2, %0"
10367 [(set_attr "type" "fcmp_media")])
10369 (define_insn "cmpunsf_media"
10370 [(set (match_operand:DI 0 "register_operand" "=r")
10371 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10372 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10373 "TARGET_SHMEDIA_FPU"
10374 "fcmpun.s %1, %2, %0"
10375 [(set_attr "type" "fcmp_media")])
10377 (define_expand "cmpsf"
10378 [(set (reg:SI T_REG)
10379 (compare (match_operand:SF 0 "arith_operand" "")
10380 (match_operand:SF 1 "arith_operand" "")))]
10381 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10384 sh_compare_op0 = operands[0];
10385 sh_compare_op1 = operands[1];
10389 (define_expand "negsf2"
10390 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10391 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10392 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10397 expand_sf_unop (&gen_negsf2_i, operands);
10402 (define_insn "*negsf2_media"
10403 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10404 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10405 "TARGET_SHMEDIA_FPU"
10407 [(set_attr "type" "fmove_media")])
10409 (define_insn "negsf2_i"
10410 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10411 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10412 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10415 [(set_attr "type" "fmove")
10416 (set_attr "fp_mode" "single")])
10418 (define_expand "sqrtsf2"
10419 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10420 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10421 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10426 expand_sf_unop (&gen_sqrtsf2_i, operands);
10431 (define_insn "*sqrtsf2_media"
10432 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10433 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10434 "TARGET_SHMEDIA_FPU"
10436 [(set_attr "type" "fdiv_media")])
10438 (define_insn "sqrtsf2_i"
10439 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10440 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10441 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10444 [(set_attr "type" "fdiv")
10445 (set_attr "fp_mode" "single")])
10447 (define_insn "rsqrtsf2"
10448 [(set (match_operand:SF 0 "register_operand" "=f")
10449 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10450 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10451 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10452 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10453 && operands[1] == CONST1_RTX (SFmode)"
10455 [(set_attr "type" "fsrra")
10456 (set_attr "fp_mode" "single")])
10458 (define_insn "fsca"
10459 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10461 (unspec:SF [(mult:SF
10462 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10463 (match_operand:SF 2 "immediate_operand" "i"))
10465 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10467 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10468 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10469 && operands[2] == sh_fsca_int2sf ()"
10471 [(set_attr "type" "fsca")
10472 (set_attr "fp_mode" "single")])
10474 (define_expand "sinsf2"
10475 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10476 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10478 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10481 rtx scaled = gen_reg_rtx (SFmode);
10482 rtx truncated = gen_reg_rtx (SImode);
10483 rtx fsca = gen_reg_rtx (V2SFmode);
10484 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10486 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10487 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10488 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10489 get_fpscr_rtx ()));
10490 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10494 (define_expand "cossf2"
10495 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10496 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10498 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10501 rtx scaled = gen_reg_rtx (SFmode);
10502 rtx truncated = gen_reg_rtx (SImode);
10503 rtx fsca = gen_reg_rtx (V2SFmode);
10504 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10506 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10507 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10508 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10509 get_fpscr_rtx ()));
10510 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10514 (define_expand "sindf2"
10515 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10516 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10518 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10521 rtx scaled = gen_reg_rtx (DFmode);
10522 rtx truncated = gen_reg_rtx (SImode);
10523 rtx fsca = gen_reg_rtx (V2SFmode);
10524 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10525 rtx sfresult = gen_reg_rtx (SFmode);
10527 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10528 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10529 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10530 get_fpscr_rtx ()));
10531 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10532 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10536 (define_expand "cosdf2"
10537 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10538 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10540 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10543 rtx scaled = gen_reg_rtx (DFmode);
10544 rtx truncated = gen_reg_rtx (SImode);
10545 rtx fsca = gen_reg_rtx (V2SFmode);
10546 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10547 rtx sfresult = gen_reg_rtx (SFmode);
10549 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10550 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10551 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10552 get_fpscr_rtx ()));
10553 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10554 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10558 (define_expand "abssf2"
10559 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10560 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10561 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10566 expand_sf_unop (&gen_abssf2_i, operands);
10571 (define_insn "*abssf2_media"
10572 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10573 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10574 "TARGET_SHMEDIA_FPU"
10576 [(set_attr "type" "fmove_media")])
10578 (define_insn "abssf2_i"
10579 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10580 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10581 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10584 [(set_attr "type" "fmove")
10585 (set_attr "fp_mode" "single")])
10587 (define_expand "adddf3"
10588 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10589 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10590 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10591 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10594 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10596 expand_df_binop (&gen_adddf3_i, operands);
10601 (define_insn "*adddf3_media"
10602 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10603 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10604 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10605 "TARGET_SHMEDIA_FPU"
10606 "fadd.d %1, %2, %0"
10607 [(set_attr "type" "dfparith_media")])
10609 (define_insn "adddf3_i"
10610 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10611 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10612 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10613 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10614 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10616 [(set_attr "type" "dfp_arith")
10617 (set_attr "fp_mode" "double")])
10619 (define_expand "subdf3"
10620 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10621 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10622 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10623 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10626 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10628 expand_df_binop (&gen_subdf3_i, operands);
10633 (define_insn "*subdf3_media"
10634 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10635 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10636 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10637 "TARGET_SHMEDIA_FPU"
10638 "fsub.d %1, %2, %0"
10639 [(set_attr "type" "dfparith_media")])
10641 (define_insn "subdf3_i"
10642 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10643 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10644 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10645 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10646 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10648 [(set_attr "type" "dfp_arith")
10649 (set_attr "fp_mode" "double")])
10651 (define_expand "muldf3"
10652 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10653 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10654 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10655 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10658 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10660 expand_df_binop (&gen_muldf3_i, operands);
10665 (define_insn "*muldf3_media"
10666 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10667 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10668 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10669 "TARGET_SHMEDIA_FPU"
10670 "fmul.d %1, %2, %0"
10671 [(set_attr "type" "dfmul_media")])
10673 (define_insn "muldf3_i"
10674 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10675 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10676 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10677 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10678 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10680 [(set_attr "type" "dfp_arith")
10681 (set_attr "fp_mode" "double")])
10683 (define_expand "divdf3"
10684 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10685 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10686 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10687 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10690 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10692 expand_df_binop (&gen_divdf3_i, operands);
10697 (define_insn "*divdf3_media"
10698 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10699 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10700 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10701 "TARGET_SHMEDIA_FPU"
10702 "fdiv.d %1, %2, %0"
10703 [(set_attr "type" "dfdiv_media")])
10705 (define_insn "divdf3_i"
10706 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10707 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10708 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10709 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10710 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10712 [(set_attr "type" "dfdiv")
10713 (set_attr "fp_mode" "double")])
10715 (define_insn "floatdidf2"
10716 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10717 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10718 "TARGET_SHMEDIA_FPU"
10720 [(set_attr "type" "dfpconv_media")])
10722 (define_expand "floatsidf2"
10723 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10724 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10725 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10728 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10730 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10731 get_fpscr_rtx ()));
10736 (define_insn "*floatsidf2_media"
10737 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10738 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10739 "TARGET_SHMEDIA_FPU"
10741 [(set_attr "type" "dfpconv_media")])
10743 (define_insn "floatsidf2_i"
10744 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10745 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10746 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10747 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10749 [(set_attr "type" "dfp_conv")
10750 (set_attr "fp_mode" "double")])
10752 (define_insn "fix_truncdfdi2"
10753 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10754 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10755 "TARGET_SHMEDIA_FPU"
10757 [(set_attr "type" "dfpconv_media")])
10759 (define_expand "fix_truncdfsi2"
10760 [(set (match_operand:SI 0 "fpul_operand" "")
10761 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10762 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10765 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10767 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10768 get_fpscr_rtx ()));
10773 (define_insn "*fix_truncdfsi2_media"
10774 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10775 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10776 "TARGET_SHMEDIA_FPU"
10778 [(set_attr "type" "dfpconv_media")])
10780 (define_insn "fix_truncdfsi2_i"
10781 [(set (match_operand:SI 0 "fpul_operand" "=y")
10782 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10783 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10784 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10786 [(set_attr "type" "dfp_conv")
10787 (set_attr "dfp_comp" "no")
10788 (set_attr "fp_mode" "double")])
10790 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10791 ;; fix_truncdfsi2_i.
10792 ;; (define_insn "fix_truncdfsi2_i4"
10793 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10794 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10795 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10796 ;; (clobber (reg:SI FPUL_REG))]
10799 ;; [(set_attr "length" "4")
10800 ;; (set_attr "fp_mode" "double")])
10803 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10804 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10805 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10806 ;; (clobber (reg:SI FPUL_REG))]
10808 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10809 ;; (use (match_dup 2))])
10810 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10812 (define_insn "cmpgtdf_t"
10813 [(set (reg:SI T_REG)
10814 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10815 (match_operand:DF 1 "arith_reg_operand" "f")))
10816 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10817 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10819 [(set_attr "type" "dfp_cmp")
10820 (set_attr "fp_mode" "double")])
10822 (define_insn "cmpeqdf_t"
10823 [(set (reg:SI T_REG)
10824 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10825 (match_operand:DF 1 "arith_reg_operand" "f")))
10826 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10827 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10829 [(set_attr "type" "dfp_cmp")
10830 (set_attr "fp_mode" "double")])
10832 (define_insn "*ieee_ccmpeqdf_t"
10833 [(set (reg:SI T_REG)
10834 (ior:SI (reg:SI T_REG)
10835 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10836 (match_operand:DF 1 "arith_reg_operand" "f"))))
10837 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10838 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10839 "* return output_ieee_ccmpeq (insn, operands);"
10840 [(set_attr "length" "4")
10841 (set_attr "fp_mode" "double")])
10843 (define_insn "cmpeqdf_media"
10844 [(set (match_operand:DI 0 "register_operand" "=r")
10845 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10846 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10847 "TARGET_SHMEDIA_FPU"
10848 "fcmpeq.d %1,%2,%0"
10849 [(set_attr "type" "fcmp_media")])
10851 (define_insn "cmpsieqdf_media"
10852 [(set (match_operand:SI 0 "register_operand" "=r")
10853 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10854 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10855 "TARGET_SHMEDIA_FPU"
10856 "fcmpeq.d %1,%2,%0"
10857 [(set_attr "type" "fcmp_media")])
10859 (define_insn "cmpgtdf_media"
10860 [(set (match_operand:DI 0 "register_operand" "=r")
10861 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10862 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10863 "TARGET_SHMEDIA_FPU"
10864 "fcmpgt.d %1,%2,%0"
10865 [(set_attr "type" "fcmp_media")])
10867 (define_insn "cmpgedf_media"
10868 [(set (match_operand:DI 0 "register_operand" "=r")
10869 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10870 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10871 "TARGET_SHMEDIA_FPU"
10872 "fcmpge.d %1,%2,%0"
10873 [(set_attr "type" "fcmp_media")])
10875 (define_insn "cmpundf_media"
10876 [(set (match_operand:DI 0 "register_operand" "=r")
10877 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10878 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10879 "TARGET_SHMEDIA_FPU"
10880 "fcmpun.d %1,%2,%0"
10881 [(set_attr "type" "fcmp_media")])
10883 (define_expand "cmpdf"
10884 [(set (reg:SI T_REG)
10885 (compare (match_operand:DF 0 "arith_operand" "")
10886 (match_operand:DF 1 "arith_operand" "")))]
10887 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10890 sh_compare_op0 = operands[0];
10891 sh_compare_op1 = operands[1];
10895 (define_expand "negdf2"
10896 [(set (match_operand:DF 0 "arith_reg_operand" "")
10897 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10898 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10901 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10903 expand_df_unop (&gen_negdf2_i, operands);
10908 (define_insn "*negdf2_media"
10909 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10910 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10911 "TARGET_SHMEDIA_FPU"
10913 [(set_attr "type" "fmove_media")])
10915 (define_insn "negdf2_i"
10916 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10917 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10918 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10919 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10921 [(set_attr "type" "fmove")
10922 (set_attr "fp_mode" "double")])
10924 (define_expand "sqrtdf2"
10925 [(set (match_operand:DF 0 "arith_reg_operand" "")
10926 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10927 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10930 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10932 expand_df_unop (&gen_sqrtdf2_i, operands);
10937 (define_insn "*sqrtdf2_media"
10938 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10939 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10940 "TARGET_SHMEDIA_FPU"
10942 [(set_attr "type" "dfdiv_media")])
10944 (define_insn "sqrtdf2_i"
10945 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10946 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10947 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10948 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10950 [(set_attr "type" "dfdiv")
10951 (set_attr "fp_mode" "double")])
10953 (define_expand "absdf2"
10954 [(set (match_operand:DF 0 "arith_reg_operand" "")
10955 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10956 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10959 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10961 expand_df_unop (&gen_absdf2_i, operands);
10966 (define_insn "*absdf2_media"
10967 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10968 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10969 "TARGET_SHMEDIA_FPU"
10971 [(set_attr "type" "fmove_media")])
10973 (define_insn "absdf2_i"
10974 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10975 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10976 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10977 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10979 [(set_attr "type" "fmove")
10980 (set_attr "fp_mode" "double")])
10982 (define_expand "extendsfdf2"
10983 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10984 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10985 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10988 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10990 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10991 get_fpscr_rtx ()));
10996 (define_insn "*extendsfdf2_media"
10997 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10998 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10999 "TARGET_SHMEDIA_FPU"
11001 [(set_attr "type" "dfpconv_media")])
11003 (define_insn "extendsfdf2_i4"
11004 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11005 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11006 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11007 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11009 [(set_attr "type" "fp")
11010 (set_attr "fp_mode" "double")])
11012 (define_expand "truncdfsf2"
11013 [(set (match_operand:SF 0 "fpul_operand" "")
11014 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11015 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11018 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11020 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11021 get_fpscr_rtx ()));
11026 (define_insn "*truncdfsf2_media"
11027 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11028 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11029 "TARGET_SHMEDIA_FPU"
11031 [(set_attr "type" "dfpconv_media")])
11033 (define_insn "truncdfsf2_i4"
11034 [(set (match_operand:SF 0 "fpul_operand" "=y")
11035 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11036 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11037 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11039 [(set_attr "type" "fp")
11040 (set_attr "fp_mode" "double")])
11042 ;; Bit field extract patterns. These give better code for packed bitfields,
11043 ;; because they allow auto-increment addresses to be generated.
11045 (define_expand "insv"
11046 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11047 (match_operand:SI 1 "immediate_operand" "")
11048 (match_operand:SI 2 "immediate_operand" ""))
11049 (match_operand:SI 3 "general_operand" ""))]
11050 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11053 rtx addr_target, orig_address, shift_reg, qi_val;
11054 HOST_WIDE_INT bitsize, size, v = 0;
11055 rtx x = operands[3];
11057 /* ??? expmed doesn't care for non-register predicates. */
11058 if (! memory_operand (operands[0], VOIDmode)
11059 || ! immediate_operand (operands[1], VOIDmode)
11060 || ! immediate_operand (operands[2], VOIDmode)
11061 || ! general_operand (x, VOIDmode))
11063 /* If this isn't a 16 / 24 / 32 bit field, or if
11064 it doesn't start on a byte boundary, then fail. */
11065 bitsize = INTVAL (operands[1]);
11066 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11067 || (INTVAL (operands[2]) % 8) != 0)
11070 size = bitsize / 8;
11071 orig_address = XEXP (operands[0], 0);
11072 shift_reg = gen_reg_rtx (SImode);
11073 if (GET_CODE (x) == CONST_INT)
11076 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11080 emit_insn (gen_movsi (shift_reg, operands[3]));
11081 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11083 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11085 operands[0] = replace_equiv_address (operands[0], addr_target);
11086 emit_insn (gen_movqi (operands[0], qi_val));
11090 if (GET_CODE (x) == CONST_INT)
11092 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11095 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11096 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11098 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11099 emit_insn (gen_movqi (operands[0], qi_val));
11105 (define_insn "movua"
11106 [(set (match_operand:SI 0 "register_operand" "=z")
11107 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11108 (const_int 32) (const_int 0)))]
11111 [(set_attr "type" "movua")])
11113 ;; We shouldn't need this, but cse replaces increments with references
11114 ;; to other regs before flow has a chance to create post_inc
11115 ;; addressing modes, and only postreload's cse_move2add brings the
11116 ;; increments back to a usable form.
11118 [(set (match_operand:SI 0 "register_operand" "")
11119 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11120 (const_int 32) (const_int 0)))
11121 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11122 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11123 [(set (match_operand:SI 0 "register_operand" "")
11124 (sign_extract:SI (mem:SI (post_inc:SI
11125 (match_operand:SI 1 "register_operand" "")))
11126 (const_int 32) (const_int 0)))]
11129 (define_expand "extv"
11130 [(set (match_operand:SI 0 "register_operand" "")
11131 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11132 (match_operand 2 "const_int_operand" "")
11133 (match_operand 3 "const_int_operand" "")))]
11136 if (TARGET_SH4A_ARCH
11137 && INTVAL (operands[2]) == 32
11138 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11139 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11141 emit_insn (gen_movua (operands[0],
11142 adjust_address (operands[1], SImode, 0)));
11149 (define_expand "extzv"
11150 [(set (match_operand:SI 0 "register_operand" "")
11151 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11152 (match_operand 2 "const_int_operand" "")
11153 (match_operand 3 "const_int_operand" "")))]
11156 if (TARGET_SH4A_ARCH
11157 && INTVAL (operands[2]) == 32
11158 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11159 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11161 emit_insn (gen_movua (operands[0],
11162 adjust_address (operands[1], SImode, 0)));
11170 ;; -------------------------------------------------------------------------
11172 ;; -------------------------------------------------------------------------
11174 ;; This matches cases where a stack pointer increment at the start of the
11175 ;; epilogue combines with a stack slot read loading the return value.
11178 [(set (match_operand:SI 0 "arith_reg_operand" "")
11179 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11180 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11181 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11184 ;; See the comment on the dt combiner pattern above.
11187 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11188 (plus:SI (match_dup 0)
11190 (set (reg:SI T_REG)
11191 (eq:SI (match_dup 0)
11196 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11197 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11198 ;; reload when the constant is too large for a reg+offset address.
11200 ;; ??? We would get much better code if this was done in reload. This would
11201 ;; require modifying find_reloads_address to recognize that if the constant
11202 ;; is out-of-range for an immediate add, then we get better code by reloading
11203 ;; the constant into a register than by reloading the sum into a register,
11204 ;; since the former is one instruction shorter if the address does not need
11205 ;; to be offsettable. Unfortunately this does not work, because there is
11206 ;; only one register, r0, that can be used as an index register. This register
11207 ;; is also the function return value register. So, if we try to force reload
11208 ;; to use double-reg addresses, then we end up with some instructions that
11209 ;; need to use r0 twice. The only way to fix this is to change the calling
11210 ;; convention so that r0 is not used to return values.
11213 [(set (match_operand:SI 0 "register_operand" "=r")
11214 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11215 (set (mem:SI (match_dup 0))
11216 (match_operand:SI 2 "general_movsrc_operand" ""))]
11217 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11218 "mov.l %2,@(%0,%1)")
11221 [(set (match_operand:SI 0 "register_operand" "=r")
11222 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11223 (set (match_operand:SI 2 "general_movdst_operand" "")
11224 (mem:SI (match_dup 0)))]
11225 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11226 "mov.l @(%0,%1),%2")
11229 [(set (match_operand:SI 0 "register_operand" "=r")
11230 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11231 (set (mem:HI (match_dup 0))
11232 (match_operand:HI 2 "general_movsrc_operand" ""))]
11233 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11234 "mov.w %2,@(%0,%1)")
11237 [(set (match_operand:SI 0 "register_operand" "=r")
11238 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11239 (set (match_operand:HI 2 "general_movdst_operand" "")
11240 (mem:HI (match_dup 0)))]
11241 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11242 "mov.w @(%0,%1),%2")
11245 [(set (match_operand:SI 0 "register_operand" "=r")
11246 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11247 (set (mem:QI (match_dup 0))
11248 (match_operand:QI 2 "general_movsrc_operand" ""))]
11249 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11250 "mov.b %2,@(%0,%1)")
11253 [(set (match_operand:SI 0 "register_operand" "=r")
11254 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11255 (set (match_operand:QI 2 "general_movdst_operand" "")
11256 (mem:QI (match_dup 0)))]
11257 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11258 "mov.b @(%0,%1),%2")
11261 [(set (match_operand:SI 0 "register_operand" "=r")
11262 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11263 (set (mem:SF (match_dup 0))
11264 (match_operand:SF 2 "general_movsrc_operand" ""))]
11265 "TARGET_SH1 && REGNO (operands[0]) == 0
11266 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11267 || (GET_CODE (operands[2]) == SUBREG
11268 && REGNO (SUBREG_REG (operands[2])) < 16))
11269 && reg_unused_after (operands[0], insn)"
11270 "mov.l %2,@(%0,%1)")
11273 [(set (match_operand:SI 0 "register_operand" "=r")
11274 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11275 (set (match_operand:SF 2 "general_movdst_operand" "")
11277 (mem:SF (match_dup 0)))]
11278 "TARGET_SH1 && REGNO (operands[0]) == 0
11279 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11280 || (GET_CODE (operands[2]) == SUBREG
11281 && REGNO (SUBREG_REG (operands[2])) < 16))
11282 && reg_unused_after (operands[0], insn)"
11283 "mov.l @(%0,%1),%2")
11286 [(set (match_operand:SI 0 "register_operand" "=r")
11287 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11288 (set (mem:SF (match_dup 0))
11289 (match_operand:SF 2 "general_movsrc_operand" ""))]
11290 "TARGET_SH2E && REGNO (operands[0]) == 0
11291 && ((GET_CODE (operands[2]) == REG
11292 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11293 || (GET_CODE (operands[2]) == SUBREG
11294 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11295 && reg_unused_after (operands[0], insn)"
11296 "fmov{.s|} %2,@(%0,%1)")
11299 [(set (match_operand:SI 0 "register_operand" "=r")
11300 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11301 (set (match_operand:SF 2 "general_movdst_operand" "")
11303 (mem:SF (match_dup 0)))]
11304 "TARGET_SH2E && REGNO (operands[0]) == 0
11305 && ((GET_CODE (operands[2]) == REG
11306 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11307 || (GET_CODE (operands[2]) == SUBREG
11308 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11309 && reg_unused_after (operands[0], insn)"
11310 "fmov{.s|} @(%0,%1),%2")
11312 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11313 (define_insn "sp_switch_1"
11314 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11318 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11319 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11320 return \"mov r0,r15\";
11322 [(set_attr "length" "10")])
11324 ;; Switch back to the original stack for interrupt functions with the
11325 ;; sp_switch attribute. */
11326 (define_insn "sp_switch_2"
11329 "mov.l @r15+,r15\;mov.l @r15+,r0"
11330 [(set_attr "length" "4")])
11332 ;; Integer vector moves
11334 (define_expand "movv8qi"
11335 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11336 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11338 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11340 (define_insn "movv8qi_i"
11341 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11342 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11344 && (register_operand (operands[0], V8QImode)
11345 || sh_register_operand (operands[1], V8QImode))"
11352 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11353 (set_attr "length" "4,4,16,4,4")])
11356 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11357 (subreg:V8QI (const_int 0) 0))]
11359 [(set (match_dup 0)
11360 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11361 (const_int 0) (const_int 0) (const_int 0)
11362 (const_int 0) (const_int 0)]))])
11365 [(set (match_operand 0 "arith_reg_dest" "")
11366 (match_operand 1 "sh_rep_vec" ""))]
11367 "TARGET_SHMEDIA && reload_completed
11368 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11369 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11370 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11371 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11372 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11373 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11374 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11375 [(set (match_dup 0) (match_dup 1))
11379 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11380 rtx elt1 = XVECEXP (operands[1], 0, 1);
11383 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11387 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11388 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11390 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11391 operands[1] = XVECEXP (operands[1], 0, 0);
11394 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11396 = GEN_INT (TARGET_LITTLE_ENDIAN
11397 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11398 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11401 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11403 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11409 [(set (match_operand 0 "arith_reg_dest" "")
11410 (match_operand 1 "sh_const_vec" ""))]
11411 "TARGET_SHMEDIA && reload_completed
11412 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11413 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11414 [(set (match_dup 0) (match_dup 1))]
11417 rtx v = operands[1];
11418 enum machine_mode new_mode
11419 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11421 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11423 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11426 (define_expand "movv2hi"
11427 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11428 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11430 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11432 (define_insn "movv2hi_i"
11433 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11434 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11436 && (register_operand (operands[0], V2HImode)
11437 || sh_register_operand (operands[1], V2HImode))"
11444 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11445 (set_attr "length" "4,4,16,4,4")
11446 (set (attr "highpart")
11447 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11448 (const_string "user")]
11449 (const_string "ignore")))])
11451 (define_expand "movv4hi"
11452 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11453 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11455 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11457 (define_insn "movv4hi_i"
11458 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11459 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11461 && (register_operand (operands[0], V4HImode)
11462 || sh_register_operand (operands[1], V4HImode))"
11469 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11470 (set_attr "length" "4,4,16,4,4")
11471 (set_attr "highpart" "depend")])
11473 (define_expand "movv2si"
11474 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11475 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11477 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11479 (define_insn "movv2si_i"
11480 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11481 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11483 && (register_operand (operands[0], V2SImode)
11484 || sh_register_operand (operands[1], V2SImode))"
11491 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11492 (set_attr "length" "4,4,16,4,4")
11493 (set_attr "highpart" "depend")])
11495 ;; Multimedia Intrinsics
11497 (define_insn "absv2si2"
11498 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11499 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11502 [(set_attr "type" "mcmp_media")
11503 (set_attr "highpart" "depend")])
11505 (define_insn "absv4hi2"
11506 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11507 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11510 [(set_attr "type" "mcmp_media")
11511 (set_attr "highpart" "depend")])
11513 (define_insn "addv2si3"
11514 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11515 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11516 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11518 "madd.l %1, %2, %0"
11519 [(set_attr "type" "arith_media")
11520 (set_attr "highpart" "depend")])
11522 (define_insn "addv4hi3"
11523 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11524 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11525 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11527 "madd.w %1, %2, %0"
11528 [(set_attr "type" "arith_media")
11529 (set_attr "highpart" "depend")])
11531 (define_insn_and_split "addv2hi3"
11532 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11533 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11534 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11541 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11542 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11543 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11544 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11545 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11547 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11548 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11551 [(set_attr "highpart" "must_split")])
11553 (define_insn "ssaddv2si3"
11554 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11555 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11556 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11558 "madds.l %1, %2, %0"
11559 [(set_attr "type" "mcmp_media")
11560 (set_attr "highpart" "depend")])
11562 (define_insn "usaddv8qi3"
11563 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11564 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11565 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11567 "madds.ub %1, %2, %0"
11568 [(set_attr "type" "mcmp_media")
11569 (set_attr "highpart" "depend")])
11571 (define_insn "ssaddv4hi3"
11572 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11573 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11574 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11576 "madds.w %1, %2, %0"
11577 [(set_attr "type" "mcmp_media")
11578 (set_attr "highpart" "depend")])
11580 (define_insn "negcmpeqv8qi"
11581 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11582 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11583 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11585 "mcmpeq.b %N1, %N2, %0"
11586 [(set_attr "type" "mcmp_media")
11587 (set_attr "highpart" "depend")])
11589 (define_insn "negcmpeqv2si"
11590 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11591 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11592 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11594 "mcmpeq.l %N1, %N2, %0"
11595 [(set_attr "type" "mcmp_media")
11596 (set_attr "highpart" "depend")])
11598 (define_insn "negcmpeqv4hi"
11599 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11600 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11601 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11603 "mcmpeq.w %N1, %N2, %0"
11604 [(set_attr "type" "mcmp_media")
11605 (set_attr "highpart" "depend")])
11607 (define_insn "negcmpgtuv8qi"
11608 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11609 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11610 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11612 "mcmpgt.ub %N1, %N2, %0"
11613 [(set_attr "type" "mcmp_media")
11614 (set_attr "highpart" "depend")])
11616 (define_insn "negcmpgtv2si"
11617 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11618 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11619 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11621 "mcmpgt.l %N1, %N2, %0"
11622 [(set_attr "type" "mcmp_media")
11623 (set_attr "highpart" "depend")])
11625 (define_insn "negcmpgtv4hi"
11626 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11627 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11628 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11630 "mcmpgt.w %N1, %N2, %0"
11631 [(set_attr "type" "mcmp_media")
11632 (set_attr "highpart" "depend")])
11634 (define_insn "mcmv"
11635 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11636 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11637 (match_operand:DI 2 "arith_reg_operand" "r"))
11638 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11639 (not:DI (match_dup 2)))))]
11642 [(set_attr "type" "arith_media")
11643 (set_attr "highpart" "depend")])
11645 (define_insn "mcnvs_lw"
11646 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11648 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11649 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11651 "mcnvs.lw %N1, %N2, %0"
11652 [(set_attr "type" "mcmp_media")])
11654 (define_insn "mcnvs_wb"
11655 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11657 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11658 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11660 "mcnvs.wb %N1, %N2, %0"
11661 [(set_attr "type" "mcmp_media")])
11663 (define_insn "mcnvs_wub"
11664 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11666 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11667 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11669 "mcnvs.wub %N1, %N2, %0"
11670 [(set_attr "type" "mcmp_media")])
11672 (define_insn "mextr_rl"
11673 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11674 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11675 (match_operand:HI 3 "mextr_bit_offset" "i"))
11676 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11677 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11678 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11681 static char templ[21];
11683 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11684 (int) INTVAL (operands[3]) >> 3);
11687 [(set_attr "type" "arith_media")])
11689 (define_insn "*mextr_lr"
11690 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11691 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11692 (match_operand:HI 3 "mextr_bit_offset" "i"))
11693 (lshiftrt: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%%N2, %%N1, %%0\",
11701 (int) INTVAL (operands[4]) >> 3);
11704 [(set_attr "type" "arith_media")])
11706 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11707 ; vector then varies depending on endianness.
11708 (define_expand "mextr1"
11709 [(match_operand:DI 0 "arith_reg_dest" "")
11710 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11711 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11715 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11716 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11720 (define_expand "mextr2"
11721 [(match_operand:DI 0 "arith_reg_dest" "")
11722 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11723 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11727 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11728 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11732 (define_expand "mextr3"
11733 [(match_operand:DI 0 "arith_reg_dest" "")
11734 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11735 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11739 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11740 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11744 (define_expand "mextr4"
11745 [(match_operand:DI 0 "arith_reg_dest" "")
11746 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11747 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11751 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11752 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11756 (define_expand "mextr5"
11757 [(match_operand:DI 0 "arith_reg_dest" "")
11758 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11759 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11763 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11764 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11768 (define_expand "mextr6"
11769 [(match_operand:DI 0 "arith_reg_dest" "")
11770 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11771 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11775 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11776 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11780 (define_expand "mextr7"
11781 [(match_operand:DI 0 "arith_reg_dest" "")
11782 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11783 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11787 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11788 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11792 (define_expand "mmacfx_wl"
11793 [(match_operand:V2SI 0 "arith_reg_dest" "")
11794 (match_operand:V2HI 1 "extend_reg_operand" "")
11795 (match_operand:V2HI 2 "extend_reg_operand" "")
11796 (match_operand:V2SI 3 "arith_reg_operand" "")]
11800 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11801 operands[1], operands[2]));
11805 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11807 (define_insn "mmacfx_wl_i"
11808 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11810 (match_operand:V2SI 1 "arith_reg_operand" "0")
11815 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11816 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11819 "mmacfx.wl %2, %3, %0"
11820 [(set_attr "type" "mac_media")
11821 (set_attr "highpart" "depend")])
11823 (define_expand "mmacnfx_wl"
11824 [(match_operand:V2SI 0 "arith_reg_dest" "")
11825 (match_operand:V2HI 1 "extend_reg_operand" "")
11826 (match_operand:V2HI 2 "extend_reg_operand" "")
11827 (match_operand:V2SI 3 "arith_reg_operand" "")]
11831 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11832 operands[1], operands[2]));
11836 (define_insn "mmacnfx_wl_i"
11837 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11839 (match_operand:V2SI 1 "arith_reg_operand" "0")
11844 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11845 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11848 "mmacnfx.wl %2, %3, %0"
11849 [(set_attr "type" "mac_media")
11850 (set_attr "highpart" "depend")])
11852 (define_insn "mulv2si3"
11853 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11854 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11855 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11857 "mmul.l %1, %2, %0"
11858 [(set_attr "type" "d2mpy_media")
11859 (set_attr "highpart" "depend")])
11861 (define_insn "mulv4hi3"
11862 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11863 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11864 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11866 "mmul.w %1, %2, %0"
11867 [(set_attr "type" "dmpy_media")
11868 (set_attr "highpart" "depend")])
11870 (define_insn "mmulfx_l"
11871 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11875 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11876 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11879 "mmulfx.l %1, %2, %0"
11880 [(set_attr "type" "d2mpy_media")
11881 (set_attr "highpart" "depend")])
11883 (define_insn "mmulfx_w"
11884 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11888 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11889 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11892 "mmulfx.w %1, %2, %0"
11893 [(set_attr "type" "dmpy_media")
11894 (set_attr "highpart" "depend")])
11896 (define_insn "mmulfxrp_w"
11897 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11902 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11903 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11907 "mmulfxrp.w %1, %2, %0"
11908 [(set_attr "type" "dmpy_media")
11909 (set_attr "highpart" "depend")])
11912 (define_expand "mmulhi_wl"
11913 [(match_operand:V2SI 0 "arith_reg_dest" "")
11914 (match_operand:V4HI 1 "arith_reg_operand" "")
11915 (match_operand:V4HI 2 "arith_reg_operand" "")]
11919 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11920 (operands[0], operands[1], operands[2]));
11924 (define_expand "mmullo_wl"
11925 [(match_operand:V2SI 0 "arith_reg_dest" "")
11926 (match_operand:V4HI 1 "arith_reg_operand" "")
11927 (match_operand:V4HI 2 "arith_reg_operand" "")]
11931 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11932 (operands[0], operands[1], operands[2]));
11936 (define_insn "mmul23_wl"
11937 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11940 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11941 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11942 (parallel [(const_int 2) (const_int 3)])))]
11944 "* return (TARGET_LITTLE_ENDIAN
11945 ? \"mmulhi.wl %1, %2, %0\"
11946 : \"mmullo.wl %1, %2, %0\");"
11947 [(set_attr "type" "dmpy_media")
11948 (set (attr "highpart")
11949 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11950 (const_string "user")))])
11952 (define_insn "mmul01_wl"
11953 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11956 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11957 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11958 (parallel [(const_int 0) (const_int 1)])))]
11960 "* return (TARGET_LITTLE_ENDIAN
11961 ? \"mmullo.wl %1, %2, %0\"
11962 : \"mmulhi.wl %1, %2, %0\");"
11963 [(set_attr "type" "dmpy_media")
11964 (set (attr "highpart")
11965 (cond [(eq_attr "endian" "little") (const_string "ignore")]
11966 (const_string "user")))])
11969 (define_expand "mmulsum_wq"
11970 [(match_operand:DI 0 "arith_reg_dest" "")
11971 (match_operand:V4HI 1 "arith_reg_operand" "")
11972 (match_operand:V4HI 2 "arith_reg_operand" "")
11973 (match_operand:DI 3 "arith_reg_operand" "")]
11977 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11978 operands[1], operands[2]));
11982 (define_insn "mmulsum_wq_i"
11983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11984 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11989 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11990 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11991 (parallel [(const_int 0)]))
11992 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11993 (sign_extend:V4DI (match_dup 3)))
11994 (parallel [(const_int 1)])))
11996 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11997 (sign_extend:V4DI (match_dup 3)))
11998 (parallel [(const_int 2)]))
11999 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12000 (sign_extend:V4DI (match_dup 3)))
12001 (parallel [(const_int 3)]))))))]
12003 "mmulsum.wq %2, %3, %0"
12004 [(set_attr "type" "mac_media")])
12006 (define_expand "mperm_w"
12007 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12008 (match_operand:V4HI 1 "arith_reg_operand" "r")
12009 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12013 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12014 (operands[0], operands[1], operands[2]));
12018 ; This use of vec_select isn't exactly correct according to rtl.texi
12019 ; (because not constant), but it seems a straightforward extension.
12020 (define_insn "mperm_w_little"
12021 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12023 (match_operand:V4HI 1 "arith_reg_operand" "r")
12025 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12026 (const_int 2) (const_int 0))
12027 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12028 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12029 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12030 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12031 "mperm.w %1, %N2, %0"
12032 [(set_attr "type" "arith_media")])
12034 (define_insn "mperm_w_big"
12035 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12037 (match_operand:V4HI 1 "arith_reg_operand" "r")
12039 [(zero_extract:QI (not:QI (match_operand:QI 2
12040 "extend_reg_or_0_operand" "rZ"))
12041 (const_int 2) (const_int 0))
12042 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12043 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12044 (zero_extract:QI (not:QI (match_dup 2))
12045 (const_int 2) (const_int 6))])))]
12046 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12047 "mperm.w %1, %N2, %0"
12048 [(set_attr "type" "arith_media")])
12050 (define_insn "mperm_w0"
12051 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12052 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12053 "trunc_hi_operand" "r"))))]
12055 "mperm.w %1, r63, %0"
12056 [(set_attr "type" "arith_media")
12057 (set_attr "highpart" "ignore")])
12059 (define_expand "msad_ubq"
12060 [(match_operand:DI 0 "arith_reg_dest" "")
12061 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12062 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12063 (match_operand:DI 3 "arith_reg_operand" "")]
12067 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12068 operands[1], operands[2]));
12072 (define_insn "msad_ubq_i"
12073 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12078 (match_operand:DI 1 "arith_reg_operand" "0")
12079 (abs:DI (vec_select:DI
12082 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12084 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12085 (parallel [(const_int 0)]))))
12086 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12087 (zero_extend:V8DI (match_dup 3)))
12088 (parallel [(const_int 1)]))))
12090 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12091 (zero_extend:V8DI (match_dup 3)))
12092 (parallel [(const_int 2)])))
12093 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12094 (zero_extend:V8DI (match_dup 3)))
12095 (parallel [(const_int 3)])))))
12098 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12099 (zero_extend:V8DI (match_dup 3)))
12100 (parallel [(const_int 4)])))
12101 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12102 (zero_extend:V8DI (match_dup 3)))
12103 (parallel [(const_int 5)]))))
12105 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12106 (zero_extend:V8DI (match_dup 3)))
12107 (parallel [(const_int 6)])))
12108 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12109 (zero_extend:V8DI (match_dup 3)))
12110 (parallel [(const_int 7)])))))))]
12112 "msad.ubq %N2, %N3, %0"
12113 [(set_attr "type" "mac_media")])
12115 (define_insn "mshalds_l"
12116 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12119 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12120 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12121 (const_int 31)))))]
12123 "mshalds.l %1, %2, %0"
12124 [(set_attr "type" "mcmp_media")
12125 (set_attr "highpart" "depend")])
12127 (define_insn "mshalds_w"
12128 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12131 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12132 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12133 (const_int 15)))))]
12135 "mshalds.w %1, %2, %0"
12136 [(set_attr "type" "mcmp_media")
12137 (set_attr "highpart" "depend")])
12139 (define_insn "ashrv2si3"
12140 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12141 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12142 (match_operand:DI 2 "arith_reg_operand" "r")))]
12144 "mshard.l %1, %2, %0"
12145 [(set_attr "type" "arith_media")
12146 (set_attr "highpart" "depend")])
12148 (define_insn "ashrv4hi3"
12149 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12150 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12151 (match_operand:DI 2 "arith_reg_operand" "r")))]
12153 "mshard.w %1, %2, %0"
12154 [(set_attr "type" "arith_media")
12155 (set_attr "highpart" "depend")])
12157 (define_insn "mshards_q"
12158 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12160 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12161 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12163 "mshards.q %1, %N2, %0"
12164 [(set_attr "type" "mcmp_media")])
12166 (define_expand "mshfhi_b"
12167 [(match_operand:V8QI 0 "arith_reg_dest" "")
12168 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12169 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12173 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12174 (operands[0], operands[1], operands[2]));
12178 (define_expand "mshflo_b"
12179 [(match_operand:V8QI 0 "arith_reg_dest" "")
12180 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12181 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12185 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12186 (operands[0], operands[1], operands[2]));
12190 (define_insn "mshf4_b"
12192 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12194 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12195 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12196 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12197 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12199 "* return (TARGET_LITTLE_ENDIAN
12200 ? \"mshfhi.b %N1, %N2, %0\"
12201 : \"mshflo.b %N1, %N2, %0\");"
12202 [(set_attr "type" "arith_media")
12203 (set (attr "highpart")
12204 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12205 (const_string "user")))])
12207 (define_insn "mshf0_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 0) (const_int 8) (const_int 1) (const_int 9)
12214 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12216 "* return (TARGET_LITTLE_ENDIAN
12217 ? \"mshflo.b %N1, %N2, %0\"
12218 : \"mshfhi.b %N1, %N2, %0\");"
12219 [(set_attr "type" "arith_media")
12220 (set (attr "highpart")
12221 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12222 (const_string "user")))])
12224 (define_expand "mshfhi_l"
12225 [(match_operand:V2SI 0 "arith_reg_dest" "")
12226 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12227 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12231 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12232 (operands[0], operands[1], operands[2]));
12236 (define_expand "mshflo_l"
12237 [(match_operand:V2SI 0 "arith_reg_dest" "")
12238 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12239 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12243 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12244 (operands[0], operands[1], operands[2]));
12248 (define_insn "mshf4_l"
12249 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12251 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12252 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12253 (parallel [(const_int 1) (const_int 3)])))]
12255 "* return (TARGET_LITTLE_ENDIAN
12256 ? \"mshfhi.l %N1, %N2, %0\"
12257 : \"mshflo.l %N1, %N2, %0\");"
12258 [(set_attr "type" "arith_media")
12259 (set (attr "highpart")
12260 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12261 (const_string "user")))])
12263 (define_insn "mshf0_l"
12264 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12266 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12267 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12268 (parallel [(const_int 0) (const_int 2)])))]
12270 "* return (TARGET_LITTLE_ENDIAN
12271 ? \"mshflo.l %N1, %N2, %0\"
12272 : \"mshfhi.l %N1, %N2, %0\");"
12273 [(set_attr "type" "arith_media")
12274 (set (attr "highpart")
12275 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12276 (const_string "user")))])
12278 (define_expand "mshfhi_w"
12279 [(match_operand:V4HI 0 "arith_reg_dest" "")
12280 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12281 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12285 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12286 (operands[0], operands[1], operands[2]));
12290 (define_expand "mshflo_w"
12291 [(match_operand:V4HI 0 "arith_reg_dest" "")
12292 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12293 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12297 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12298 (operands[0], operands[1], operands[2]));
12302 (define_insn "mshf4_w"
12303 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12305 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12306 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12307 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12309 "* return (TARGET_LITTLE_ENDIAN
12310 ? \"mshfhi.w %N1, %N2, %0\"
12311 : \"mshflo.w %N1, %N2, %0\");"
12312 [(set_attr "type" "arith_media")
12313 (set (attr "highpart")
12314 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12315 (const_string "user")))])
12317 (define_insn "mshf0_w"
12318 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12320 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12321 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12322 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12324 "* return (TARGET_LITTLE_ENDIAN
12325 ? \"mshflo.w %N1, %N2, %0\"
12326 : \"mshfhi.w %N1, %N2, %0\");"
12327 [(set_attr "type" "arith_media")
12328 (set (attr "highpart")
12329 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12330 (const_string "user")))])
12332 (define_insn "mshflo_w_x"
12333 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12335 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12336 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12337 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12339 "mshflo.w %N1, %N2, %0"
12340 [(set_attr "type" "arith_media")
12341 (set_attr "highpart" "ignore")])
12343 /* These are useful to expand ANDs and as combiner patterns. */
12344 (define_insn_and_split "mshfhi_l_di"
12345 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12346 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12348 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12349 (const_int -4294967296))))]
12352 mshfhi.l %N1, %N2, %0
12354 "TARGET_SHMEDIA && reload_completed
12355 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12356 [(set (match_dup 3) (match_dup 4))
12357 (set (match_dup 5) (match_dup 6))]
12360 operands[3] = gen_lowpart (SImode, operands[0]);
12361 operands[4] = gen_highpart (SImode, operands[1]);
12362 operands[5] = gen_highpart (SImode, operands[0]);
12363 operands[6] = gen_highpart (SImode, operands[2]);
12365 [(set_attr "type" "arith_media")])
12367 (define_insn "*mshfhi_l_di_rev"
12368 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12369 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12370 (const_int -4294967296))
12371 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12374 "mshfhi.l %N2, %N1, %0"
12375 [(set_attr "type" "arith_media")])
12378 [(set (match_operand:DI 0 "arith_reg_dest" "")
12379 (ior:DI (zero_extend:DI (match_operand:SI 1
12380 "extend_reg_or_0_operand" ""))
12381 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12382 (const_int -4294967296))))
12383 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12388 emit_insn (gen_ashldi3_media (operands[3],
12389 simplify_gen_subreg (DImode, operands[1],
12392 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12396 (define_insn "mshflo_l_di"
12397 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12398 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12399 (const_int 4294967295))
12400 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12404 "mshflo.l %N1, %N2, %0"
12405 [(set_attr "type" "arith_media")
12406 (set_attr "highpart" "ignore")])
12408 (define_insn "*mshflo_l_di_rev"
12409 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12410 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12412 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12413 (const_int 4294967295))))]
12416 "mshflo.l %N2, %N1, %0"
12417 [(set_attr "type" "arith_media")
12418 (set_attr "highpart" "ignore")])
12420 ;; Combiner pattern for trampoline initialization.
12421 (define_insn_and_split "*double_shori"
12422 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12423 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12425 (match_operand:DI 2 "const_int_operand" "n")))]
12427 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12429 "rtx_equal_p (operands[0], operands[1])"
12433 HOST_WIDE_INT v = INTVAL (operands[2]);
12435 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12436 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12439 [(set_attr "highpart" "ignore")])
12442 (define_insn "*mshflo_l_di_x"
12443 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12444 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12446 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12450 "mshflo.l %N1, %N2, %0"
12451 [(set_attr "type" "arith_media")
12452 (set_attr "highpart" "ignore")])
12454 (define_insn_and_split "concat_v2sf"
12455 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12456 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12457 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12458 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12462 mshflo.l %N1, %N2, %0
12465 "TARGET_SHMEDIA && reload_completed
12466 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12467 [(set (match_dup 3) (match_dup 1))
12468 (set (match_dup 4) (match_dup 2))]
12471 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12472 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12474 [(set_attr "type" "arith_media")
12475 (set_attr "highpart" "ignore")])
12477 (define_insn "*mshflo_l_di_x_rev"
12478 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12479 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12481 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12484 "mshflo.l %N2, %N1, %0"
12485 [(set_attr "type" "arith_media")
12486 (set_attr "highpart" "ignore")])
12488 (define_insn "ashlv2si3"
12489 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12490 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12491 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12493 "mshlld.l %1, %2, %0"
12494 [(set_attr "type" "arith_media")
12495 (set_attr "highpart" "depend")])
12498 [(set (match_operand 0 "any_register_operand" "")
12499 (match_operator 3 "shift_operator"
12500 [(match_operand 1 "any_register_operand" "")
12501 (match_operand 2 "shift_count_reg_operand" "")]))]
12502 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12503 [(set (match_dup 0) (match_dup 3))]
12506 rtx count = operands[2];
12507 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12509 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12510 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12511 || GET_CODE (count) == TRUNCATE)
12512 count = XEXP (count, 0);
12513 inner_mode = GET_MODE (count);
12514 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12515 subreg_lowpart_offset (outer_mode, inner_mode));
12516 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12517 operands[1], count);
12520 (define_insn "ashlv4hi3"
12521 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12522 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12523 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12525 "mshlld.w %1, %2, %0"
12526 [(set_attr "type" "arith_media")
12527 (set_attr "highpart" "depend")])
12529 (define_insn "lshrv2si3"
12530 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12531 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12532 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12534 "mshlrd.l %1, %2, %0"
12535 [(set_attr "type" "arith_media")
12536 (set_attr "highpart" "depend")])
12538 (define_insn "lshrv4hi3"
12539 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12540 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12541 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12543 "mshlrd.w %1, %2, %0"
12544 [(set_attr "type" "arith_media")
12545 (set_attr "highpart" "depend")])
12547 (define_insn "subv2si3"
12548 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12549 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12550 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12552 "msub.l %N1, %2, %0"
12553 [(set_attr "type" "arith_media")
12554 (set_attr "highpart" "depend")])
12556 (define_insn "subv4hi3"
12557 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12558 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12559 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12561 "msub.w %N1, %2, %0"
12562 [(set_attr "type" "arith_media")
12563 (set_attr "highpart" "depend")])
12565 (define_insn_and_split "subv2hi3"
12566 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12567 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12568 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12575 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12576 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12577 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12578 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12579 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12581 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12582 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12585 [(set_attr "highpart" "must_split")])
12587 (define_insn "sssubv2si3"
12588 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12589 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12590 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12592 "msubs.l %N1, %2, %0"
12593 [(set_attr "type" "mcmp_media")
12594 (set_attr "highpart" "depend")])
12596 (define_insn "ussubv8qi3"
12597 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12598 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12599 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12601 "msubs.ub %N1, %2, %0"
12602 [(set_attr "type" "mcmp_media")
12603 (set_attr "highpart" "depend")])
12605 (define_insn "sssubv4hi3"
12606 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12607 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12608 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12610 "msubs.w %N1, %2, %0"
12611 [(set_attr "type" "mcmp_media")
12612 (set_attr "highpart" "depend")])
12614 ;; Floating Point Intrinsics
12616 (define_insn "fcosa_s"
12617 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12618 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12622 [(set_attr "type" "atrans_media")])
12624 (define_insn "fsina_s"
12625 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12626 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12630 [(set_attr "type" "atrans_media")])
12632 (define_insn "fipr"
12633 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12634 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12635 "fp_arith_reg_operand" "f")
12636 (match_operand:V4SF 2
12637 "fp_arith_reg_operand" "f"))
12638 (parallel [(const_int 0)]))
12639 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12640 (parallel [(const_int 1)])))
12641 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12642 (parallel [(const_int 2)]))
12643 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12644 (parallel [(const_int 3)])))))]
12646 "fipr.s %1, %2, %0"
12647 [(set_attr "type" "fparith_media")])
12649 (define_insn "fsrra_s"
12650 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12651 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12655 [(set_attr "type" "atrans_media")])
12657 (define_insn "ftrv"
12658 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12662 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12663 (parallel [(const_int 0) (const_int 5)
12664 (const_int 10) (const_int 15)]))
12665 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12667 (vec_select:V4SF (match_dup 1)
12668 (parallel [(const_int 4) (const_int 9)
12669 (const_int 14) (const_int 3)]))
12670 (vec_select:V4SF (match_dup 2)
12671 (parallel [(const_int 1) (const_int 2)
12672 (const_int 3) (const_int 0)]))))
12675 (vec_select:V4SF (match_dup 1)
12676 (parallel [(const_int 8) (const_int 13)
12677 (const_int 2) (const_int 7)]))
12678 (vec_select:V4SF (match_dup 2)
12679 (parallel [(const_int 2) (const_int 3)
12680 (const_int 0) (const_int 1)])))
12682 (vec_select:V4SF (match_dup 1)
12683 (parallel [(const_int 12) (const_int 1)
12684 (const_int 6) (const_int 11)]))
12685 (vec_select:V4SF (match_dup 2)
12686 (parallel [(const_int 3) (const_int 0)
12687 (const_int 1) (const_int 2)]))))))]
12689 "ftrv.s %1, %2, %0"
12690 [(set_attr "type" "fparith_media")])
12692 (define_insn "ldhi_l"
12693 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12695 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12698 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12702 [(set_attr "type" "load_media")])
12704 (define_insn "ldhi_q"
12705 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12707 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12710 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12714 [(set_attr "type" "load_media")])
12716 (define_insn_and_split "*ldhi_q_comb0"
12717 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12719 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12720 "register_operand" "r")
12721 (match_operand:SI 2
12722 "ua_offset" "I06"))
12725 (plus:SI (and:SI (match_dup 1) (const_int 7))
12728 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12732 "emit_insn (gen_ldhi_q (operands[0],
12733 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12737 (define_insn_and_split "*ldhi_q_comb1"
12738 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12740 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12741 "register_operand" "r")
12742 (match_operand:SI 2
12743 "ua_offset" "I06"))
12746 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12747 "ua_offset" "I06"))
12751 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12752 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12756 "emit_insn (gen_ldhi_q (operands[0],
12757 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12761 (define_insn "ldlo_l"
12762 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12764 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12766 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12767 (and:SI (match_dup 1) (const_int 3))))]
12770 [(set_attr "type" "load_media")])
12772 (define_insn "ldlo_q"
12773 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12775 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12777 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12778 (and:SI (match_dup 1) (const_int 7))))]
12781 [(set_attr "type" "load_media")])
12783 (define_insn_and_split "*ldlo_q_comb0"
12784 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12786 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12787 (match_operand:SI 2 "ua_offset" "I06"))
12789 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12790 (and:SI (match_dup 1) (const_int 7))))]
12791 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12795 "emit_insn (gen_ldlo_q (operands[0],
12796 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12799 (define_insn_and_split "*ldlo_q_comb1"
12800 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12802 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12803 (match_operand:SI 2 "ua_offset" "I06"))
12805 (minus:SI (const_int 8)
12806 (and:SI (plus:SI (match_dup 1)
12807 (match_operand:SI 3 "ua_offset" "I06"))
12809 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12810 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12811 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12815 "emit_insn (gen_ldlo_q (operands[0],
12816 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12819 (define_insn "sthi_l"
12820 [(set (zero_extract:SI
12821 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12824 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12826 (match_operand:SI 1 "arith_reg_operand" "r"))]
12829 [(set_attr "type" "ustore_media")])
12831 ;; All unaligned stores are considered to be 'narrow' because they typically
12832 ;; operate on less that a quadword, and when they operate on a full quadword,
12833 ;; the vanilla store high / store low sequence will cause a stall if not
12834 ;; scheduled apart.
12835 (define_insn "sthi_q"
12836 [(set (zero_extract:DI
12837 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12840 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12842 (match_operand:DI 1 "arith_reg_operand" "r"))]
12845 [(set_attr "type" "ustore_media")])
12847 (define_insn_and_split "*sthi_q_comb0"
12848 [(set (zero_extract:DI
12849 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12850 "register_operand" "r")
12851 (match_operand:SI 1 "ua_offset"
12855 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12857 (match_operand:DI 2 "arith_reg_operand" "r"))]
12858 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12862 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12866 (define_insn_and_split "*sthi_q_comb1"
12867 [(set (zero_extract:DI
12868 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12869 "register_operand" "r")
12870 (match_operand:SI 1 "ua_offset"
12874 (plus:SI (and:SI (plus:SI (match_dup 0)
12875 (match_operand:SI 2 "ua_offset" "I06"))
12879 (match_operand:DI 3 "arith_reg_operand" "r"))]
12880 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12881 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12885 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12889 ;; This is highpart user because the address is used as full 64 bit.
12890 (define_insn "stlo_l"
12891 [(set (zero_extract:SI
12892 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12894 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12895 (and:SI (match_dup 0) (const_int 3)))
12896 (match_operand:SI 1 "arith_reg_operand" "r"))]
12899 [(set_attr "type" "ustore_media")])
12901 (define_insn "stlo_q"
12902 [(set (zero_extract:DI
12903 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12905 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12906 (and:SI (match_dup 0) (const_int 7)))
12907 (match_operand:DI 1 "arith_reg_operand" "r"))]
12910 [(set_attr "type" "ustore_media")])
12912 (define_insn_and_split "*stlo_q_comb0"
12913 [(set (zero_extract:DI
12914 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12915 (match_operand:SI 1 "ua_offset" "I06"))
12917 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12918 (and:SI (match_dup 0) (const_int 7)))
12919 (match_operand:DI 2 "arith_reg_operand" "r"))]
12920 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12924 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12928 (define_insn_and_split "*stlo_q_comb1"
12929 [(set (zero_extract:DI
12930 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12931 (match_operand:SI 1 "ua_offset" "I06"))
12933 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12934 (match_operand:SI 2
12935 "ua_offset" "I06"))
12937 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12938 (match_operand:DI 3 "arith_reg_operand" "r"))]
12939 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12943 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12947 (define_insn "ldhi_l64"
12948 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12950 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12953 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12957 [(set_attr "type" "load_media")])
12959 (define_insn "ldhi_q64"
12960 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12962 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12965 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12969 [(set_attr "type" "load_media")])
12971 (define_insn "ldlo_l64"
12972 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12974 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12976 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12977 (and:DI (match_dup 1) (const_int 3))))]
12980 [(set_attr "type" "load_media")])
12982 (define_insn "ldlo_q64"
12983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12985 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12987 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12988 (and:DI (match_dup 1) (const_int 7))))]
12991 [(set_attr "type" "load_media")])
12993 (define_insn "sthi_l64"
12994 [(set (zero_extract:SI
12995 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12998 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13000 (match_operand:SI 1 "arith_reg_operand" "r"))]
13003 [(set_attr "type" "ustore_media")])
13005 (define_insn "sthi_q64"
13006 [(set (zero_extract:DI
13007 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13010 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13012 (match_operand:DI 1 "arith_reg_operand" "r"))]
13015 [(set_attr "type" "ustore_media")])
13017 (define_insn "stlo_l64"
13018 [(set (zero_extract:SI
13019 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13021 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13022 (and:DI (match_dup 0) (const_int 3)))
13023 (match_operand:SI 1 "arith_reg_operand" "r"))]
13026 [(set_attr "type" "ustore_media")])
13028 (define_insn "stlo_q64"
13029 [(set (zero_extract:DI
13030 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13032 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13033 (and:DI (match_dup 0) (const_int 7)))
13034 (match_operand:DI 1 "arith_reg_operand" "r"))]
13037 [(set_attr "type" "ustore_media")])
13040 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13041 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13045 [(set_attr "type" "arith_media")])
13047 (define_insn "nsbsi"
13048 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13050 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13054 [(set_attr "type" "arith_media")])
13056 (define_insn "nsbdi"
13057 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13059 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13063 [(set_attr "type" "arith_media")])
13065 (define_expand "ffsdi2"
13066 [(set (match_operand:DI 0 "arith_reg_dest" "")
13067 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13071 rtx scratch = gen_reg_rtx (DImode);
13074 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13075 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13076 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13077 emit_insn (gen_nsbdi (scratch, scratch));
13078 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13079 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13080 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13082 = gen_rtx_EXPR_LIST (REG_EQUAL,
13083 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13087 (define_expand "ffssi2"
13088 [(set (match_operand:SI 0 "arith_reg_dest" "")
13089 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13093 rtx scratch = gen_reg_rtx (SImode);
13094 rtx discratch = gen_reg_rtx (DImode);
13097 emit_insn (gen_adddi3 (discratch,
13098 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13100 emit_insn (gen_andcdi3 (discratch,
13101 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13103 emit_insn (gen_nsbsi (scratch, discratch));
13104 last = emit_insn (gen_subsi3 (operands[0],
13105 force_reg (SImode, GEN_INT (63)), scratch));
13107 = gen_rtx_EXPR_LIST (REG_EQUAL,
13108 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13112 (define_insn "byterev"
13113 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13114 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13115 (parallel [(const_int 7) (const_int 6) (const_int 5)
13116 (const_int 4) (const_int 3) (const_int 2)
13117 (const_int 1) (const_int 0)])))]
13120 [(set_attr "type" "arith_media")])
13122 (define_insn "*prefetch_media"
13123 [(prefetch (match_operand:QI 0 "address_operand" "p")
13124 (match_operand:SI 1 "const_int_operand" "n")
13125 (match_operand:SI 2 "const_int_operand" "n"))]
13129 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13130 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13133 [(set_attr "type" "other")])
13135 (define_insn "*prefetch_i4"
13136 [(prefetch (match_operand:SI 0 "register_operand" "r")
13137 (match_operand:SI 1 "const_int_operand" "n")
13138 (match_operand:SI 2 "const_int_operand" "n"))]
13139 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13142 return \"pref @%0\";
13144 [(set_attr "type" "other")])
13146 (define_expand "prefetch"
13147 [(prefetch (match_operand 0 "address_operand" "p")
13148 (match_operand:SI 1 "const_int_operand" "n")
13149 (match_operand:SI 2 "const_int_operand" "n"))]
13150 "TARGET_HARD_SH4 || TARGET_SH5"
13153 if (GET_MODE (operands[0]) != Pmode
13154 || GET_CODE (operands[1]) != CONST_INT
13155 || GET_CODE (operands[2]) != CONST_INT)
13157 if (! TARGET_SHMEDIA)
13158 operands[0] = force_reg (Pmode, operands[0]);
13161 (define_insn "alloco_i"
13162 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13163 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13169 if (GET_CODE (operands[0]) == PLUS)
13171 xops[0] = XEXP (operands[0], 0);
13172 xops[1] = XEXP (operands[0], 1);
13176 xops[0] = operands[0];
13177 xops[1] = const0_rtx;
13179 output_asm_insn (\"alloco %0, %1\", xops);
13182 [(set_attr "type" "other")])
13185 [(set (match_operand 0 "any_register_operand" "")
13186 (match_operand 1 "" ""))]
13187 "TARGET_SHMEDIA && reload_completed"
13188 [(set (match_dup 0) (match_dup 1))]
13193 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13198 ; Stack Protector Patterns
13200 (define_expand "stack_protect_set"
13201 [(set (match_operand 0 "memory_operand" "")
13202 (match_operand 1 "memory_operand" ""))]
13205 if (TARGET_SHMEDIA)
13207 if (TARGET_SHMEDIA64)
13208 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13210 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13213 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13218 (define_insn "stack_protect_set_si"
13219 [(set (match_operand:SI 0 "memory_operand" "=m")
13220 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13221 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13223 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13224 [(set_attr "type" "other")
13225 (set_attr "length" "6")])
13227 (define_insn "stack_protect_set_si_media"
13228 [(set (match_operand:SI 0 "memory_operand" "=m")
13229 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13230 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13232 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13233 [(set_attr "type" "other")
13234 (set_attr "length" "12")])
13236 (define_insn "stack_protect_set_di_media"
13237 [(set (match_operand:DI 0 "memory_operand" "=m")
13238 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13239 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13241 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13242 [(set_attr "type" "other")
13243 (set_attr "length" "12")])
13245 (define_expand "stack_protect_test"
13246 [(match_operand 0 "memory_operand" "")
13247 (match_operand 1 "memory_operand" "")
13248 (match_operand 2 "" "")]
13251 if (TARGET_SHMEDIA)
13253 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13255 if (TARGET_SHMEDIA64)
13256 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13259 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13262 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13266 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13267 emit_jump_insn (gen_branch_true (operands[2]));
13273 (define_insn "stack_protect_test_si"
13274 [(set (reg:SI T_REG)
13275 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13276 (match_operand:SI 1 "memory_operand" "m")]
13278 (set (match_scratch:SI 2 "=&r") (const_int 0))
13279 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13281 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13282 [(set_attr "type" "other")
13283 (set_attr "length" "10")])
13285 (define_insn "stack_protect_test_si_media"
13286 [(set (match_operand:SI 0 "register_operand" "=&r")
13287 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13288 (match_operand:SI 2 "memory_operand" "m")]
13290 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13292 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13293 [(set_attr "type" "other")
13294 (set_attr "length" "16")])
13296 (define_insn "stack_protect_test_di_media"
13297 [(set (match_operand:DI 0 "register_operand" "=&r")
13298 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13299 (match_operand:DI 2 "memory_operand" "m")]
13301 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13303 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13304 [(set_attr "type" "other")
13305 (set_attr "length" "16")])