1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
138 (UNSPEC_EH_RETURN 19)
146 (UNSPEC_DIV_INV_M0 30)
147 (UNSPEC_DIV_INV_M1 31)
148 (UNSPEC_DIV_INV_M2 32)
149 (UNSPEC_DIV_INV_M3 33)
150 (UNSPEC_DIV_INV20 34)
151 (UNSPEC_DIV_INV_TABLE 37)
158 ;; These are used with unspec_volatile.
164 (UNSPECV_WINDOW_END 10)
165 (UNSPECV_CONST_END 11)
168 ;; -------------------------------------------------------------------------
170 ;; -------------------------------------------------------------------------
175 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
176 (const (symbol_ref "sh_cpu_attr")))
178 (define_attr "endian" "big,little"
179 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
180 (const_string "little") (const_string "big"))))
182 ;; Indicate if the default fpu mode is single precision.
183 (define_attr "fpu_single" "yes,no"
184 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
185 (const_string "yes") (const_string "no"))))
187 (define_attr "fmovd" "yes,no"
188 (const (if_then_else (symbol_ref "TARGET_FMOVD")
189 (const_string "yes") (const_string "no"))))
191 (define_attr "pipe_model" "sh1,sh4,sh5media"
193 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
194 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
195 (const_string "sh1"))))
197 ;; cbranch conditional branch instructions
198 ;; jump unconditional jumps
199 ;; arith ordinary arithmetic
200 ;; arith3 a compound insn that behaves similarly to a sequence of
201 ;; three insns of type arith
202 ;; arith3b like above, but might end with a redirected branch
204 ;; load_si Likewise, SImode variant for general register.
205 ;; fload Likewise, but load to fp register.
207 ;; fstore floating point register to memory
208 ;; move general purpose register to register
209 ;; movi8 8-bit immediate to general purpose register
210 ;; mt_group other sh4 mt instructions
211 ;; fmove register to register, floating point
212 ;; smpy word precision integer multiply
213 ;; dmpy longword or doublelongword precision integer multiply
215 ;; pload load of pr reg, which can't be put into delay slot of rts
216 ;; prset copy register to pr reg, ditto
217 ;; pstore store of pr reg, which can't be put into delay slot of jsr
218 ;; prget copy pr to register, ditto
219 ;; pcload pc relative load of constant value
220 ;; pcfload Likewise, but load to fp register.
221 ;; pcload_si Likewise, SImode variant for general register.
222 ;; rte return from exception
223 ;; sfunc special function call with known used registers
224 ;; call function call
226 ;; fpscr_toggle toggle a bit in the fpscr
227 ;; fdiv floating point divide (or square root)
228 ;; gp_fpul move from general purpose register to fpul
229 ;; fpul_gp move from fpul to general purpose register
230 ;; mac_gp move from mac[lh] to general purpose register
231 ;; gp_mac move from general purpose register to mac[lh]
232 ;; mac_mem move from mac[lh] to memory
233 ;; mem_mac move from memory to mac[lh]
234 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
235 ;; ftrc_s fix_truncsfsi2_i4
236 ;; dfdiv double precision floating point divide (or square root)
237 ;; cwb ic_invalidate_line_i
238 ;; movua SH4a unaligned load
239 ;; fsrra square root reciprocal approximate
240 ;; fsca sine and cosine approximate
241 ;; tls_load load TLS related address
242 ;; arith_media SHmedia arithmetic, logical, and shift instructions
243 ;; cbranch_media SHmedia conditional branch instructions
244 ;; cmp_media SHmedia compare instructions
245 ;; dfdiv_media SHmedia double precision divide and square root
246 ;; dfmul_media SHmedia double precision multiply instruction
247 ;; dfparith_media SHmedia double precision floating point arithmetic
248 ;; dfpconv_media SHmedia double precision floating point conversions
249 ;; dmpy_media SHmedia longword multiply
250 ;; fcmp_media SHmedia floating point compare instructions
251 ;; fdiv_media SHmedia single precision divide and square root
252 ;; fload_media SHmedia floating point register load instructions
253 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
254 ;; fparith_media SHmedia single precision floating point arithmetic
255 ;; fpconv_media SHmedia single precision floating point conversions
256 ;; fstore_media SHmedia floating point register store instructions
257 ;; gettr_media SHmedia gettr instruction
258 ;; invalidate_line_media SHmedia invalidate_line sequence
259 ;; jump_media SHmedia unconditional branch instructions
260 ;; load_media SHmedia general register load instructions
261 ;; pt_media SHmedia pt instruction (expanded by assembler)
262 ;; ptabs_media SHmedia ptabs instruction
263 ;; store_media SHmedia general register store instructions
264 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
265 ;; mac_media SHmedia mac-style fixed point operations
266 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
267 ;; atrans_media SHmedia approximate transcendental functions
268 ;; ustore_media SHmedia unaligned stores
269 ;; nil no-op move, will be deleted.
272 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,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"
273 (const_string "other"))
275 ;; We define a new attribute namely "insn_class".We use
276 ;; this for the DFA based pipeline description.
278 ;; mt_group SH4 "mt" group instructions.
280 ;; ex_group SH4 "ex" group instructions.
282 ;; ls_group SH4 "ls" group instructions.
285 (define_attr "insn_class"
286 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
287 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
288 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
289 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
290 (eq_attr "type" "cbranch,jump") (const_string "br_group")
291 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
292 (const_string "fe_group")
293 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
294 (const_string "none")))
295 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
296 ;; so these do not belong in an insn group, although they are modeled
297 ;; with their own define_insn_reservations.
299 ;; Indicate what precision must be selected in fpscr for this insn, if any.
301 (define_attr "fp_mode" "single,double,none" (const_string "none"))
303 ;; Indicate if the fpu mode is set by this instruction
304 ;; "unknown" must have the value as "none" in fp_mode, and means
305 ;; that the instruction/abi has left the processor in an unknown
307 ;; "none" means that nothing has changed and no mode is set.
308 ;; This attribute is only used for the Renesas ABI.
309 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
311 ; If a conditional branch destination is within -252..258 bytes away
312 ; from the instruction it can be 2 bytes long. Something in the
313 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
314 ; branches are initially assumed to be 16 bytes long.
315 ; In machine_dependent_reorg, we split all branches that are longer than
318 ;; The maximum range used for SImode constant pool entries is 1018. A final
319 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
320 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
321 ;; instruction around the pool table, 2 bytes of alignment before the table,
322 ;; and 30 bytes of alignment after the table. That gives a maximum total
323 ;; pool size of 1058 bytes.
324 ;; Worst case code/pool content size ratio is 1:2 (using asms).
325 ;; Thus, in the worst case, there is one instruction in front of a maximum
326 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
327 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
328 ;; If we have a forward branch, the initial table will be put after the
329 ;; unconditional branch.
331 ;; ??? We could do much better by keeping track of the actual pcloads within
332 ;; the branch range and in the pcload range in front of the branch range.
334 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
336 (define_attr "short_cbranch_p" "no,yes"
337 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
339 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
341 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
343 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
345 ] (const_string "no")))
347 (define_attr "med_branch_p" "no,yes"
348 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
351 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
356 ] (const_string "no")))
358 (define_attr "med_cbranch_p" "no,yes"
359 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
362 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
367 ] (const_string "no")))
369 (define_attr "braf_branch_p" "no,yes"
370 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
372 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
375 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
380 ] (const_string "no")))
382 (define_attr "braf_cbranch_p" "no,yes"
383 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
385 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
388 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
390 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
393 ] (const_string "no")))
395 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
396 ; For wider ranges, we need a combination of a code and a data part.
397 ; If we can get a scratch register for a long range jump, the code
398 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
399 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
400 ; long; otherwise, it must be 6 bytes long.
402 ; All other instructions are two bytes long by default.
404 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
405 ;; but getattrtab doesn't understand this.
406 (define_attr "length" ""
407 (cond [(eq_attr "type" "cbranch")
408 (cond [(eq_attr "short_cbranch_p" "yes")
410 (eq_attr "med_cbranch_p" "yes")
412 (eq_attr "braf_cbranch_p" "yes")
414 ;; ??? using pc is not computed transitively.
415 (ne (match_dup 0) (match_dup 0))
417 (ne (symbol_ref ("flag_pic")) (const_int 0))
420 (eq_attr "type" "jump")
421 (cond [(eq_attr "med_branch_p" "yes")
423 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
425 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
427 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
428 (symbol_ref "code_for_indirect_jump_scratch"))))
429 (cond [(eq_attr "braf_branch_p" "yes")
431 (eq (symbol_ref "flag_pic") (const_int 0))
433 (ne (symbol_ref "TARGET_SH2") (const_int 0))
434 (const_int 10)] (const_int 18))
435 (eq_attr "braf_branch_p" "yes")
437 ;; ??? using pc is not computed transitively.
438 (ne (match_dup 0) (match_dup 0))
440 (ne (symbol_ref ("flag_pic")) (const_int 0))
443 (eq_attr "type" "pt_media")
444 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
445 (const_int 20) (const_int 12))
446 (and (eq_attr "type" "jump_media")
447 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
449 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
453 ;; DFA descriptions for the pipelines
456 (include "shmedia.md")
459 (include "predicates.md")
461 ;; Definitions for filling delay slots
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
465 ;; ??? This should be (nil) instead of (const_int 0)
466 (define_attr "hit_stack" "yes,no"
467 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
470 (const_string "yes")))
472 (define_attr "interrupt_function" "no,yes"
473 (const (symbol_ref "current_function_interrupt")))
475 (define_attr "in_delay_slot" "yes,no"
476 (cond [(eq_attr "type" "cbranch") (const_string "no")
477 (eq_attr "type" "pcload,pcload_si") (const_string "no")
478 (eq_attr "needs_delay_slot" "yes") (const_string "no")
479 (eq_attr "length" "2") (const_string "yes")
480 ] (const_string "no")))
482 (define_attr "cond_delay_slot" "yes,no"
483 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
484 ] (const_string "no")))
486 (define_attr "is_sfunc" ""
487 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
489 (define_attr "is_mac_media" ""
490 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
492 (define_attr "branch_zero" "yes,no"
493 (cond [(eq_attr "type" "!cbranch") (const_string "no")
494 (ne (symbol_ref "(next_active_insn (insn)\
495 == (prev_active_insn\
496 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
497 && get_attr_length (next_active_insn (insn)) == 2")
499 (const_string "yes")]
500 (const_string "no")))
502 ;; SH4 Double-precision computation with double-precision result -
503 ;; the two halves are ready at different times.
504 (define_attr "dfp_comp" "yes,no"
505 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
506 (const_string "no")))
508 ;; Insns for which the latency of a preceding fp insn is decreased by one.
509 (define_attr "late_fp_use" "yes,no" (const_string "no"))
510 ;; And feeding insns for which this relevant.
511 (define_attr "any_fp_comp" "yes,no"
512 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
513 (const_string "yes")]
514 (const_string "no")))
516 (define_attr "any_int_load" "yes,no"
517 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
518 (const_string "yes")]
519 (const_string "no")))
521 (define_attr "highpart" "user, ignore, extend, depend, must_split"
522 (const_string "user"))
525 (eq_attr "needs_delay_slot" "yes")
526 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
528 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
529 ;; and thus we can't put a pop instruction in its delay slot.
530 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
531 ;; instruction can go in the delay slot.
533 ;; Since a normal return (rts) implicitly uses the PR register,
534 ;; we can't allow PR register loads in an rts delay slot.
537 (eq_attr "type" "return")
538 [(and (eq_attr "in_delay_slot" "yes")
539 (ior (and (eq_attr "interrupt_function" "no")
540 (eq_attr "type" "!pload,prset"))
541 (and (eq_attr "interrupt_function" "yes")
543 (ne (symbol_ref "TARGET_SH3") (const_int 0))
544 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
546 ;; Since a call implicitly uses the PR register, we can't allow
547 ;; a PR register store in a jsr delay slot.
550 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
551 [(and (eq_attr "in_delay_slot" "yes")
552 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
554 ;; Say that we have annulled true branches, since this gives smaller and
555 ;; faster code when branches are predicted as not taken.
557 ;; ??? The non-annulled condition should really be "in_delay_slot",
558 ;; but insns that can be filled in non-annulled get priority over insns
559 ;; that can only be filled in anulled.
562 (and (eq_attr "type" "cbranch")
563 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
564 ;; SH2e has a hardware bug that pretty much prohibits the use of
565 ;; annuled delay slots.
566 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
567 (not (eq_attr "cpu" "sh2e"))) (nil)])
569 ;; -------------------------------------------------------------------------
570 ;; SImode signed integer comparisons
571 ;; -------------------------------------------------------------------------
575 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
576 (match_operand:SI 1 "arith_operand" "K08,r"))
580 [(set_attr "type" "mt_group")])
582 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
583 ;; That would still allow reload to create cmpi instructions, but would
584 ;; perhaps allow forcing the constant into a register when that is better.
585 ;; Probably should use r0 for mem/imm compares, but force constant into a
586 ;; register for pseudo/imm compares.
588 (define_insn "cmpeqsi_t"
590 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
591 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
597 [(set_attr "type" "mt_group")])
599 (define_insn "cmpgtsi_t"
601 (gt: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 (define_insn "cmpgesi_t"
611 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
612 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
617 [(set_attr "type" "mt_group")])
619 ;; -------------------------------------------------------------------------
620 ;; SImode compare and branch
621 ;; -------------------------------------------------------------------------
623 (define_expand "cbranchsi4"
625 (if_then_else (match_operator 0 "comparison_operator"
626 [(match_operand:SI 1 "arith_operand" "")
627 (match_operand:SI 2 "arith_operand" "")])
628 (label_ref (match_operand 3 "" ""))
630 (clobber (reg:SI T_REG))]
632 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
634 ;; -------------------------------------------------------------------------
635 ;; SImode unsigned integer comparisons
636 ;; -------------------------------------------------------------------------
638 (define_insn_and_split "cmpgeusi_t"
640 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
641 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
644 "&& operands[0] == CONST0_RTX (SImode)"
648 emit_insn (gen_sett ());
651 [(set_attr "type" "mt_group")])
653 (define_insn "cmpgtusi_t"
655 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
656 (match_operand:SI 1 "arith_reg_operand" "r")))]
659 [(set_attr "type" "mt_group")])
661 ;; We save the compare operands in the cmpxx patterns and use them when
662 ;; we generate the branch.
664 (define_expand "cmpsi"
666 (compare (match_operand:SI 0 "cmpsi_operand" "")
667 (match_operand:SI 1 "arith_operand" "")))]
668 "TARGET_SH1 || TARGET_SHMEDIA"
671 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
672 && GET_CODE (operands[1]) != CONST_INT)
673 operands[0] = copy_to_mode_reg (SImode, operands[0]);
674 sh_compare_op0 = operands[0];
675 sh_compare_op1 = operands[1];
679 ;; -------------------------------------------------------------------------
680 ;; DImode compare and branch
681 ;; -------------------------------------------------------------------------
684 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
685 ;; Therefore, we aim to have a set of three branches that go straight to the
686 ;; destination, i.e. only one of them is taken at any one time.
687 ;; This mechanism should also be slightly better for the sh4-200.
689 (define_expand "cbranchdi4"
691 (if_then_else (match_operator 0 "comparison_operator"
692 [(match_operand:DI 1 "arith_operand" "")
693 (match_operand:DI 2 "arith_operand" "")])
694 (label_ref (match_operand 3 "" ""))
696 (clobber (match_dup 4))
697 (clobber (reg:SI T_REG))]
701 enum rtx_code comparison;
703 if (TARGET_EXPAND_CBRANCHDI4)
705 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
708 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
709 if (comparison != GET_CODE (operands[0]))
711 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
712 operands[4] = gen_rtx_SCRATCH (SImode);
715 (define_insn_and_split "cbranchdi4_i"
717 (if_then_else (match_operator 0 "comparison_operator"
718 [(match_operand:DI 1 "arith_operand" "r,r")
719 (match_operand:DI 2 "arith_operand" "rN,i")])
720 (label_ref (match_operand 3 "" ""))
722 (clobber (match_scratch:SI 4 "=X,&r"))
723 (clobber (reg:SI T_REG))]
726 "&& reload_completed"
730 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
735 ;; -------------------------------------------------------------------------
736 ;; DImode signed integer comparisons
737 ;; -------------------------------------------------------------------------
741 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
742 (match_operand:DI 1 "arith_operand" "r"))
745 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
747 [(set_attr "length" "6")
748 (set_attr "type" "arith3b")])
750 (define_insn "cmpeqdi_t"
752 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
753 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
756 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
757 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
758 [(set_attr "length" "6")
759 (set_attr "type" "arith3b")])
763 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
764 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
765 ;; If we applied this split when not optimizing, it would only be
766 ;; applied during the machine-dependent reorg, when no new basic blocks
768 "TARGET_SH1 && reload_completed && optimize"
769 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
770 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
771 (label_ref (match_dup 6))
773 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
778 = gen_rtx_REG (SImode,
779 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
781 = (operands[1] == const0_rtx
783 : gen_rtx_REG (SImode,
784 true_regnum (operands[1])
785 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
786 operands[4] = gen_lowpart (SImode, operands[0]);
787 operands[5] = gen_lowpart (SImode, operands[1]);
788 operands[6] = gen_label_rtx ();
791 (define_insn "cmpgtdi_t"
793 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
794 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
797 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
798 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
799 [(set_attr "length" "8")
800 (set_attr "type" "arith3")])
802 (define_insn "cmpgedi_t"
804 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
805 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
808 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
810 [(set_attr "length" "8,2")
811 (set_attr "type" "arith3,mt_group")])
813 ;; -------------------------------------------------------------------------
814 ;; DImode unsigned integer comparisons
815 ;; -------------------------------------------------------------------------
817 (define_insn "cmpgeudi_t"
819 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
820 (match_operand:DI 1 "arith_reg_operand" "r")))]
822 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
823 [(set_attr "length" "8")
824 (set_attr "type" "arith3")])
826 (define_insn "cmpgtudi_t"
828 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
829 (match_operand:DI 1 "arith_reg_operand" "r")))]
831 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
832 [(set_attr "length" "8")
833 (set_attr "type" "arith3")])
835 (define_insn "cmpeqsi_media"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
838 (match_operand:SI 2 "cmp_operand" "Nr")))]
841 [(set_attr "type" "cmp_media")])
843 (define_insn "cmpeqdi_media"
844 [(set (match_operand:SI 0 "register_operand" "=r")
845 (eq:SI (match_operand:DI 1 "register_operand" "%r")
846 (match_operand:DI 2 "cmp_operand" "Nr")))]
849 [(set_attr "type" "cmp_media")])
851 (define_insn "cmpgtsi_media"
852 [(set (match_operand:SI 0 "register_operand" "=r")
853 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
854 (match_operand:SI 2 "cmp_operand" "rN")))]
857 [(set_attr "type" "cmp_media")])
859 (define_insn "cmpgtdi_media"
860 [(set (match_operand:SI 0 "register_operand" "=r")
861 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
862 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
865 [(set_attr "type" "cmp_media")])
867 (define_insn "cmpgtusi_media"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
870 (match_operand:SI 2 "cmp_operand" "rN")))]
872 "cmpgtu %N1, %N2, %0"
873 [(set_attr "type" "cmp_media")])
875 (define_insn "cmpgtudi_media"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
878 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
880 "cmpgtu %N1, %N2, %0"
881 [(set_attr "type" "cmp_media")])
883 ; These two patterns are for combine.
884 (define_insn "*cmpne0sisi_media"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
889 [(set_attr "type" "cmp_media")])
891 ;; We save the compare operands in the cmpxx patterns and use them when
892 ;; we generate the branch.
894 (define_expand "cmpdi"
896 (compare (match_operand:DI 0 "arith_operand" "")
897 (match_operand:DI 1 "arith_operand" "")))]
898 "TARGET_SH2 || TARGET_SHMEDIA"
901 sh_compare_op0 = operands[0];
902 sh_compare_op1 = operands[1];
905 ;; -------------------------------------------------------------------------
906 ;; Conditional move instructions
907 ;; -------------------------------------------------------------------------
909 ;; The insn names may seem reversed, but note that cmveq performs the move
910 ;; if op1 == 0, and cmvne does it if op1 != 0.
912 (define_insn "movdicc_false"
913 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
914 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
916 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
917 (match_operand:DI 3 "arith_reg_operand" "0")))]
920 [(set_attr "type" "arith_media")])
922 (define_insn "movdicc_true"
923 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
924 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
926 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
927 (match_operand:DI 3 "arith_reg_operand" "0")))]
930 [(set_attr "type" "arith_media")])
933 [(set (match_operand:DI 0 "arith_reg_dest" "")
934 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
935 [(match_operand:DI 1 "arith_reg_operand" "")
937 (match_operand:DI 2 "arith_reg_dest" "")
939 (set (match_dup 2) (match_dup 0))]
940 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
942 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
945 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
946 VOIDmode, operands[1], CONST0_RTX (DImode));
950 [(set (match_operand:DI 0 "general_movdst_operand" "")
951 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
952 (set (match_operand:DI 2 "arith_reg_dest" "")
953 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
954 [(match_operand:DI 3 "arith_reg_operand" "")
958 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
960 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
963 (define_expand "movdicc"
964 [(set (match_operand:DI 0 "register_operand" "")
965 (if_then_else:DI (match_operand 1 "comparison_operator" "")
966 (match_operand:DI 2 "register_operand" "")
967 (match_operand:DI 3 "register_operand" "")))]
971 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
972 && GET_MODE (sh_compare_op0) == DImode
973 && sh_compare_op1 == const0_rtx)
974 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
975 sh_compare_op0, sh_compare_op1);
983 tmp = gen_reg_rtx (DImode);
985 switch (GET_CODE (operands[1]))
988 emit_insn (gen_seq (tmp));
989 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
993 emit_insn (gen_seq (tmp));
994 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
998 emit_insn (gen_sgt (tmp));
999 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1003 emit_insn (gen_slt (tmp));
1004 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1008 emit_insn (gen_slt (tmp));
1009 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1013 emit_insn (gen_sgt (tmp));
1014 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1018 emit_insn (gen_sgtu (tmp));
1019 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1023 emit_insn (gen_sltu (tmp));
1024 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1028 emit_insn (gen_sltu (tmp));
1029 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1033 emit_insn (gen_sgtu (tmp));
1034 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1038 emit_insn (gen_sunordered (tmp));
1039 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1043 emit_insn (gen_sunordered (tmp));
1044 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1061 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1062 ;; SImode to DImode.
1063 (define_insn "movsicc_false"
1064 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1065 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1067 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1068 (match_operand:SI 3 "arith_reg_operand" "0")))]
1071 [(set_attr "type" "arith_media")])
1073 (define_insn "movsicc_true"
1074 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1075 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1077 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1078 (match_operand:SI 3 "arith_reg_operand" "0")))]
1081 [(set_attr "type" "arith_media")])
1084 [(set (match_operand:SI 0 "arith_reg_dest" "")
1085 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1086 [(match_operand:SI 1 "arith_reg_operand" "")
1088 (match_operand:SI 2 "arith_reg_dest" "")
1090 (set (match_dup 2) (match_dup 0))]
1091 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1093 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1096 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1097 VOIDmode, operands[1], CONST0_RTX (SImode));
1101 [(set (match_operand:SI 0 "general_movdst_operand" "")
1102 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1103 (set (match_operand:SI 2 "arith_reg_dest" "")
1104 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1105 [(match_operand:SI 3 "arith_reg_operand" "")
1109 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1110 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1112 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1115 replace_rtx (operands[4], operands[0], operands[1]);
1119 [(set (match_operand 0 "any_register_operand" "")
1120 (match_operand 1 "any_register_operand" ""))
1121 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1122 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1123 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1124 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1125 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1126 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1127 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1128 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1129 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1130 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1131 && (REGNO_REG_CLASS (REGNO (operands[0]))
1132 == REGNO_REG_CLASS (REGNO (operands[2])))
1133 && (REGNO_REG_CLASS (REGNO (operands[1]))
1134 == REGNO_REG_CLASS (REGNO (operands[0])))"
1135 [(set (match_dup 0) (match_dup 3))
1136 (set (match_dup 4) (match_dup 5))]
1140 rtx replacements[4];
1142 /* We want to replace occurrences of operands[0] with operands[1] and
1143 operands[2] with operands[0] in operands[4]/operands[5].
1144 Doing just two replace_rtx calls naively would result in the second
1145 replacement undoing all that the first did if operands[1] and operands[2]
1146 are identical, so we must do this simultaneously. */
1147 replacements[0] = operands[0];
1148 replacements[1] = operands[1];
1149 replacements[2] = operands[2];
1150 replacements[3] = operands[0];
1151 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1152 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1153 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1156 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1157 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1158 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1159 /* The operands array is aliased to recog_data.operand, which gets
1160 clobbered by extract_insn, so finish with it now. */
1161 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1162 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1163 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1164 always uses emit_insn. */
1165 /* Check that we don't violate matching constraints or earlyclobbers. */
1166 extract_insn (emit_insn (set1));
1167 if (! constrain_operands (1))
1169 extract_insn (emit (set2));
1170 if (! constrain_operands (1))
1174 tmp = replacements[0];
1175 replacements[0] = replacements[1];
1176 replacements[1] = tmp;
1177 tmp = replacements[2];
1178 replacements[2] = replacements[3];
1179 replacements[3] = tmp;
1180 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1181 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1182 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1188 ;; The register allocator is rather clumsy in handling multi-way conditional
1189 ;; moves, so allow the combiner to make them, and we split them up after
1191 (define_insn_and_split "*movsicc_umin"
1192 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1193 (umin:SI (if_then_else:SI
1194 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1196 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1197 (match_operand:SI 3 "register_operand" "0"))
1198 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1199 (clobber (match_scratch:SI 5 "=&r"))]
1200 "TARGET_SHMEDIA && no_new_pseudos"
1202 "TARGET_SHMEDIA && reload_completed"
1206 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1208 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1209 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1214 (define_insn "*movsicc_t_false"
1215 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1216 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1217 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1218 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1219 "TARGET_PRETEND_CMOVE
1220 && (arith_reg_operand (operands[1], SImode)
1221 || (immediate_operand (operands[1], SImode)
1222 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1223 "bt 0f\;mov %1,%0\\n0:"
1224 [(set_attr "type" "mt_group,arith") ;; poor approximation
1225 (set_attr "length" "4")])
1227 (define_insn "*movsicc_t_true"
1228 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1229 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1230 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1231 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1232 "TARGET_PRETEND_CMOVE
1233 && (arith_reg_operand (operands[1], SImode)
1234 || (immediate_operand (operands[1], SImode)
1235 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1236 "bf 0f\;mov %1,%0\\n0:"
1237 [(set_attr "type" "mt_group,arith") ;; poor approximation
1238 (set_attr "length" "4")])
1240 (define_expand "movsicc"
1241 [(set (match_operand:SI 0 "arith_reg_dest" "")
1242 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1243 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1244 (match_operand:SI 3 "arith_reg_operand" "")))]
1245 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1248 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1249 && GET_MODE (sh_compare_op0) == SImode
1251 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1252 && sh_compare_op1 == const0_rtx)
1253 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1254 sh_compare_op0, sh_compare_op1);
1255 else if (TARGET_PRETEND_CMOVE)
1257 enum rtx_code code = GET_CODE (operands[1]);
1258 enum rtx_code new_code = code;
1261 if (! currently_expanding_to_rtl)
1265 case LT: case LE: case LEU: case LTU:
1266 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1269 new_code = reverse_condition (code);
1271 case EQ: case GT: case GE: case GEU: case GTU:
1276 tmp = prepare_scc_operands (new_code);
1277 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1287 tmp = gen_reg_rtx (SImode);
1289 switch (GET_CODE (operands[1]))
1292 emit_insn (gen_seq (tmp));
1293 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1297 emit_insn (gen_seq (tmp));
1298 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1302 emit_insn (gen_sgt (tmp));
1303 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1307 emit_insn (gen_slt (tmp));
1308 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1312 emit_insn (gen_slt (tmp));
1313 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1317 emit_insn (gen_sgt (tmp));
1318 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1322 emit_insn (gen_sgtu (tmp));
1323 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1327 emit_insn (gen_sltu (tmp));
1328 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1332 emit_insn (gen_sltu (tmp));
1333 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1337 emit_insn (gen_sgtu (tmp));
1338 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1342 emit_insn (gen_sunordered (tmp));
1343 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1347 emit_insn (gen_sunordered (tmp));
1348 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1365 (define_expand "movqicc"
1366 [(set (match_operand:QI 0 "register_operand" "")
1367 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1368 (match_operand:QI 2 "register_operand" "")
1369 (match_operand:QI 3 "register_operand" "")))]
1373 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1374 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1375 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1376 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1380 ;; -------------------------------------------------------------------------
1381 ;; Addition instructions
1382 ;; -------------------------------------------------------------------------
1384 (define_expand "adddi3"
1385 [(set (match_operand:DI 0 "arith_reg_operand" "")
1386 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1387 (match_operand:DI 2 "arith_operand" "")))]
1393 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1395 operands[2] = force_reg (DImode, operands[2]);
1396 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1401 (define_insn "*adddi3_media"
1402 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1403 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1404 (match_operand:DI 2 "arith_operand" "r,I10")))]
1409 [(set_attr "type" "arith_media")])
1411 (define_insn "*adddisi3_media"
1412 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1413 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1414 (match_operand:DI 2 "arith_operand" "r,I10")))]
1419 [(set_attr "type" "arith_media")
1420 (set_attr "highpart" "ignore")])
1422 (define_insn "adddi3z_media"
1423 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1425 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1426 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1428 "addz.l %1, %N2, %0"
1429 [(set_attr "type" "arith_media")
1430 (set_attr "highpart" "ignore")])
1432 (define_insn "adddi3_compact"
1433 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1434 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1435 (match_operand:DI 2 "arith_reg_operand" "r")))
1436 (clobber (reg:SI T_REG))]
1439 [(set_attr "length" "6")])
1442 [(set (match_operand:DI 0 "arith_reg_dest" "")
1443 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1444 (match_operand:DI 2 "arith_reg_operand" "")))
1445 (clobber (reg:SI T_REG))]
1446 "TARGET_SH1 && reload_completed"
1450 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1451 high0 = gen_rtx_REG (SImode,
1452 true_regnum (operands[0])
1453 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1454 high2 = gen_rtx_REG (SImode,
1455 true_regnum (operands[2])
1456 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1457 emit_insn (gen_clrt ());
1458 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1459 emit_insn (gen_addc1 (high0, high0, high2));
1464 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1465 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1466 (match_operand:SI 2 "arith_reg_operand" "r"))
1469 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1472 [(set_attr "type" "arith")])
1474 (define_insn "addc1"
1475 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1476 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1477 (match_operand:SI 2 "arith_reg_operand" "r"))
1479 (clobber (reg:SI T_REG))]
1482 [(set_attr "type" "arith")])
1484 (define_expand "addsi3"
1485 [(set (match_operand:SI 0 "arith_reg_operand" "")
1486 (plus:SI (match_operand:SI 1 "arith_operand" "")
1487 (match_operand:SI 2 "arith_operand" "")))]
1492 operands[1] = force_reg (SImode, operands[1]);
1495 (define_insn "addsi3_media"
1496 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1497 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1498 (match_operand:SI 2 "arith_operand" "r,I10")))]
1503 [(set_attr "type" "arith_media")
1504 (set_attr "highpart" "ignore")])
1506 (define_insn "addsidi3_media"
1507 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1508 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1510 (match_operand:SI 2 "arith_operand"
1516 [(set_attr "type" "arith_media")
1517 (set_attr "highpart" "ignore")])
1519 (define_insn "*addsi3_compact"
1520 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1521 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1522 (match_operand:SI 2 "arith_operand" "rI08")))]
1525 [(set_attr "type" "arith")])
1527 ;; -------------------------------------------------------------------------
1528 ;; Subtraction instructions
1529 ;; -------------------------------------------------------------------------
1531 (define_expand "subdi3"
1532 [(set (match_operand:DI 0 "arith_reg_operand" "")
1533 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1534 (match_operand:DI 2 "arith_reg_operand" "")))]
1540 operands[1] = force_reg (DImode, operands[1]);
1541 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1546 (define_insn "*subdi3_media"
1547 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1548 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1549 (match_operand:DI 2 "arith_reg_operand" "r")))]
1552 [(set_attr "type" "arith_media")])
1554 (define_insn "subdisi3_media"
1555 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1556 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1557 (match_operand:DI 2 "arith_reg_operand" "r")))]
1560 [(set_attr "type" "arith_media")
1561 (set_attr "highpart" "ignore")])
1563 (define_insn "subdi3_compact"
1564 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1565 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1566 (match_operand:DI 2 "arith_reg_operand" "r")))
1567 (clobber (reg:SI T_REG))]
1570 [(set_attr "length" "6")])
1573 [(set (match_operand:DI 0 "arith_reg_dest" "")
1574 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1575 (match_operand:DI 2 "arith_reg_operand" "")))
1576 (clobber (reg:SI T_REG))]
1577 "TARGET_SH1 && reload_completed"
1581 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1582 high0 = gen_rtx_REG (SImode,
1583 true_regnum (operands[0])
1584 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1585 high2 = gen_rtx_REG (SImode,
1586 true_regnum (operands[2])
1587 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1588 emit_insn (gen_clrt ());
1589 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1590 emit_insn (gen_subc1 (high0, high0, high2));
1595 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1596 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1597 (match_operand:SI 2 "arith_reg_operand" "r"))
1600 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1605 [(set_attr "type" "arith")])
1607 (define_insn "subc1"
1608 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1609 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1610 (match_operand:SI 2 "arith_reg_operand" "r"))
1612 (clobber (reg:SI T_REG))]
1615 [(set_attr "type" "arith")])
1617 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1618 ;; pattern for this case. This helps multimedia applications that compute
1619 ;; the sum of absolute differences.
1620 (define_insn "mov_neg_si_t"
1621 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1624 [(set_attr "type" "arith")])
1626 (define_insn "*subsi3_internal"
1627 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1628 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1629 (match_operand:SI 2 "arith_reg_operand" "r")))]
1632 [(set_attr "type" "arith")])
1634 (define_insn_and_split "*subsi3_media"
1635 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1636 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1637 (match_operand:SI 2 "extend_reg_operand" "r")))]
1639 && (operands[1] != constm1_rtx
1640 || (GET_CODE (operands[2]) != TRUNCATE
1641 && GET_CODE (operands[2]) != SUBREG))"
1643 "operands[1] == constm1_rtx"
1644 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1646 [(set_attr "type" "arith_media")
1647 (set_attr "highpart" "ignore")])
1650 [(set (match_operand:SI 0 "arith_reg_dest" "")
1651 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1652 "general_extend_operand"
1654 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1655 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1656 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1660 [(set (match_operand:SI 0 "arith_reg_dest" "")
1661 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1662 "general_extend_operand"
1664 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1665 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1666 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1668 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1669 ;; will sometimes save one instruction. Otherwise we might get
1670 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1673 (define_expand "subsi3"
1674 [(set (match_operand:SI 0 "arith_reg_operand" "")
1675 (minus:SI (match_operand:SI 1 "arith_operand" "")
1676 (match_operand:SI 2 "arith_reg_operand" "")))]
1680 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1682 emit_insn (gen_negsi2 (operands[0], operands[2]));
1683 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1688 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1690 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1691 operands[1] = force_reg (SImode, operands[1]);
1695 ;; -------------------------------------------------------------------------
1696 ;; Division instructions
1697 ;; -------------------------------------------------------------------------
1699 ;; We take advantage of the library routines which don't clobber as many
1700 ;; registers as a normal function call would.
1702 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1703 ;; also has an effect on the register that holds the address of the sfunc.
1704 ;; To make this work, we have an extra dummy insn that shows the use
1705 ;; of this register for reorg.
1707 (define_insn "use_sfunc_addr"
1708 [(set (reg:SI PR_REG)
1709 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1710 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1712 [(set_attr "length" "0")])
1714 (define_insn "udivsi3_sh2a"
1715 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1716 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1717 (match_operand:SI 2 "arith_reg_operand" "z")))]
1720 [(set_attr "type" "arith")
1721 (set_attr "in_delay_slot" "no")])
1723 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1724 ;; hard register 0. If we used hard register 0, then the next instruction
1725 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1726 ;; gets allocated to a stack slot that needs its address reloaded, then
1727 ;; there is nothing to prevent reload from using r0 to reload the address.
1728 ;; This reload would clobber the value in r0 we are trying to store.
1729 ;; If we let reload allocate r0, then this problem can never happen.
1731 (define_insn "udivsi3_i1"
1732 [(set (match_operand:SI 0 "register_operand" "=z")
1733 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1734 (clobber (reg:SI T_REG))
1735 (clobber (reg:SI PR_REG))
1736 (clobber (reg:SI R4_REG))
1737 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1738 "TARGET_SH1 && ! TARGET_SH4"
1740 [(set_attr "type" "sfunc")
1741 (set_attr "needs_delay_slot" "yes")])
1743 ; Since shmedia-nofpu code could be linked against shcompact code, and
1744 ; the udivsi3 libcall has the same name, we must consider all registers
1745 ; clobbered that are in the union of the registers clobbered by the
1746 ; shmedia and the shcompact implementation. Note, if the shcompact
1747 ; implementation actually used shcompact code, we'd need to clobber
1748 ; also r23 and fr23.
1749 (define_insn "udivsi3_i1_media"
1750 [(set (match_operand:SI 0 "register_operand" "=z")
1751 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1752 (clobber (reg:SI T_MEDIA_REG))
1753 (clobber (reg:SI PR_MEDIA_REG))
1754 (clobber (reg:SI R20_REG))
1755 (clobber (reg:SI R21_REG))
1756 (clobber (reg:SI R22_REG))
1757 (clobber (reg:DI TR0_REG))
1758 (clobber (reg:DI TR1_REG))
1759 (clobber (reg:DI TR2_REG))
1760 (use (match_operand 1 "target_operand" "b"))]
1761 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1763 [(set_attr "type" "sfunc")
1764 (set_attr "needs_delay_slot" "yes")])
1766 (define_expand "udivsi3_i4_media"
1768 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1770 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1771 (set (match_dup 5) (float:DF (match_dup 3)))
1772 (set (match_dup 6) (float:DF (match_dup 4)))
1773 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1774 (set (match_dup 8) (fix:DI (match_dup 7)))
1775 (set (match_operand:SI 0 "register_operand" "")
1776 (truncate:SI (match_dup 8)))]
1777 "TARGET_SHMEDIA_FPU"
1780 operands[3] = gen_reg_rtx (DImode);
1781 operands[4] = gen_reg_rtx (DImode);
1782 operands[5] = gen_reg_rtx (DFmode);
1783 operands[6] = gen_reg_rtx (DFmode);
1784 operands[7] = gen_reg_rtx (DFmode);
1785 operands[8] = gen_reg_rtx (DImode);
1788 (define_insn "udivsi3_i4"
1789 [(set (match_operand:SI 0 "register_operand" "=y")
1790 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1791 (clobber (reg:SI T_REG))
1792 (clobber (reg:SI PR_REG))
1793 (clobber (reg:DF DR0_REG))
1794 (clobber (reg:DF DR2_REG))
1795 (clobber (reg:DF DR4_REG))
1796 (clobber (reg:SI R0_REG))
1797 (clobber (reg:SI R1_REG))
1798 (clobber (reg:SI R4_REG))
1799 (clobber (reg:SI R5_REG))
1800 (use (reg:PSI FPSCR_REG))
1801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1802 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1804 [(set_attr "type" "sfunc")
1805 (set_attr "fp_mode" "double")
1806 (set_attr "needs_delay_slot" "yes")])
1808 (define_insn "udivsi3_i4_single"
1809 [(set (match_operand:SI 0 "register_operand" "=y")
1810 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1811 (clobber (reg:SI T_REG))
1812 (clobber (reg:SI PR_REG))
1813 (clobber (reg:DF DR0_REG))
1814 (clobber (reg:DF DR2_REG))
1815 (clobber (reg:DF DR4_REG))
1816 (clobber (reg:SI R0_REG))
1817 (clobber (reg:SI R1_REG))
1818 (clobber (reg:SI R4_REG))
1819 (clobber (reg:SI R5_REG))
1820 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1821 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1823 [(set_attr "type" "sfunc")
1824 (set_attr "needs_delay_slot" "yes")])
1826 (define_insn "udivsi3_i4_int"
1827 [(set (match_operand:SI 0 "register_operand" "=z")
1828 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829 (clobber (reg:SI T_REG))
1830 (clobber (reg:SI R1_REG))
1831 (clobber (reg:SI PR_REG))
1832 (clobber (reg:SI MACH_REG))
1833 (clobber (reg:SI MACL_REG))
1834 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1837 [(set_attr "type" "sfunc")
1838 (set_attr "needs_delay_slot" "yes")])
1841 (define_expand "udivsi3"
1842 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1843 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1844 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1845 (parallel [(set (match_operand:SI 0 "register_operand" "")
1846 (udiv:SI (reg:SI R4_REG)
1848 (clobber (reg:SI T_REG))
1849 (clobber (reg:SI PR_REG))
1850 (clobber (reg:SI R4_REG))
1851 (use (match_dup 3))])]
1857 operands[3] = gen_reg_rtx (Pmode);
1858 /* Emit the move of the address to a pseudo outside of the libcall. */
1859 if (TARGET_DIVIDE_CALL_TABLE)
1861 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1862 that causes problems when the divide code is supposed to come from a
1863 separate library. Division by zero is undefined, so dividing 1 can be
1864 implemented by comparing with the divisor. */
1865 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1867 emit_insn (gen_cmpsi (operands[1], operands[2]));
1868 emit_insn (gen_sgeu (operands[0]));
1871 else if (operands[2] == const0_rtx)
1873 emit_move_insn (operands[0], operands[2]);
1876 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1877 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1879 else if (TARGET_DIVIDE_CALL_FP)
1881 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1882 if (TARGET_FPU_SINGLE)
1883 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1885 last = gen_udivsi3_i4 (operands[0], operands[3]);
1887 else if (TARGET_SHMEDIA_FPU)
1889 operands[1] = force_reg (SImode, operands[1]);
1890 operands[2] = force_reg (SImode, operands[2]);
1891 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1894 else if (TARGET_SH2A)
1896 operands[1] = force_reg (SImode, operands[1]);
1897 operands[2] = force_reg (SImode, operands[2]);
1898 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1901 else if (TARGET_SH5)
1903 function_symbol (operands[3],
1904 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1908 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1909 else if (TARGET_FPU_ANY)
1910 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1912 last = gen_udivsi3_i1 (operands[0], operands[3]);
1916 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1917 last = gen_udivsi3_i1 (operands[0], operands[3]);
1919 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1920 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1921 last = emit_insn (last);
1922 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1923 invariant code motion can move it. */
1924 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1925 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1929 (define_insn "divsi3_sh2a"
1930 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1931 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1932 (match_operand:SI 2 "arith_reg_operand" "z")))]
1935 [(set_attr "type" "arith")
1936 (set_attr "in_delay_slot" "no")])
1938 (define_insn "divsi3_i1"
1939 [(set (match_operand:SI 0 "register_operand" "=z")
1940 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1941 (clobber (reg:SI T_REG))
1942 (clobber (reg:SI PR_REG))
1943 (clobber (reg:SI R1_REG))
1944 (clobber (reg:SI R2_REG))
1945 (clobber (reg:SI R3_REG))
1946 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1947 "TARGET_SH1 && ! TARGET_SH4"
1949 [(set_attr "type" "sfunc")
1950 (set_attr "needs_delay_slot" "yes")])
1952 (define_insn "divsi3_i1_media"
1953 [(set (match_operand:SI 0 "register_operand" "=z")
1954 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1955 (clobber (reg:SI T_MEDIA_REG))
1956 (clobber (reg:SI PR_MEDIA_REG))
1957 (clobber (reg:SI R1_REG))
1958 (clobber (reg:SI R20_REG))
1959 (clobber (reg:SI R21_REG))
1960 (clobber (reg:SI TR0_REG))
1961 (use (match_operand 1 "target_operand" "b"))]
1962 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1964 [(set_attr "type" "sfunc")])
1966 (define_insn "divsi3_media_2"
1967 [(set (match_operand:SI 0 "register_operand" "=z")
1968 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1969 (clobber (reg:SI T_MEDIA_REG))
1970 (clobber (reg:SI PR_MEDIA_REG))
1971 (clobber (reg:SI R1_REG))
1972 (clobber (reg:SI R21_REG))
1973 (clobber (reg:SI TR0_REG))
1974 (use (reg:SI R20_REG))
1975 (use (match_operand 1 "target_operand" "b"))]
1976 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1978 [(set_attr "type" "sfunc")])
1980 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1981 ;; hard reg clobbers and data dependencies that we need when we want
1982 ;; to rematerialize the division into a call.
1983 (define_insn_and_split "divsi_inv_call"
1984 [(set (match_operand:SI 0 "register_operand" "=r")
1985 (div:SI (match_operand:SI 1 "register_operand" "r")
1986 (match_operand:SI 2 "register_operand" "r")))
1987 (clobber (reg:SI R4_REG))
1988 (clobber (reg:SI R5_REG))
1989 (clobber (reg:SI T_MEDIA_REG))
1990 (clobber (reg:SI PR_MEDIA_REG))
1991 (clobber (reg:SI R1_REG))
1992 (clobber (reg:SI R21_REG))
1993 (clobber (reg:SI TR0_REG))
1994 (clobber (reg:SI R20_REG))
1995 (use (match_operand:SI 3 "register_operand" "r"))]
1998 "&& (high_life_started || reload_completed)"
1999 [(set (match_dup 0) (match_dup 3))]
2001 [(set_attr "highpart" "must_split")])
2003 ;; This is the combiner pattern for -mdiv=inv:call .
2004 (define_insn_and_split "*divsi_inv_call_combine"
2005 [(set (match_operand:SI 0 "register_operand" "=z")
2006 (div:SI (match_operand:SI 1 "register_operand" "r")
2007 (match_operand:SI 2 "register_operand" "r")))
2008 (clobber (reg:SI R4_REG))
2009 (clobber (reg:SI R5_REG))
2010 (clobber (reg:SI T_MEDIA_REG))
2011 (clobber (reg:SI PR_MEDIA_REG))
2012 (clobber (reg:SI R1_REG))
2013 (clobber (reg:SI R21_REG))
2014 (clobber (reg:SI TR0_REG))
2015 (clobber (reg:SI R20_REG))
2016 (use (unspec:SI [(match_dup 1)
2017 (match_operand:SI 3 "" "")
2018 (unspec:SI [(match_operand:SI 4 "" "")
2020 (match_operand:DI 5 "" "")]
2022 (match_operand:DI 6 "" "")
2025 UNSPEC_DIV_INV_M3))]
2028 "&& (high_life_started || reload_completed)"
2032 const char *name = sh_divsi3_libfunc;
2033 enum sh_function_kind kind = SFUNC_GOT;
2036 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2037 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2038 while (TARGET_DIVIDE_INV_CALL2)
2040 rtx x = operands[3];
2042 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2044 x = XVECEXP (x, 0, 0);
2045 name = \"__sdivsi3_2\";
2046 kind = SFUNC_STATIC;
2047 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2050 sym = function_symbol (NULL, name, kind);
2051 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2054 [(set_attr "highpart" "must_split")])
2056 (define_expand "divsi3_i4_media"
2057 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2058 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2059 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2060 (set (match_operand:SI 0 "register_operand" "=r")
2061 (fix:SI (match_dup 5)))]
2062 "TARGET_SHMEDIA_FPU"
2065 operands[3] = gen_reg_rtx (DFmode);
2066 operands[4] = gen_reg_rtx (DFmode);
2067 operands[5] = gen_reg_rtx (DFmode);
2070 (define_insn "divsi3_i4"
2071 [(set (match_operand:SI 0 "register_operand" "=y")
2072 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2073 (clobber (reg:SI PR_REG))
2074 (clobber (reg:DF DR0_REG))
2075 (clobber (reg:DF DR2_REG))
2076 (use (reg:PSI FPSCR_REG))
2077 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2078 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2080 [(set_attr "type" "sfunc")
2081 (set_attr "fp_mode" "double")
2082 (set_attr "needs_delay_slot" "yes")])
2084 (define_insn "divsi3_i4_single"
2085 [(set (match_operand:SI 0 "register_operand" "=y")
2086 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2087 (clobber (reg:SI PR_REG))
2088 (clobber (reg:DF DR0_REG))
2089 (clobber (reg:DF DR2_REG))
2090 (clobber (reg:SI R2_REG))
2091 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2092 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2094 [(set_attr "type" "sfunc")
2095 (set_attr "needs_delay_slot" "yes")])
2097 (define_insn "divsi3_i4_int"
2098 [(set (match_operand:SI 0 "register_operand" "=z")
2099 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2100 (clobber (reg:SI T_REG))
2101 (clobber (reg:SI PR_REG))
2102 (clobber (reg:SI R1_REG))
2103 (clobber (reg:SI MACH_REG))
2104 (clobber (reg:SI MACL_REG))
2105 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2108 [(set_attr "type" "sfunc")
2109 (set_attr "needs_delay_slot" "yes")])
2111 (define_expand "divsi3"
2112 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2113 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2114 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2115 (parallel [(set (match_operand:SI 0 "register_operand" "")
2116 (div:SI (reg:SI R4_REG)
2118 (clobber (reg:SI T_REG))
2119 (clobber (reg:SI PR_REG))
2120 (clobber (reg:SI R1_REG))
2121 (clobber (reg:SI R2_REG))
2122 (clobber (reg:SI R3_REG))
2123 (use (match_dup 3))])]
2129 operands[3] = gen_reg_rtx (Pmode);
2130 /* Emit the move of the address to a pseudo outside of the libcall. */
2131 if (TARGET_DIVIDE_CALL_TABLE)
2133 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2134 last = gen_divsi3_i4_int (operands[0], operands[3]);
2136 else if (TARGET_DIVIDE_CALL_FP)
2138 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2139 if (TARGET_FPU_SINGLE)
2140 last = gen_divsi3_i4_single (operands[0], operands[3]);
2142 last = gen_divsi3_i4 (operands[0], operands[3]);
2144 else if (TARGET_SH2A)
2146 operands[1] = force_reg (SImode, operands[1]);
2147 operands[2] = force_reg (SImode, operands[2]);
2148 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2151 else if (TARGET_DIVIDE_INV)
2153 rtx dividend = operands[1];
2154 rtx divisor = operands[2];
2156 rtx nsb_res = gen_reg_rtx (DImode);
2157 rtx norm64 = gen_reg_rtx (DImode);
2158 rtx tab_ix = gen_reg_rtx (DImode);
2159 rtx norm32 = gen_reg_rtx (SImode);
2160 rtx i92 = force_reg (DImode, GEN_INT (92));
2161 rtx scratch0a = gen_reg_rtx (DImode);
2162 rtx scratch0b = gen_reg_rtx (DImode);
2163 rtx inv0 = gen_reg_rtx (SImode);
2164 rtx scratch1a = gen_reg_rtx (DImode);
2165 rtx scratch1b = gen_reg_rtx (DImode);
2166 rtx shift = gen_reg_rtx (DImode);
2168 rtx inv1 = gen_reg_rtx (SImode);
2169 rtx scratch2a = gen_reg_rtx (DImode);
2170 rtx scratch2b = gen_reg_rtx (SImode);
2171 rtx inv2 = gen_reg_rtx (SImode);
2172 rtx scratch3a = gen_reg_rtx (DImode);
2173 rtx scratch3b = gen_reg_rtx (DImode);
2174 rtx scratch3c = gen_reg_rtx (DImode);
2175 rtx scratch3d = gen_reg_rtx (SImode);
2176 rtx scratch3e = gen_reg_rtx (DImode);
2177 rtx result = gen_reg_rtx (SImode);
2179 if (! arith_reg_or_0_operand (dividend, SImode))
2180 dividend = force_reg (SImode, dividend);
2181 if (! arith_reg_operand (divisor, SImode))
2182 divisor = force_reg (SImode, divisor);
2183 if (flag_pic && Pmode != DImode)
2185 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2186 tab_base = gen_datalabel_ref (tab_base);
2187 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2191 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2192 tab_base = gen_datalabel_ref (tab_base);
2193 tab_base = force_reg (DImode, tab_base);
2195 if (TARGET_DIVIDE_INV20U)
2196 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2198 i2p27 = GEN_INT (0);
2199 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2200 i43 = force_reg (DImode, GEN_INT (43));
2203 emit_insn (gen_nsbdi (nsb_res,
2204 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2205 emit_insn (gen_ashldi3_media (norm64,
2206 gen_rtx_SUBREG (DImode, divisor, 0),
2208 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2209 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2210 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2211 inv0, scratch0a, scratch0b,
2212 scratch1a, scratch1b));
2213 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2214 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2216 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2218 scratch3a, scratch3b, scratch3c,
2219 scratch2a, scratch2b, scratch3d, scratch3e));
2220 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2221 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2222 else if (TARGET_DIVIDE_INV_FP)
2223 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2224 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2225 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2226 gen_reg_rtx (DFmode)));
2228 emit_move_insn (operands[0], result);
2231 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2233 operands[1] = force_reg (SImode, operands[1]);
2234 operands[2] = force_reg (SImode, operands[2]);
2235 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2238 else if (TARGET_SH5)
2240 if (TARGET_DIVIDE_CALL2)
2242 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2243 tab_base = gen_datalabel_ref (tab_base);
2244 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2246 if (TARGET_FPU_ANY && TARGET_SH1)
2247 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2248 else if (TARGET_DIVIDE_CALL2)
2249 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2251 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2254 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2255 (operands[0], operands[3]));
2256 else if (TARGET_FPU_ANY)
2257 last = gen_divsi3_i4_single (operands[0], operands[3]);
2259 last = gen_divsi3_i1 (operands[0], operands[3]);
2263 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2264 last = gen_divsi3_i1 (operands[0], operands[3]);
2266 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2267 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2268 last = emit_insn (last);
2269 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2270 invariant code motion can move it. */
2271 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2272 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload. See PR27117.
2281 (define_insn "divsi_inv_qitable"
2282 [(set (match_operand:DI 0 "register_operand" "=r")
2283 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284 (match_operand:DI 2 "register_operand" "r")]
2285 UNSPEC_DIV_INV_TABLE)))]
2289 [(set_attr "type" "load_media")
2290 (set_attr "highpart" "user")])
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296 (match_operand:DI 2 "register_operand" "r")]
2297 UNSPEC_DIV_INV_TABLE)))]
2301 [(set_attr "type" "load_media")
2302 (set_attr "highpart" "user")])
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307 [(set (match_operand:SI 0 "register_operand" "=r")
2308 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309 (match_operand:DI 2 "register_operand" "r")
2310 (match_operand:SI 3 "register_operand" "r")]
2312 (clobber (match_operand:DI 4 "register_operand" "=r"))
2313 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2321 ldx.ub r20, r21, r19 // u0.8
2323 muls.l r25, r19, r19 // s2.38
2324 ldx.w r20, r21, r21 // s2.14
2325 shari r19, 24, r19 // truncate to s2.14
2326 sub r21, r19, r19 // some 11 bit inverse in s1.14
2329 rtx inv0 = operands[0];
2330 rtx tab_base = operands[1];
2331 rtx tab_ix = operands[2];
2332 rtx norm32 = operands[3];
2333 rtx scratch0 = operands[4];
2334 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335 rtx scratch1 = operands[5];
2337 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348 [(set (match_operand:SI 0 "register_operand" "=r")
2349 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350 (match_operand:DI 2 "register_operand" "r")
2351 (match_operand:SI 3 "register_operand" "r")]
2353 (clobber (match_operand:SI 4 "register_operand" "=r"))
2354 (clobber (match_operand:DI 5 "register_operand" "=r"))
2355 (clobber (match_operand:DI 6 "register_operand" "=r"))
2356 (clobber (match_operand:DI 7 "register_operand" "=r"))
2357 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2365 muls.l r19, r19, r18 // u0.28
2366 muls.l r25, r18, r18 // s2.58
2367 shlli r19, 45, r0 // multiply by two and convert to s2.58
2369 shari r18, 28, r18 // some 18 bit inverse in s1.30
2372 rtx inv1 = operands[0];
2373 rtx tab_base = operands[1];
2374 rtx tab_ix = operands[2];
2375 rtx norm32 = operands[3];
2376 rtx inv0 = operands[4];
2377 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378 rtx scratch0a = operands[5];
2379 rtx scratch0b = operands[6];
2380 rtx scratch0 = operands[7];
2381 rtx scratch1 = operands[8];
2382 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2384 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385 scratch0a, scratch0b));
2386 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396 [(set (match_operand:SI 0 "register_operand" "=r")
2397 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398 (match_operand:SI 2 "register_operand" "r")
2399 (match_operand:DI 3 "register_operand" "r")]
2401 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2409 muls.l r18, r25, r0 // s2.60
2410 shari r0, 16, r0 // s-16.44
2412 muls.l r0, r18, r19 // s-16.74
2413 shari r19, 30, r19 // s-16.44
2415 rtx inv2 = operands[0];
2416 rtx norm32 = operands[1];
2417 rtx inv1 = operands[2];
2418 rtx i92 = operands[3];
2419 rtx scratch0 = operands[4];
2420 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2422 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2430 (define_insn_and_split "divsi_inv_m3"
2431 [(set (match_operand:SI 0 "register_operand" "=r")
2432 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433 (match_operand:SI 2 "register_operand" "r")
2434 (match_operand:SI 3 "register_operand" "r")
2435 (match_operand:DI 4 "register_operand" "r")
2436 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2439 (clobber (match_operand:DI 7 "register_operand" "=r"))
2440 (clobber (match_operand:DI 8 "register_operand" "=r"))
2441 (clobber (match_operand:DI 9 "register_operand" "=r"))
2442 (clobber (match_operand:DI 10 "register_operand" "=r"))
2443 (clobber (match_operand:SI 11 "register_operand" "=r"))
2444 (clobber (match_operand:SI 12 "register_operand" "=r"))
2445 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2453 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2454 r0: scratch0 r19: scratch1 r21: scratch2
2456 muls.l r18, r4, r25 // s32.30
2457 muls.l r19, r4, r19 // s15.30
2459 shari r19, 14, r19 // s18.-14
2465 rtx result = operands[0];
2466 rtx dividend = operands[1];
2467 rtx inv1 = operands[2];
2468 rtx inv2 = operands[3];
2469 rtx shift = operands[4];
2470 rtx scratch0 = operands[7];
2471 rtx scratch1 = operands[8];
2472 rtx scratch2 = operands[9];
2474 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488 [(set (match_operand:SI 0 "register_operand" "=r")
2489 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491 (match_operand:DI 3 "register_operand" "r")
2492 (match_operand:SI 4 "register_operand" "r")]
2494 (unspec:SI [(match_dup 4)
2495 (unspec:SI [(match_dup 2)
2497 (match_dup 4)] UNSPEC_DIV_INV_M1)
2498 (match_operand:SI 5 "" "")]
2500 (match_operand:DI 6 "register_operand" "r")
2501 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2504 (clobber (match_operand:DI 9 "register_operand" "=r"))
2505 (clobber (match_operand:DI 10 "register_operand" "=r"))
2506 (clobber (match_operand:DI 11 "register_operand" "=r"))
2507 (clobber (match_operand:DI 12 "register_operand" "=r"))
2508 (clobber (match_operand:SI 13 "register_operand" "=r"))
2509 (clobber (match_operand:SI 14 "register_operand" "=r"))
2510 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2512 && (TARGET_DIVIDE_INV_MINLAT
2513 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2519 rtx result = operands[0];
2520 rtx dividend = operands[1];
2521 rtx tab_base = operands[2];
2522 rtx tab_ix = operands[3];
2523 rtx norm32 = operands[4];
2524 /* rtx i92 = operands[5]; */
2525 rtx shift = operands[6];
2526 rtx i2p27 = operands[7];
2527 rtx i43 = operands[8];
2528 rtx scratch0 = operands[9];
2529 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530 rtx scratch1 = operands[10];
2531 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532 rtx scratch2 = operands[11];
2533 rtx scratch3 = operands[12];
2534 rtx scratch4 = operands[13];
2535 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536 rtx scratch5 = operands[14];
2537 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538 rtx scratch6 = operands[15];
2540 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541 scratch0, scratch1));
2542 /* inv0 == scratch4 */
2543 if (! TARGET_DIVIDE_INV20U)
2545 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2547 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2551 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2554 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557 /* inv1 == scratch4 */
2559 if (TARGET_DIVIDE_INV_MINLAT)
2561 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2575 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2577 emit_insn (gen_nsbdi (scratch6,
2578 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581 emit_insn (gen_divsi_inv20 (scratch2,
2582 norm32, scratch4, dividend,
2583 scratch6, scratch3, i43,
2584 /* scratch0 may be shared with i2p27. */
2585 scratch0, scratch1, scratch5,
2586 label, label, i2p27));
2588 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2593 (define_insn "divsi_inv20"
2594 [(set (match_operand:DI 0 "register_operand" "=&r")
2595 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596 (match_operand:SI 2 "register_operand" "r")
2597 (match_operand:SI 3 "register_operand" "r")
2598 (match_operand:DI 4 "register_operand" "r")
2599 (match_operand:DI 5 "register_operand" "r")
2600 (match_operand:DI 6 "register_operand" "r")
2601 (match_operand:DI 12 "register_operand" "r")
2602 (match_operand 10 "target_operand" "b")
2603 (match_operand 11 "immediate_operand" "i")]
2605 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2609 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615 %10 label (tr), %11 label (imm)
2617 muls.l inv1, norm32, scratch0 // s2.60
2618 muls.l inv1, dividend, result // s32.30
2619 xor i2p27, result_sign, round_scratch
2620 bge/u dividend_nsb, i43, tr.. (label)
2621 shari scratch0, 16, scratch0 // s-16.44
2622 muls.l sratch0_si, inv1, scratch0 // s-16.74
2623 sub result, round_scratch, result
2624 shari dividend, 14, scratch1 // s19.-14
2625 shari scratch0, 30, scratch0 // s-16.44
2626 muls.l scratch0, scratch1, round_scratch // s15.30
2628 sub result, round_scratch, result */
2630 int likely = TARGET_DIVIDE_INV20L;
2632 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634 output_asm_insn (likely
2635 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636 : \"bge/u\t%4, %6, %10\", operands);
2637 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2641 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2645 (define_insn_and_split "divsi_inv_fp"
2646 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648 (match_operand:SI 2 "register_operand" "rf")))
2649 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650 (clobber (match_operand:SI 4 "register_operand" "=r"))
2651 (clobber (match_operand:SI 5 "register_operand" "=r"))
2652 (clobber (match_operand:DF 6 "register_operand" "=r"))
2653 (clobber (match_operand:DF 7 "register_operand" "=r"))
2654 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655 "TARGET_SHMEDIA_FPU"
2657 "&& (high_life_started || reload_completed)"
2658 [(set (match_dup 0) (match_dup 3))]
2660 [(set_attr "highpart" "must_split")])
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666 [(set (match_operand:SI 0 "register_operand" "=f")
2667 (div:SI (match_operand:SI 1 "register_operand" "f")
2668 (match_operand:SI 2 "register_operand" "f")))
2669 (use (unspec:SI [(match_dup 1)
2670 (match_operand:SI 3 "" "")
2671 (unspec:SI [(match_operand:SI 4 "" "")
2673 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674 (match_operand:DI 6 "" "")
2676 (const_int 0)] UNSPEC_DIV_INV_M3))
2677 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2685 [(set (match_dup 9) (float:DF (match_dup 1)))
2686 (set (match_dup 10) (float:DF (match_dup 2)))
2687 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2689 (fix:SI (match_dup 11)))
2690 (set (match_dup 0) (match_dup 8))]
2693 if (! fp_arith_reg_operand (operands[1], SImode))
2695 emit_move_insn (operands[7], operands[1]);
2696 operands[1] = operands[7];
2698 if (! fp_arith_reg_operand (operands[2], SImode))
2700 emit_move_insn (operands[8], operands[2]);
2701 operands[2] = operands[8];
2704 [(set_attr "highpart" "must_split")])
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2710 (define_insn "umulhisi3_i"
2711 [(set (reg:SI MACL_REG)
2712 (mult:SI (zero_extend:SI
2713 (match_operand:HI 0 "arith_reg_operand" "r"))
2715 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2718 [(set_attr "type" "smpy")])
2720 (define_insn "mulhisi3_i"
2721 [(set (reg:SI MACL_REG)
2722 (mult:SI (sign_extend:SI
2723 (match_operand:HI 0 "arith_reg_operand" "r"))
2725 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2728 [(set_attr "type" "smpy")])
2730 (define_expand "mulhisi3"
2731 [(set (reg:SI MACL_REG)
2732 (mult:SI (sign_extend:SI
2733 (match_operand:HI 1 "arith_reg_operand" ""))
2735 (match_operand:HI 2 "arith_reg_operand" ""))))
2736 (set (match_operand:SI 0 "arith_reg_operand" "")
2743 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2744 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2745 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2746 invariant code motion can move it. */
2747 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2748 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2749 /* expand_binop can't find a suitable code in umul_widen_optab to
2750 make a REG_EQUAL note from, so make one here.
2751 See also smulsi3_highpart.
2752 ??? Alternatively, we could put this at the calling site of expand_binop,
2753 i.e. expand_expr. */
2754 set_unique_reg_note (last, REG_EQUAL,
2755 copy_rtx (SET_SRC (single_set (first))));
2760 (define_expand "umulhisi3"
2761 [(set (reg:SI MACL_REG)
2762 (mult:SI (zero_extend:SI
2763 (match_operand:HI 1 "arith_reg_operand" ""))
2765 (match_operand:HI 2 "arith_reg_operand" ""))))
2766 (set (match_operand:SI 0 "arith_reg_operand" "")
2773 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2774 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2775 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2776 invariant code motion can move it. */
2777 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2778 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2779 /* expand_binop can't find a suitable code in umul_widen_optab to
2780 make a REG_EQUAL note from, so make one here.
2781 See also smulsi3_highpart.
2782 ??? Alternatively, we could put this at the calling site of expand_binop,
2783 i.e. expand_expr. */
2784 set_unique_reg_note (last, REG_EQUAL,
2785 copy_rtx (SET_SRC (single_set (first))));
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2794 [(set (match_operand:SI 1 "register_operand" "=z")
2795 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796 (clobber (reg:SI MACL_REG))
2797 (clobber (reg:SI T_REG))
2798 (clobber (reg:SI PR_REG))
2799 (clobber (reg:SI R3_REG))
2800 (clobber (reg:SI R2_REG))
2801 (clobber (reg:SI R1_REG))
2802 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2805 [(set_attr "type" "sfunc")
2806 (set_attr "needs_delay_slot" "yes")])
2808 (define_expand "mulsi3_call"
2809 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811 (parallel[(set (match_operand:SI 0 "register_operand" "")
2812 (mult:SI (reg:SI R4_REG)
2814 (clobber (reg:SI MACL_REG))
2815 (clobber (reg:SI T_REG))
2816 (clobber (reg:SI PR_REG))
2817 (clobber (reg:SI R3_REG))
2818 (clobber (reg:SI R2_REG))
2819 (clobber (reg:SI R1_REG))
2820 (use (match_operand:SI 3 "register_operand" ""))])]
2824 (define_insn "mul_r"
2825 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827 (match_operand:SI 2 "arith_reg_operand" "z")))]
2830 [(set_attr "type" "dmpy")])
2832 (define_insn "mul_l"
2833 [(set (reg:SI MACL_REG)
2834 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835 (match_operand:SI 1 "arith_reg_operand" "r")))]
2838 [(set_attr "type" "dmpy")])
2840 (define_expand "mulsi3"
2841 [(set (reg:SI MACL_REG)
2842 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2843 (match_operand:SI 2 "arith_reg_operand" "")))
2844 (set (match_operand:SI 0 "arith_reg_operand" "")
2853 /* The address must be set outside the libcall,
2854 since it goes into a pseudo. */
2855 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2856 rtx addr = force_reg (SImode, sym);
2857 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2860 last = emit_insn (insns);
2864 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2866 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2867 /* consec_sets_giv can only recognize the first insn that sets a
2868 giv as the giv insn. So we must tag this also with a REG_EQUAL
2870 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2872 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2873 invariant code motion can move it. */
2874 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2875 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2879 (define_insn "mulsidi3_i"
2880 [(set (reg:SI MACH_REG)
2884 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2885 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2887 (set (reg:SI MACL_REG)
2888 (mult:SI (match_dup 0)
2892 [(set_attr "type" "dmpy")])
2894 (define_expand "mulsidi3"
2895 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2896 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2897 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2898 "TARGET_SH2 || TARGET_SHMEDIA"
2903 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2909 (define_insn "mulsidi3_media"
2910 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2911 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2912 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2915 [(set_attr "type" "dmpy_media")
2916 (set_attr "highpart" "ignore")])
2918 (define_insn "mulsidi3_compact"
2919 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2921 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2922 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2923 (clobber (reg:SI MACH_REG))
2924 (clobber (reg:SI MACL_REG))]
2929 [(set (match_operand:DI 0 "arith_reg_dest" "")
2931 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2932 (sign_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_mulsidi3_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 "umulsidi3_i"
2952 [(set (reg:SI MACH_REG)
2956 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2957 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2959 (set (reg:SI MACL_REG)
2960 (mult:SI (match_dup 0)
2964 [(set_attr "type" "dmpy")])
2966 (define_expand "umulsidi3"
2967 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2968 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2969 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2970 "TARGET_SH2 || TARGET_SHMEDIA"
2975 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2981 (define_insn "umulsidi3_media"
2982 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2983 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2984 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2987 [(set_attr "type" "dmpy_media")
2988 (set_attr "highpart" "ignore")])
2990 (define_insn "umulsidi3_compact"
2991 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2993 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2994 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2995 (clobber (reg:SI MACH_REG))
2996 (clobber (reg:SI MACL_REG))]
3001 [(set (match_operand:DI 0 "arith_reg_dest" "")
3002 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3003 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3004 (clobber (reg:SI MACH_REG))
3005 (clobber (reg:SI MACL_REG))]
3010 rtx low_dst = gen_lowpart (SImode, operands[0]);
3011 rtx high_dst = gen_highpart (SImode, operands[0]);
3013 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3015 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3016 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3017 /* We need something to tag the possible REG_EQUAL notes on to. */
3018 emit_move_insn (operands[0], operands[0]);
3022 (define_insn "smulsi3_highpart_i"
3023 [(set (reg:SI MACH_REG)
3027 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3028 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3030 (clobber (reg:SI MACL_REG))]
3033 [(set_attr "type" "dmpy")])
3035 (define_expand "smulsi3_highpart"
3037 [(set (reg:SI MACH_REG)
3041 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3042 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3044 (clobber (reg:SI MACL_REG))])
3045 (set (match_operand:SI 0 "arith_reg_operand" "")
3052 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3053 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3054 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3055 invariant code motion can move it. */
3056 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3057 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3058 /* expand_binop can't find a suitable code in mul_highpart_optab to
3059 make a REG_EQUAL note from, so make one here.
3060 See also {,u}mulhisi.
3061 ??? Alternatively, we could put this at the calling site of expand_binop,
3062 i.e. expand_mult_highpart. */
3063 set_unique_reg_note (last, REG_EQUAL,
3064 copy_rtx (SET_SRC (single_set (first))));
3069 (define_insn "umulsi3_highpart_i"
3070 [(set (reg:SI MACH_REG)
3074 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3075 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3077 (clobber (reg:SI MACL_REG))]
3080 [(set_attr "type" "dmpy")])
3082 (define_expand "umulsi3_highpart"
3084 [(set (reg:SI MACH_REG)
3088 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3089 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3091 (clobber (reg:SI MACL_REG))])
3092 (set (match_operand:SI 0 "arith_reg_operand" "")
3099 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3100 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3101 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3102 invariant code motion can move it. */
3103 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3104 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3108 (define_insn_and_split "muldi3"
3109 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3110 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3111 (match_operand:DI 2 "arith_reg_operand" "r")))
3112 (clobber (match_scratch:DI 3 "=&r"))
3113 (clobber (match_scratch:DI 4 "=r"))]
3120 rtx op3_v2si, op2_v2si;
3122 op3_v2si = operands[3];
3123 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3125 op3_v2si = XEXP (op3_v2si, 0);
3126 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3128 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3129 op2_v2si = operands[2];
3130 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3132 op2_v2si = XEXP (op2_v2si, 0);
3133 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3135 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3136 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3137 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3138 emit_insn (gen_umulsidi3_media (operands[4],
3139 sh_gen_truncate (SImode, operands[1], 0),
3140 sh_gen_truncate (SImode, operands[2], 0)));
3141 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3142 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3143 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3144 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3149 ;; -------------------------------------------------------------------------
3150 ;; Logical operations
3151 ;; -------------------------------------------------------------------------
3153 (define_insn "*andsi3_compact"
3154 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3155 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3156 (match_operand:SI 2 "logical_operand" "r,K08")))]
3159 [(set_attr "type" "arith")])
3161 (define_insn "*andsi3_media"
3162 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3163 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3164 (match_operand:SI 2 "logical_operand" "r,I10")))]
3169 [(set_attr "type" "arith_media")])
3171 ;; If the constant is 255, then emit an extu.b instruction instead of an
3172 ;; and, since that will give better code.
3174 (define_expand "andsi3"
3175 [(set (match_operand:SI 0 "arith_reg_operand" "")
3176 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3177 (match_operand:SI 2 "logical_operand" "")))]
3182 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3184 emit_insn (gen_zero_extendqisi2 (operands[0],
3185 gen_lowpart (QImode, operands[1])));
3190 (define_insn_and_split "anddi3"
3191 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3192 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3193 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3200 && ! logical_operand (operands[2], DImode)"
3204 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3205 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3207 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3210 [(set_attr "type" "arith_media")])
3212 (define_insn "andcsi3"
3213 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3214 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3215 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3218 [(set_attr "type" "arith_media")])
3220 (define_insn "andcdi3"
3221 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3222 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3223 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3226 [(set_attr "type" "arith_media")])
3228 (define_expand "iorsi3"
3229 [(set (match_operand:SI 0 "arith_reg_operand" "")
3230 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3231 (match_operand:SI 2 "logical_operand" "")))]
3235 (define_insn "*iorsi3_compact"
3236 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3237 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3238 (match_operand:SI 2 "logical_operand" "r,K08")))]
3241 [(set_attr "type" "arith")])
3243 (define_insn "*iorsi3_media"
3244 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3245 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3246 (match_operand:SI 2 "logical_operand" "r,I10")))]
3251 [(set_attr "type" "arith_media")])
3253 (define_insn "iordi3"
3254 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3255 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3256 (match_operand:DI 2 "logical_operand" "r,I10")))]
3261 [(set_attr "type" "arith_media")])
3263 (define_insn_and_split "*logical_sidi3"
3264 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3265 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3266 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3267 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3270 "&& reload_completed"
3271 [(set (match_dup 0) (match_dup 3))]
3275 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3276 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3277 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3280 (define_insn_and_split "*logical_sidisi3"
3281 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3282 (truncate:SI (sign_extend:DI
3283 (match_operator:SI 3 "logical_operator"
3284 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3285 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3289 [(set (match_dup 0) (match_dup 3))])
3291 (define_insn_and_split "*logical_sidi3_2"
3292 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3293 (sign_extend:DI (truncate:SI (sign_extend:DI
3294 (match_operator:SI 3 "logical_operator"
3295 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3296 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3300 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3302 (define_expand "xorsi3"
3303 [(set (match_operand:SI 0 "arith_reg_operand" "")
3304 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3305 (match_operand:SI 2 "xor_operand" "")))]
3309 (define_insn "*xorsi3_compact"
3310 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3311 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3312 (match_operand:SI 2 "logical_operand" "K08,r")))]
3315 [(set_attr "type" "arith")])
3317 (define_insn "*xorsi3_media"
3318 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3319 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3320 (match_operand:SI 2 "xor_operand" "r,I06")))]
3325 [(set_attr "type" "arith_media")])
3327 (define_insn "xordi3"
3328 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3329 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3330 (match_operand:DI 2 "xor_operand" "r,I06")))]
3335 [(set_attr "type" "arith_media")])
3337 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3338 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3340 [(set (match_operand:DI 0 "arith_reg_dest" "")
3341 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3342 [(match_operand 1 "any_register_operand" "")
3343 (match_operand 2 "any_register_operand" "")])))]
3345 [(set (match_dup 5) (match_dup 4))
3346 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3349 enum machine_mode inmode = GET_MODE (operands[1]);
3352 if (GET_CODE (operands[0]) == SUBREG)
3354 offset = SUBREG_BYTE (operands[0]);
3355 operands[0] = SUBREG_REG (operands[0]);
3357 gcc_assert (GET_CODE (operands[0]) == REG);
3358 if (! TARGET_LITTLE_ENDIAN)
3359 offset += 8 - GET_MODE_SIZE (inmode);
3360 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3363 ;; -------------------------------------------------------------------------
3364 ;; Shifts and rotates
3365 ;; -------------------------------------------------------------------------
3367 (define_expand "rotldi3"
3368 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3369 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3370 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3372 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3374 (define_insn "rotldi3_mextr"
3375 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3376 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3377 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3381 static char templ[16];
3383 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3384 8 - (int) (INTVAL (operands[2]) >> 3));
3387 [(set_attr "type" "arith_media")])
3389 (define_expand "rotrdi3"
3390 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3391 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3392 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3394 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3396 (define_insn "rotrdi3_mextr"
3397 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3398 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3399 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3403 static char templ[16];
3405 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3408 [(set_attr "type" "arith_media")])
3411 [(set (match_operand:DI 0 "arith_reg_dest" "")
3412 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3413 "ua_address_operand" "")))
3414 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3416 (clobber (match_operand:DI 3 "register_operand" ""))]
3418 [(match_dup 4) (match_dup 5)]
3421 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3422 (operands[3], operands[1]));
3423 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3424 GEN_INT (56), GEN_INT (8));
3427 (define_insn "rotlsi3_1"
3428 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3429 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3432 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3435 [(set_attr "type" "arith")])
3437 (define_insn "rotlsi3_31"
3438 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3439 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3441 (clobber (reg:SI T_REG))]
3444 [(set_attr "type" "arith")])
3446 (define_insn "rotlsi3_16"
3447 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3448 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3452 [(set_attr "type" "arith")])
3454 (define_expand "rotlsi3"
3455 [(set (match_operand:SI 0 "arith_reg_dest" "")
3456 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3457 (match_operand:SI 2 "immediate_operand" "")))]
3461 static const char rot_tab[] = {
3462 000, 000, 000, 000, 000, 000, 010, 001,
3463 001, 001, 011, 013, 003, 003, 003, 003,
3464 003, 003, 003, 003, 003, 013, 012, 002,
3465 002, 002, 010, 000, 000, 000, 000, 000,
3470 if (GET_CODE (operands[2]) != CONST_INT)
3472 count = INTVAL (operands[2]);
3473 choice = rot_tab[count];
3474 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3480 emit_move_insn (operands[0], operands[1]);
3481 count -= (count & 16) * 2;
3484 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3491 parts[0] = gen_reg_rtx (SImode);
3492 parts[1] = gen_reg_rtx (SImode);
3493 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3494 emit_move_insn (parts[choice-1], operands[1]);
3495 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3496 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3497 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3498 count = (count & ~16) - 8;
3502 for (; count > 0; count--)
3503 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3504 for (; count < 0; count++)
3505 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3510 (define_insn "*rotlhi3_8"
3511 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3512 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3516 [(set_attr "type" "arith")])
3518 (define_expand "rotlhi3"
3519 [(set (match_operand:HI 0 "arith_reg_operand" "")
3520 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3521 (match_operand:HI 2 "immediate_operand" "")))]
3525 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3532 (define_insn "ashlsi3_sh2a"
3533 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3534 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3535 (match_operand:SI 2 "arith_reg_operand" "r")))]
3538 [(set_attr "type" "arith")
3539 (set_attr "length" "4")])
3541 ;; This pattern is used by init_expmed for computing the costs of shift
3544 (define_insn_and_split "ashlsi3_std"
3545 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3546 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3547 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3548 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3550 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3551 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3559 && GET_CODE (operands[2]) == CONST_INT
3560 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3561 [(set (match_dup 3) (match_dup 2))
3563 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3564 (clobber (match_dup 4))])]
3565 "operands[4] = gen_rtx_SCRATCH (SImode);"
3566 [(set_attr "length" "*,*,*,4")
3567 (set_attr "type" "dyn_shift,arith,arith,arith")])
3569 (define_insn "ashlhi3_k"
3570 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3571 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3572 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3573 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3577 [(set_attr "type" "arith")])
3579 (define_insn "ashlsi3_n"
3580 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3581 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3582 (match_operand:SI 2 "const_int_operand" "n")))
3583 (clobber (reg:SI T_REG))]
3584 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3586 [(set (attr "length")
3587 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3589 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3591 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3593 (const_string "8")))
3594 (set_attr "type" "arith")])
3597 [(set (match_operand:SI 0 "arith_reg_dest" "")
3598 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3599 (match_operand:SI 2 "const_int_operand" "")))
3600 (clobber (reg:SI T_REG))]
3601 "TARGET_SH1 && reload_completed"
3602 [(use (reg:SI R0_REG))]
3605 gen_shifty_op (ASHIFT, operands);
3609 (define_insn "ashlsi3_media"
3610 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3611 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3612 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3617 [(set_attr "type" "arith_media")
3618 (set_attr "highpart" "ignore")])
3620 (define_expand "ashlsi3"
3621 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3622 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3623 (match_operand:SI 2 "nonmemory_operand" "")))
3624 (clobber (reg:SI T_REG))])]
3630 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3633 if (GET_CODE (operands[2]) == CONST_INT
3634 && sh_dynamicalize_shift_p (operands[2]))
3635 operands[2] = force_reg (SImode, operands[2]);
3638 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3641 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3645 (define_insn "*ashlhi3_n"
3646 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3647 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3648 (match_operand:HI 2 "const_int_operand" "n")))
3649 (clobber (reg:SI T_REG))]
3652 [(set (attr "length")
3653 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3655 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3657 (const_string "6")))
3658 (set_attr "type" "arith")])
3660 (define_expand "ashlhi3"
3661 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3662 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3663 (match_operand:SI 2 "nonmemory_operand" "")))
3664 (clobber (reg:SI T_REG))])]
3668 if (GET_CODE (operands[2]) != CONST_INT)
3670 /* It may be possible to call gen_ashlhi3 directly with more generic
3671 operands. Make sure operands[1] is a HImode register here. */
3672 if (!arith_reg_operand (operands[1], HImode))
3673 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3677 [(set (match_operand:HI 0 "arith_reg_dest" "")
3678 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3679 (match_operand:HI 2 "const_int_operand" "")))
3680 (clobber (reg:SI T_REG))]
3681 "TARGET_SH1 && reload_completed"
3682 [(use (reg:SI R0_REG))]
3685 gen_shifty_hi_op (ASHIFT, operands);
3690 ; arithmetic shift right
3693 (define_insn "ashrsi3_sh2a"
3694 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3695 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3696 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3699 [(set_attr "type" "dyn_shift")
3700 (set_attr "length" "4")])
3702 (define_insn "ashrsi3_k"
3703 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3704 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3705 (match_operand:SI 2 "const_int_operand" "M")))
3706 (clobber (reg:SI T_REG))]
3707 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3709 [(set_attr "type" "arith")])
3711 ;; We can't do HImode right shifts correctly unless we start out with an
3712 ;; explicit zero / sign extension; doing that would result in worse overall
3713 ;; code, so just let the machine independent code widen the mode.
3714 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3717 ;; ??? This should be a define expand.
3719 (define_insn "ashrsi2_16"
3720 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3721 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3725 [(set_attr "length" "4")])
3728 [(set (match_operand:SI 0 "arith_reg_dest" "")
3729 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3732 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3733 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3734 "operands[2] = gen_lowpart (HImode, operands[0]);")
3736 ;; ??? This should be a define expand.
3738 (define_insn "ashrsi2_31"
3739 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3740 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3742 (clobber (reg:SI T_REG))]
3745 [(set_attr "length" "4")])
3748 [(set (match_operand:SI 0 "arith_reg_dest" "")
3749 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3751 (clobber (reg:SI T_REG))]
3756 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3757 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3762 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3764 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3766 && peep2_reg_dead_p (2, operands[0])
3767 && peep2_reg_dead_p (2, operands[1])"
3771 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3775 (define_insn "ashlsi_c"
3776 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3777 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3779 (lt:SI (match_dup 1) (const_int 0)))]
3782 [(set_attr "type" "arith")])
3784 (define_insn "*ashlsi_c_void"
3785 [(set (reg:SI T_REG)
3786 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3787 (clobber (match_scratch:SI 1 "=0"))]
3788 "TARGET_SH1 && cse_not_expected"
3790 [(set_attr "type" "arith")])
3792 (define_insn "ashrsi3_d"
3793 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3794 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3795 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3798 [(set_attr "type" "dyn_shift")])
3800 (define_insn "ashrsi3_n"
3801 [(set (reg:SI R4_REG)
3802 (ashiftrt:SI (reg:SI R4_REG)
3803 (match_operand:SI 0 "const_int_operand" "i")))
3804 (clobber (reg:SI T_REG))
3805 (clobber (reg:SI PR_REG))
3806 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3809 [(set_attr "type" "sfunc")
3810 (set_attr "needs_delay_slot" "yes")])
3812 (define_insn "ashrsi3_media"
3813 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3814 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3815 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3820 [(set_attr "type" "arith_media")
3821 (set_attr "highpart" "ignore")])
3823 (define_expand "ashrsi3"
3824 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3825 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3826 (match_operand:SI 2 "nonmemory_operand" "")))
3827 (clobber (reg:SI T_REG))])]
3833 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3836 if (expand_ashiftrt (operands))
3842 ;; logical shift right
3844 (define_insn "lshrsi3_sh2a"
3845 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3846 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3847 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3850 [(set_attr "type" "dyn_shift")
3851 (set_attr "length" "4")])
3853 (define_insn "lshrsi3_d"
3854 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3855 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3856 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3859 [(set_attr "type" "dyn_shift")])
3861 ;; Only the single bit shift clobbers the T bit.
3863 (define_insn "lshrsi3_m"
3864 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3865 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3866 (match_operand:SI 2 "const_int_operand" "M")))
3867 (clobber (reg:SI T_REG))]
3868 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3870 [(set_attr "type" "arith")])
3872 (define_insn "lshrsi3_k"
3873 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3874 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3875 (match_operand:SI 2 "const_int_operand" "P27")))]
3876 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3877 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3879 [(set_attr "type" "arith")])
3881 (define_insn "lshrsi3_n"
3882 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3883 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3884 (match_operand:SI 2 "const_int_operand" "n")))
3885 (clobber (reg:SI T_REG))]
3886 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3888 [(set (attr "length")
3889 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3891 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3893 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3895 (const_string "8")))
3896 (set_attr "type" "arith")])
3899 [(set (match_operand:SI 0 "arith_reg_dest" "")
3900 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3901 (match_operand:SI 2 "const_int_operand" "")))
3902 (clobber (reg:SI T_REG))]
3903 "TARGET_SH1 && reload_completed"
3904 [(use (reg:SI R0_REG))]
3907 gen_shifty_op (LSHIFTRT, operands);
3911 (define_insn "lshrsi3_media"
3912 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3913 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3914 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3919 [(set_attr "type" "arith_media")
3920 (set_attr "highpart" "ignore")])
3922 (define_expand "lshrsi3"
3923 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3924 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3925 (match_operand:SI 2 "nonmemory_operand" "")))
3926 (clobber (reg:SI T_REG))])]
3932 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3935 if (GET_CODE (operands[2]) == CONST_INT
3936 && sh_dynamicalize_shift_p (operands[2]))
3937 operands[2] = force_reg (SImode, operands[2]);
3938 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3940 rtx count = copy_to_mode_reg (SImode, operands[2]);
3941 emit_insn (gen_negsi2 (count, count));
3942 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3945 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3949 ;; ??? This should be a define expand.
3951 (define_insn "ashldi3_k"
3952 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3953 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3955 (clobber (reg:SI T_REG))]
3957 "shll %R0\;rotcl %S0"
3958 [(set_attr "length" "4")
3959 (set_attr "type" "arith")])
3961 (define_insn "ashldi3_media"
3962 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3963 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3964 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3969 [(set_attr "type" "arith_media")])
3971 (define_insn "*ashldisi3_media"
3972 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3973 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3974 (match_operand:DI 2 "const_int_operand" "n")))]
3975 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3976 "shlli.l %1, %2, %0"
3977 [(set_attr "type" "arith_media")
3978 (set_attr "highpart" "ignore")])
3980 (define_expand "ashldi3"
3981 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3982 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3983 (match_operand:DI 2 "immediate_operand" "")))
3984 (clobber (reg:SI T_REG))])]
3990 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3993 if (GET_CODE (operands[2]) != CONST_INT
3994 || INTVAL (operands[2]) != 1)
3998 ;; ??? This should be a define expand.
4000 (define_insn "lshrdi3_k"
4001 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4002 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4004 (clobber (reg:SI T_REG))]
4006 "shlr %S0\;rotcr %R0"
4007 [(set_attr "length" "4")
4008 (set_attr "type" "arith")])
4010 (define_insn "lshrdi3_media"
4011 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4012 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4013 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4015 && (arith_reg_dest (operands[0], DImode)
4016 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4020 [(set_attr "type" "arith_media")])
4022 (define_insn "*lshrdisi3_media"
4023 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4024 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4025 (match_operand:DI 2 "const_int_operand" "n")))]
4026 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4027 "shlri.l %1, %2, %0"
4028 [(set_attr "type" "arith_media")
4029 (set_attr "highpart" "ignore")])
4031 (define_expand "lshrdi3"
4032 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4033 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4034 (match_operand:DI 2 "immediate_operand" "")))
4035 (clobber (reg:SI T_REG))])]
4041 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4044 if (GET_CODE (operands[2]) != CONST_INT
4045 || INTVAL (operands[2]) != 1)
4049 ;; ??? This should be a define expand.
4051 (define_insn "ashrdi3_k"
4052 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4053 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4055 (clobber (reg:SI T_REG))]
4057 "shar %S0\;rotcr %R0"
4058 [(set_attr "length" "4")
4059 (set_attr "type" "arith")])
4061 (define_insn "ashrdi3_media"
4062 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4063 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4064 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4066 && (arith_reg_dest (operands[0], DImode)
4067 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4071 [(set_attr "type" "arith_media")])
4073 (define_insn "*ashrdisi3_media"
4074 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4075 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4076 (match_operand:DI 2 "const_int_operand" "n")))]
4077 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4078 "shari.l %1, %2, %0"
4079 [(set_attr "type" "arith_media")
4080 (set_attr "highpart" "ignore")])
4082 (define_insn "ashrdisi3_media_high"
4083 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4085 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4086 (match_operand:DI 2 "const_int_operand" "n"))))]
4087 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4089 [(set_attr "type" "arith_media")])
4091 (define_insn "ashrdisi3_media_opaque"
4092 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4093 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4094 (match_operand:DI 2 "const_int_operand" "n")]
4098 [(set_attr "type" "arith_media")])
4100 (define_expand "ashrdi3"
4101 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4102 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4103 (match_operand:DI 2 "immediate_operand" "")))
4104 (clobber (reg:SI T_REG))])]
4110 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4113 if (GET_CODE (operands[2]) != CONST_INT
4114 || INTVAL (operands[2]) != 1)
4118 ;; combined left/right shift
4121 [(set (match_operand:SI 0 "register_operand" "")
4122 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4123 (match_operand:SI 2 "const_int_operand" ""))
4124 (match_operand:SI 3 "const_int_operand" "")))]
4125 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4126 [(use (reg:SI R0_REG))]
4127 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4131 [(set (match_operand:SI 0 "register_operand" "")
4132 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4133 (match_operand:SI 2 "const_int_operand" ""))
4134 (match_operand:SI 3 "const_int_operand" "")))
4135 (clobber (reg:SI T_REG))]
4136 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4137 [(use (reg:SI R0_REG))]
4138 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4142 [(set (match_operand:SI 0 "register_operand" "=r")
4143 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4144 (match_operand:SI 2 "const_int_operand" "n"))
4145 (match_operand:SI 3 "const_int_operand" "n")))
4146 (clobber (reg:SI T_REG))]
4147 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4149 [(set (attr "length")
4150 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4152 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4154 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4156 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4158 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4160 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4162 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4163 (const_string "16")]
4164 (const_string "18")))
4165 (set_attr "type" "arith")])
4168 [(set (match_operand:SI 0 "register_operand" "=z")
4169 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4170 (match_operand:SI 2 "const_int_operand" "n"))
4171 (match_operand:SI 3 "const_int_operand" "n")))
4172 (clobber (reg:SI T_REG))]
4173 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4175 [(set (attr "length")
4176 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4178 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4180 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4182 (const_string "10")))
4183 (set_attr "type" "arith")])
4185 ;; shift left / and combination with a scratch register: The combine pass
4186 ;; does not accept the individual instructions, even though they are
4187 ;; cheap. But it needs a precise description so that it is usable after
4189 (define_insn "and_shl_scratch"
4190 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4194 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4195 (match_operand:SI 2 "const_int_operand" "N,n"))
4196 (match_operand:SI 3 "" "0,r"))
4197 (match_operand:SI 4 "const_int_operand" "n,n"))
4198 (match_operand:SI 5 "const_int_operand" "n,n")))
4199 (clobber (reg:SI T_REG))]
4202 [(set (attr "length")
4203 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4205 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4207 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4209 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4210 (const_string "10")]
4211 (const_string "12")))
4212 (set_attr "type" "arith")])
4215 [(set (match_operand:SI 0 "register_operand" "")
4219 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4220 (match_operand:SI 2 "const_int_operand" ""))
4221 (match_operand:SI 3 "register_operand" ""))
4222 (match_operand:SI 4 "const_int_operand" ""))
4223 (match_operand:SI 5 "const_int_operand" "")))
4224 (clobber (reg:SI T_REG))]
4226 [(use (reg:SI R0_REG))]
4229 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4231 if (INTVAL (operands[2]))
4233 gen_shifty_op (LSHIFTRT, operands);
4235 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4236 operands[2] = operands[4];
4237 gen_shifty_op (ASHIFT, operands);
4238 if (INTVAL (operands[5]))
4240 operands[2] = operands[5];
4241 gen_shifty_op (LSHIFTRT, operands);
4246 ;; signed left/right shift combination.
4248 [(set (match_operand:SI 0 "register_operand" "")
4250 (ashift:SI (match_operand:SI 1 "register_operand" "")
4251 (match_operand:SI 2 "const_int_operand" ""))
4252 (match_operand:SI 3 "const_int_operand" "")
4254 (clobber (reg:SI T_REG))]
4256 [(use (reg:SI R0_REG))]
4257 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4260 (define_insn "shl_sext_ext"
4261 [(set (match_operand:SI 0 "register_operand" "=r")
4263 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4264 (match_operand:SI 2 "const_int_operand" "n"))
4265 (match_operand:SI 3 "const_int_operand" "n")
4267 (clobber (reg:SI T_REG))]
4268 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4270 [(set (attr "length")
4271 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4273 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4275 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4277 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4279 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4281 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4283 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4285 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4286 (const_string "16")]
4287 (const_string "18")))
4288 (set_attr "type" "arith")])
4290 (define_insn "shl_sext_sub"
4291 [(set (match_operand:SI 0 "register_operand" "=z")
4293 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4294 (match_operand:SI 2 "const_int_operand" "n"))
4295 (match_operand:SI 3 "const_int_operand" "n")
4297 (clobber (reg:SI T_REG))]
4298 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4300 [(set (attr "length")
4301 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4303 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4305 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4307 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4308 (const_string "12")]
4309 (const_string "14")))
4310 (set_attr "type" "arith")])
4312 ;; These patterns are found in expansions of DImode shifts by 16, and
4313 ;; allow the xtrct instruction to be generated from C source.
4315 (define_insn "xtrct_left"
4316 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4317 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4319 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4323 [(set_attr "type" "arith")])
4325 (define_insn "xtrct_right"
4326 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4327 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4329 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4333 [(set_attr "type" "arith")])
4335 ;; -------------------------------------------------------------------------
4337 ;; -------------------------------------------------------------------------
4340 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4341 (neg:SI (plus:SI (reg:SI T_REG)
4342 (match_operand:SI 1 "arith_reg_operand" "r"))))
4344 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4348 [(set_attr "type" "arith")])
4350 (define_insn "*negdi_media"
4351 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4352 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4355 [(set_attr "type" "arith_media")])
4357 (define_expand "negdi2"
4358 [(set (match_operand:DI 0 "arith_reg_operand" "")
4359 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4365 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4366 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4368 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4369 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4371 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4372 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4374 emit_insn (gen_clrt ());
4375 emit_insn (gen_negc (low_dst, low_src));
4376 emit_insn (gen_negc (high_dst, high_src));
4381 (define_insn "negsi2"
4382 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4383 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4386 [(set_attr "type" "arith")])
4388 (define_insn "one_cmplsi2"
4389 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4390 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4393 [(set_attr "type" "arith")])
4395 (define_expand "one_cmpldi2"
4396 [(set (match_operand:DI 0 "arith_reg_dest" "")
4397 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4399 "TARGET_SHMEDIA" "")
4401 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4402 This can be used as some kind of conditional execution, which is useful
4405 [(set (match_operand:SI 0 "arith_reg_dest" "")
4406 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4407 (match_operand:SI 1 "arith_reg_operand" ""))
4411 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4412 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4416 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4417 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4418 (match_operand:SI 1 "arith_reg_operand" "0")
4419 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4421 "bf 0f\;neg %2,%0\\n0:"
4422 [(set_attr "type" "arith") ;; poor approximation
4423 (set_attr "length" "4")])
4426 ;; -------------------------------------------------------------------------
4427 ;; Zero extension instructions
4428 ;; -------------------------------------------------------------------------
4430 (define_insn "zero_extendsidi2"
4431 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4432 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4434 "addz.l %1, r63, %0"
4435 [(set_attr "type" "arith_media")
4436 (set_attr "highpart" "extend")])
4438 (define_insn "zero_extendhidi2"
4439 [(set (match_operand:DI 0 "register_operand" "=r,r")
4440 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4445 [(set_attr "type" "*,load_media")
4446 (set (attr "highpart")
4447 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4448 (const_string "user")]
4449 (const_string "ignore")))])
4452 [(set (match_operand:DI 0 "register_operand" "")
4453 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4454 "TARGET_SHMEDIA && reload_completed"
4455 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4456 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4459 if (GET_CODE (operands[1]) == TRUNCATE)
4460 operands[1] = XEXP (operands[1], 0);
4463 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4464 ;; reload the entire truncate expression.
4465 (define_insn_and_split "*loaddi_trunc"
4466 [(set (match_operand 0 "any_register_operand" "=r")
4467 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4468 "TARGET_SHMEDIA && reload_completed"
4470 "TARGET_SHMEDIA && reload_completed"
4471 [(set (match_dup 0) (match_dup 1))]
4472 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4474 (define_insn "zero_extendqidi2"
4475 [(set (match_operand:DI 0 "register_operand" "=r,r")
4476 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4481 [(set_attr "type" "arith_media,load_media")
4482 (set (attr "highpart")
4483 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4484 (const_string "user")]
4485 (const_string "ignore")))])
4487 (define_expand "zero_extendhisi2"
4488 [(set (match_operand:SI 0 "arith_reg_operand" "")
4489 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4493 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4494 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4497 (define_insn "*zero_extendhisi2_compact"
4498 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4499 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4502 [(set_attr "type" "arith")])
4504 (define_insn "*zero_extendhisi2_media"
4505 [(set (match_operand:SI 0 "register_operand" "=r,r")
4506 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4511 [(set_attr "type" "arith_media,load_media")
4512 (set (attr "highpart")
4513 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4514 (const_string "user")]
4515 (const_string "ignore")))])
4518 [(set (match_operand:SI 0 "register_operand" "")
4519 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4520 "TARGET_SHMEDIA && reload_completed"
4521 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4522 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4525 rtx op1 = operands[1];
4527 if (GET_CODE (op1) == TRUNCATE)
4528 op1 = XEXP (op1, 0);
4530 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4531 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4534 (define_expand "zero_extendqisi2"
4535 [(set (match_operand:SI 0 "arith_reg_operand" "")
4536 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4540 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4541 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4544 (define_insn "*zero_extendqisi2_compact"
4545 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4546 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4549 [(set_attr "type" "arith")])
4551 (define_insn "*zero_extendqisi2_media"
4552 [(set (match_operand:SI 0 "register_operand" "=r,r")
4553 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4558 [(set_attr "type" "arith_media,load_media")
4559 (set (attr "highpart")
4560 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4561 (const_string "user")]
4562 (const_string "ignore")))])
4564 (define_insn "zero_extendqihi2"
4565 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4566 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4569 [(set_attr "type" "arith")])
4571 ;; -------------------------------------------------------------------------
4572 ;; Sign extension instructions
4573 ;; -------------------------------------------------------------------------
4575 ;; ??? This should be a define expand.
4576 ;; ??? Or perhaps it should be dropped?
4578 ;; convert_move generates good code for SH[1-4].
4579 (define_insn "extendsidi2"
4580 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4581 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4587 [(set_attr "type" "arith_media,load_media,fpconv_media")
4588 (set (attr "highpart")
4589 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4590 (const_string "user")]
4591 (const_string "extend")))])
4593 (define_insn "extendhidi2"
4594 [(set (match_operand:DI 0 "register_operand" "=r,r")
4595 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4600 [(set_attr "type" "*,load_media")
4601 (set (attr "highpart")
4602 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4603 (const_string "user")]
4604 (const_string "ignore")))])
4607 [(set (match_operand:DI 0 "register_operand" "")
4608 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4609 "TARGET_SHMEDIA && reload_completed"
4610 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4611 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4614 if (GET_CODE (operands[1]) == TRUNCATE)
4615 operands[1] = XEXP (operands[1], 0);
4618 (define_insn "extendqidi2"
4619 [(set (match_operand:DI 0 "register_operand" "=r,r")
4620 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4625 [(set_attr "type" "*,load_media")
4626 (set (attr "highpart")
4627 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4628 (const_string "user")]
4629 (const_string "ignore")))])
4632 [(set (match_operand:DI 0 "register_operand" "")
4633 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4634 "TARGET_SHMEDIA && reload_completed"
4635 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4636 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4639 if (GET_CODE (operands[1]) == TRUNCATE)
4640 operands[1] = XEXP (operands[1], 0);
4643 (define_expand "extendhisi2"
4644 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4645 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4649 (define_insn "*extendhisi2_compact"
4650 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4651 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4656 [(set_attr "type" "arith,load")])
4658 (define_insn "*extendhisi2_media"
4659 [(set (match_operand:SI 0 "register_operand" "=r,r")
4660 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4665 [(set_attr "type" "arith_media,load_media")
4666 (set (attr "highpart")
4667 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4668 (const_string "user")]
4669 (const_string "ignore")))])
4672 [(set (match_operand:SI 0 "register_operand" "")
4673 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4674 "TARGET_SHMEDIA && reload_completed"
4675 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4676 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4679 rtx op1 = operands[1];
4680 if (GET_CODE (op1) == TRUNCATE)
4681 op1 = XEXP (op1, 0);
4683 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4684 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4687 (define_expand "extendqisi2"
4688 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4689 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4693 (define_insn "*extendqisi2_compact"
4694 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4695 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4700 [(set_attr "type" "arith,load")])
4702 (define_insn "*extendqisi2_media"
4703 [(set (match_operand:SI 0 "register_operand" "=r,r")
4704 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4709 [(set_attr "type" "arith_media,load_media")
4710 (set (attr "highpart")
4711 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712 (const_string "user")]
4713 (const_string "ignore")))])
4716 [(set (match_operand:SI 0 "register_operand" "")
4717 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4718 "TARGET_SHMEDIA && reload_completed"
4719 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4720 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4723 rtx op1 = operands[1];
4724 if (GET_CODE (op1) == TRUNCATE)
4725 op1 = XEXP (op1, 0);
4727 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4728 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4731 (define_insn "extendqihi2"
4732 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4733 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4738 [(set_attr "type" "arith,load")])
4740 /* It would seem useful to combine the truncXi patterns into the movXi
4741 patterns, but unary operators are ignored when matching constraints,
4742 so we need separate patterns. */
4743 (define_insn "truncdisi2"
4744 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4745 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4754 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4755 (set (attr "highpart")
4756 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4757 (const_string "user")]
4758 (const_string "extend")))])
4760 (define_insn "truncdihi2"
4761 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4762 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4765 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4767 [(set_attr "type" "arith_media,store_media")
4768 (set_attr "length" "8,4")
4769 (set (attr "highpart")
4770 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4771 (const_string "user")]
4772 (const_string "extend")))])
4774 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4775 ; Because we use zero extension, we can't provide signed QImode compares
4776 ; using a simple compare or conditional branch insn.
4777 (define_insn "truncdiqi2"
4778 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4779 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4784 [(set_attr "type" "arith_media,store")
4785 (set (attr "highpart")
4786 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4787 (const_string "user")]
4788 (const_string "extend")))])
4789 ;; -------------------------------------------------------------------------
4790 ;; Move instructions
4791 ;; -------------------------------------------------------------------------
4793 ;; define push and pop so it is easy for sh.c
4794 ;; We can't use push and pop on SHcompact because the stack must always
4795 ;; be 8-byte aligned.
4797 (define_expand "push"
4798 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4799 (match_operand:SI 0 "register_operand" "r,l,x"))]
4800 "TARGET_SH1 && ! TARGET_SH5"
4803 (define_expand "pop"
4804 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4805 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4806 "TARGET_SH1 && ! TARGET_SH5"
4809 (define_expand "push_e"
4810 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4811 (match_operand:SF 0 "" ""))
4812 (use (reg:PSI FPSCR_REG))
4813 (clobber (scratch:SI))])]
4814 "TARGET_SH1 && ! TARGET_SH5"
4817 (define_insn "push_fpul"
4818 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4819 "TARGET_SH2E && ! TARGET_SH5"
4821 [(set_attr "type" "fstore")
4822 (set_attr "late_fp_use" "yes")
4823 (set_attr "hit_stack" "yes")])
4825 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4827 (define_expand "push_4"
4828 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4829 (match_operand:DF 0 "" ""))
4830 (use (reg:PSI FPSCR_REG))
4831 (clobber (scratch:SI))])]
4832 "TARGET_SH1 && ! TARGET_SH5"
4835 (define_expand "pop_e"
4836 [(parallel [(set (match_operand:SF 0 "" "")
4837 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4838 (use (reg:PSI FPSCR_REG))
4839 (clobber (scratch:SI))])]
4840 "TARGET_SH1 && ! TARGET_SH5"
4843 (define_insn "pop_fpul"
4844 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4845 "TARGET_SH2E && ! TARGET_SH5"
4847 [(set_attr "type" "load")
4848 (set_attr "hit_stack" "yes")])
4850 (define_expand "pop_4"
4851 [(parallel [(set (match_operand:DF 0 "" "")
4852 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4853 (use (reg:PSI FPSCR_REG))
4854 (clobber (scratch:SI))])]
4855 "TARGET_SH1 && ! TARGET_SH5"
4858 (define_expand "push_fpscr"
4863 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4864 gen_rtx_PRE_DEC (Pmode,
4865 stack_pointer_rtx)),
4867 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4871 (define_expand "pop_fpscr"
4876 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4877 gen_frame_mem (PSImode,
4878 gen_rtx_POST_INC (Pmode,
4879 stack_pointer_rtx))));
4880 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4884 ;; These two patterns can happen as the result of optimization, when
4885 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4886 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4889 [(set (reg:SI T_REG) (const_int 0))]
4894 [(set (reg:SI T_REG) (const_int 1))]
4898 ;; t/r must come after r/r, lest reload will try to reload stuff like
4899 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4900 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4901 (define_insn "movsi_i"
4902 [(set (match_operand:SI 0 "general_movdst_operand"
4903 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4904 (match_operand:SI 1 "general_movsrc_operand"
4905 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4909 && (register_operand (operands[0], SImode)
4910 || register_operand (operands[1], SImode))"
4928 [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4929 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4931 ;; t/r must come after r/r, lest reload will try to reload stuff like
4932 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4933 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4934 ;; will require a reload.
4935 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4936 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4937 (define_insn "movsi_ie"
4938 [(set (match_operand:SI 0 "general_movdst_operand"
4939 "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4940 (match_operand:SI 1 "general_movsrc_operand"
4941 "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4942 "(TARGET_SH2E || TARGET_SH2A)
4943 && (register_operand (operands[0], SImode)
4944 || register_operand (operands[1], SImode))"
4970 ! move optimized away"
4971 [(set_attr "type" "pcload_si,move,movi8,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4972 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4973 (set_attr_alternative "length"
4980 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4981 (const_int 4) (const_int 2))
4986 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4987 (const_int 4) (const_int 2))
5004 (define_insn "movsi_i_lowpart"
5005 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5006 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5008 && (register_operand (operands[0], SImode)
5009 || register_operand (operands[1], SImode))"
5020 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5022 (define_insn_and_split "load_ra"
5023 [(set (match_operand:SI 0 "general_movdst_operand" "")
5024 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5027 "&& ! currently_expanding_to_rtl"
5028 [(set (match_dup 0) (match_dup 1))]
5031 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
5032 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5035 ;; The '?'s in the following constraints may not reflect the time taken
5036 ;; to perform the move. They are there to discourage the use of floating-
5037 ;; point registers for storing integer values.
5038 (define_insn "*movsi_media"
5039 [(set (match_operand:SI 0 "general_movdst_operand"
5040 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5041 (match_operand:SI 1 "general_movsrc_operand"
5042 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5044 && (register_operand (operands[0], SImode)
5045 || sh_register_operand (operands[1], SImode)
5046 || GET_CODE (operands[1]) == TRUNCATE)"
5061 [(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")
5062 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5063 (set (attr "highpart")
5064 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5065 (const_string "user")]
5066 (const_string "ignore")))])
5068 (define_insn "*movsi_media_nofpu"
5069 [(set (match_operand:SI 0 "general_movdst_operand"
5070 "=r,r,r,r,m,*b,r,*b")
5071 (match_operand:SI 1 "general_movsrc_operand"
5072 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5074 && (register_operand (operands[0], SImode)
5075 || sh_register_operand (operands[1], SImode)
5076 || GET_CODE (operands[1]) == TRUNCATE)"
5086 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5087 (set_attr "length" "4,4,8,4,4,4,4,12")
5088 (set (attr "highpart")
5089 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5090 (const_string "user")]
5091 (const_string "ignore")))])
5093 (define_expand "movsi_const"
5094 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5095 (const:SI (sign_extend:SI
5098 (match_operand:DI 1 "immediate_operand" "s")
5101 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5104 (truncate:HI (match_dup 1))))))]
5105 "TARGET_SHMEDIA && reload_completed
5106 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5109 if (GET_CODE (operands[1]) == LABEL_REF
5110 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5111 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5112 else if (GOTOFF_P (operands[1]))
5114 rtx unspec = XEXP (operands[1], 0);
5116 if (! UNSPEC_GOTOFF_P (unspec))
5118 unspec = XEXP (unspec, 0);
5119 if (! UNSPEC_GOTOFF_P (unspec))
5122 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5123 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5124 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5128 (define_expand "movsi_const_16bit"
5129 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5130 (const:SI (sign_extend:SI
5132 (match_operand:DI 1 "immediate_operand" "s")))))]
5133 "TARGET_SHMEDIA && flag_pic && reload_completed
5134 && GET_CODE (operands[1]) == SYMBOL_REF"
5138 [(set (match_operand:SI 0 "arith_reg_dest" "")
5139 (match_operand:SI 1 "immediate_operand" ""))]
5140 "TARGET_SHMEDIA && reload_completed
5141 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5145 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5147 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5153 [(set (match_operand:SI 0 "register_operand" "")
5154 (match_operand:SI 1 "immediate_operand" ""))]
5155 "TARGET_SHMEDIA && reload_completed
5156 && ((GET_CODE (operands[1]) == CONST_INT
5157 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5158 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5159 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5161 (define_expand "movsi"
5162 [(set (match_operand:SI 0 "general_movdst_operand" "")
5163 (match_operand:SI 1 "general_movsrc_operand" ""))]
5165 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5167 (define_expand "ic_invalidate_line"
5168 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5169 (match_dup 1)] UNSPEC_ICACHE)
5170 (clobber (scratch:SI))])]
5171 "TARGET_HARD_SH4 || TARGET_SH5"
5176 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5179 else if (TARGET_SHCOMPACT)
5181 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5182 operands[1] = force_reg (Pmode, operands[1]);
5183 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5186 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5188 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5191 operands[0] = force_reg (Pmode, operands[0]);
5192 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5196 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5197 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5198 ;; the requirement *1*00 for associative address writes. The alignment of
5199 ;; %0 implies that its least significant bit is cleared,
5200 ;; thus we clear the V bit of a matching entry if there is one.
5201 (define_insn "ic_invalidate_line_i"
5202 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5203 (match_operand:SI 1 "register_operand" "r")]
5205 (clobber (match_scratch:SI 2 "=&r"))]
5207 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5208 [(set_attr "length" "8")
5209 (set_attr "type" "cwb")])
5211 (define_insn "ic_invalidate_line_sh4a"
5212 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5214 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5215 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5216 [(set_attr "length" "16")
5217 (set_attr "type" "cwb")])
5219 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5220 ;; an add in the code that calculates the address.
5221 (define_insn "ic_invalidate_line_media"
5222 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5225 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5226 [(set_attr "length" "16")
5227 (set_attr "type" "invalidate_line_media")])
5229 (define_insn "ic_invalidate_line_compact"
5230 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5231 (match_operand:SI 1 "register_operand" "r")]
5233 (clobber (reg:SI PR_REG))]
5236 [(set_attr "type" "sfunc")
5237 (set_attr "needs_delay_slot" "yes")])
5239 (define_expand "initialize_trampoline"
5240 [(match_operand:SI 0 "" "")
5241 (match_operand:SI 1 "" "")
5242 (match_operand:SI 2 "" "")]
5248 tramp = force_reg (Pmode, operands[0]);
5249 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5251 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5252 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5254 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5258 (define_insn "initialize_trampoline_compact"
5259 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5260 (match_operand:SI 1 "register_operand" "r")
5261 (reg:SI R2_REG) (reg:SI R3_REG)]
5264 (clobber (reg:SI PR_REG))]
5267 [(set_attr "type" "sfunc")
5268 (set_attr "needs_delay_slot" "yes")])
5270 (define_insn "movqi_i"
5271 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5272 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5274 && (arith_reg_operand (operands[0], QImode)
5275 || arith_reg_operand (operands[1], QImode))"
5284 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5286 (define_insn "*movqi_media"
5287 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5288 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5290 && (arith_reg_operand (operands[0], QImode)
5291 || extend_reg_or_0_operand (operands[1], QImode))"
5297 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5298 (set (attr "highpart")
5299 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5300 (const_string "user")]
5301 (const_string "ignore")))])
5303 (define_expand "movqi"
5304 [(set (match_operand:QI 0 "general_operand" "")
5305 (match_operand:QI 1 "general_operand" ""))]
5307 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5309 (define_expand "reload_inqi"
5310 [(set (match_operand:SI 2 "" "=&r")
5311 (match_operand:QI 1 "inqhi_operand" ""))
5312 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5313 (truncate:QI (match_dup 3)))]
5317 rtx inner = XEXP (operands[1], 0);
5318 int regno = REGNO (inner);
5320 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5321 operands[1] = gen_rtx_REG (SImode, regno);
5322 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5325 /* When storing r0, we have to avoid reg+reg addressing. */
5326 (define_insn "movhi_i"
5327 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5328 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5330 && (arith_reg_operand (operands[0], HImode)
5331 || arith_reg_operand (operands[1], HImode))
5332 && (GET_CODE (operands[0]) != MEM
5333 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5334 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5335 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5345 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5347 (define_insn "*movhi_media"
5348 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5349 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5351 && (arith_reg_operand (operands[0], HImode)
5352 || arith_reg_or_0_operand (operands[1], HImode))"
5359 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5360 (set (attr "highpart")
5361 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5362 (const_string "user")]
5363 (const_string "ignore")))])
5366 [(set (match_operand:HI 0 "register_operand" "")
5367 (match_operand:HI 1 "immediate_operand" ""))]
5368 "TARGET_SHMEDIA && reload_completed
5369 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5370 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5372 (define_expand "movhi"
5373 [(set (match_operand:HI 0 "general_movdst_operand" "")
5374 (match_operand:HI 1 "general_movsrc_operand" ""))]
5376 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5378 (define_expand "reload_inhi"
5379 [(set (match_operand:SI 2 "" "=&r")
5380 (match_operand:HI 1 "inqhi_operand" ""))
5381 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5382 (truncate:HI (match_dup 3)))]
5386 rtx inner = XEXP (operands[1], 0);
5387 int regno = REGNO (inner);
5389 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5390 operands[1] = gen_rtx_REG (SImode, regno);
5391 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5394 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5395 ;; compiled with -m2 -ml -O3 -funroll-loops
5396 (define_insn "*movdi_i"
5397 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5398 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5400 && (arith_reg_operand (operands[0], DImode)
5401 || arith_reg_operand (operands[1], DImode))"
5402 "* return output_movedouble (insn, operands, DImode);"
5403 [(set_attr "length" "4")
5404 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5406 ;; If the output is a register and the input is memory or a register, we have
5407 ;; to be careful and see which word needs to be loaded first.
5410 [(set (match_operand:DI 0 "general_movdst_operand" "")
5411 (match_operand:DI 1 "general_movsrc_operand" ""))]
5412 "TARGET_SH1 && reload_completed"
5413 [(set (match_dup 2) (match_dup 3))
5414 (set (match_dup 4) (match_dup 5))]
5419 if ((GET_CODE (operands[0]) == MEM
5420 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5421 || (GET_CODE (operands[1]) == MEM
5422 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5425 switch (GET_CODE (operands[0]))
5428 regno = REGNO (operands[0]);
5431 regno = subreg_regno (operands[0]);
5441 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5443 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5444 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5445 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5446 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5450 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5451 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5452 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5453 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5456 if (operands[2] == 0 || operands[3] == 0
5457 || operands[4] == 0 || operands[5] == 0)
5461 ;; The '?'s in the following constraints may not reflect the time taken
5462 ;; to perform the move. They are there to discourage the use of floating-
5463 ;; point registers for storing integer values.
5464 (define_insn "*movdi_media"
5465 [(set (match_operand:DI 0 "general_movdst_operand"
5466 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5467 (match_operand:DI 1 "general_movsrc_operand"
5468 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5470 && (register_operand (operands[0], DImode)
5471 || sh_register_operand (operands[1], DImode))"
5486 [(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")
5487 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5489 (define_insn "*movdi_media_nofpu"
5490 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5491 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5493 && (register_operand (operands[0], DImode)
5494 || sh_register_operand (operands[1], DImode))"
5504 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5505 (set_attr "length" "4,4,16,4,4,4,4,*")])
5507 (define_insn "*movdi_media_I16"
5508 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5509 (match_operand:DI 1 "const_int_operand" "I16"))]
5510 "TARGET_SHMEDIA && reload_completed"
5512 [(set_attr "type" "arith_media")
5513 (set_attr "length" "4")])
5516 [(set (match_operand:DI 0 "arith_reg_dest" "")
5517 (match_operand:DI 1 "immediate_operand" ""))]
5518 "TARGET_SHMEDIA && reload_completed
5519 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5520 [(set (match_dup 0) (match_dup 1))]
5525 if (TARGET_SHMEDIA64)
5526 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5528 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5530 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5535 (define_expand "movdi_const"
5536 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5537 (const:DI (sign_extend:DI
5540 (match_operand:DI 1 "immediate_operand" "s")
5543 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5549 (const_int 32)))))))
5551 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5557 (const_int 16)))))))
5559 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5564 "TARGET_SHMEDIA64 && reload_completed
5565 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5568 sh_mark_label (operands[1], 4);
5571 (define_expand "movdi_const_32bit"
5572 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5573 (const:DI (sign_extend:DI
5576 (match_operand:DI 1 "immediate_operand" "s")
5579 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5584 "TARGET_SHMEDIA32 && reload_completed
5585 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5588 sh_mark_label (operands[1], 2);
5591 (define_expand "movdi_const_16bit"
5592 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5593 (const:DI (sign_extend:DI
5595 (match_operand:DI 1 "immediate_operand" "s")))))]
5596 "TARGET_SHMEDIA && flag_pic && reload_completed
5597 && GET_CODE (operands[1]) == SYMBOL_REF"
5601 [(set (match_operand:DI 0 "ext_dest_operand" "")
5602 (match_operand:DI 1 "immediate_operand" ""))]
5603 "TARGET_SHMEDIA && reload_completed
5604 && GET_CODE (operands[1]) == CONST_INT
5605 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5606 [(set (match_dup 0) (match_dup 2))
5610 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5611 unsigned HOST_WIDE_INT low = val;
5612 unsigned HOST_WIDE_INT high = val;
5613 unsigned HOST_WIDE_INT sign;
5614 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5616 /* Zero-extend the 16 least-significant bits. */
5619 /* Arithmetic shift right the word by 16 bits. */
5621 if (GET_CODE (operands[0]) == SUBREG
5622 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5631 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5637 /* If we can't generate the constant with a two-insn movi / shori
5638 sequence, try some other strategies. */
5639 if (! CONST_OK_FOR_I16 (high))
5641 /* Try constant load / left shift. We know VAL != 0. */
5642 val2 = val ^ (val-1);
5645 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5647 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5648 || (! CONST_OK_FOR_I16 (high >> 16)
5649 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5651 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5652 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5653 GEN_INT (trailing_zeroes));
5657 /* Try constant load / right shift. */
5658 val2 = (val >> 15) + 1;
5659 if (val2 == (val2 & -val2))
5661 int shift = 49 - exact_log2 (val2);
5663 val2 = trunc_int_for_mode (val << shift, DImode);
5664 if (CONST_OK_FOR_I16 (val2))
5666 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5672 val2 = val & 0xffff;
5673 if ((val >> 16 & 0xffff) == val2
5674 && (val >> 32 & 0xffff) == val2
5675 && (val >> 48 & 0xffff) == val2)
5677 val2 = (HOST_WIDE_INT) val >> 48;
5678 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5679 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5682 /* Try movi / mshflo.l */
5683 val2 = (HOST_WIDE_INT) val >> 32;
5684 if (val2 == ((unsigned HOST_WIDE_INT)
5685 trunc_int_for_mode (val, SImode)))
5687 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5691 /* Try movi / mshflo.l w/ r63. */
5692 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5693 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5695 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5701 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5704 operands[2] = GEN_INT (val2);
5708 [(set (match_operand:DI 0 "ext_dest_operand" "")
5709 (match_operand:DI 1 "immediate_operand" ""))]
5710 "TARGET_SHMEDIA && reload_completed
5711 && GET_CODE (operands[1]) == CONST_DOUBLE"
5712 [(set (match_dup 0) (match_dup 2))
5714 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5717 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5718 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5719 unsigned HOST_WIDE_INT val = low;
5720 unsigned HOST_WIDE_INT sign;
5722 /* Zero-extend the 16 least-significant bits. */
5724 operands[1] = GEN_INT (val);
5726 /* Arithmetic shift right the double-word by 16 bits. */
5728 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5731 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5735 /* This will only be true if high is a sign-extension of low, i.e.,
5736 it must be either 0 or (unsigned)-1, and be zero iff the
5737 most-significant bit of low is set. */
5738 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5739 operands[2] = GEN_INT (low);
5741 operands[2] = immed_double_const (low, high, DImode);
5744 (define_insn "shori_media"
5745 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5746 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5748 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5749 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5753 [(set_attr "type" "arith_media,*")])
5755 (define_insn "*shori_media_si"
5756 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5757 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5759 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5763 (define_expand "movdi"
5764 [(set (match_operand:DI 0 "general_movdst_operand" "")
5765 (match_operand:DI 1 "general_movsrc_operand" ""))]
5767 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5769 (define_insn "movdf_media"
5770 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5771 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5773 && (register_operand (operands[0], DFmode)
5774 || sh_register_operand (operands[1], DFmode))"
5785 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5787 (define_insn "movdf_media_nofpu"
5788 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5789 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5791 && (register_operand (operands[0], DFmode)
5792 || sh_register_operand (operands[1], DFmode))"
5798 [(set_attr "type" "arith_media,*,load_media,store_media")])
5801 [(set (match_operand:DF 0 "arith_reg_dest" "")
5802 (match_operand:DF 1 "immediate_operand" ""))]
5803 "TARGET_SHMEDIA && reload_completed"
5804 [(set (match_dup 3) (match_dup 2))]
5807 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5809 REAL_VALUE_TYPE value;
5811 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5812 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5814 if (HOST_BITS_PER_WIDE_INT >= 64)
5815 operands[2] = immed_double_const ((unsigned long) values[endian]
5816 | ((HOST_WIDE_INT) values[1 - endian]
5820 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5821 operands[2] = immed_double_const (values[endian], values[1 - endian],
5825 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5828 ;; ??? This should be a define expand.
5830 (define_insn "movdf_k"
5831 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5832 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5834 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5835 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5836 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5837 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5838 && (arith_reg_operand (operands[0], DFmode)
5839 || arith_reg_operand (operands[1], DFmode))"
5840 "* return output_movedouble (insn, operands, DFmode);"
5841 [(set_attr "length" "4")
5842 (set_attr "type" "move,pcload,load,store")])
5844 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5845 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5846 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5847 ;; the d/m/c/X alternative, which is split later into single-precision
5848 ;; instructions. And when not optimizing, no splits are done before fixing
5849 ;; up pcloads, so we need usable length information for that.
5850 (define_insn "movdf_i4"
5851 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5852 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5853 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5854 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5855 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5856 && (arith_reg_operand (operands[0], DFmode)
5857 || arith_reg_operand (operands[1], DFmode))"
5869 [(set_attr_alternative "length"
5870 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5872 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5873 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5874 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5876 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5877 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5878 ;; increment or decrement r15 explicitly.
5880 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5881 (const_int 10) (const_int 8))
5883 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5884 (const_int 10) (const_int 8))])
5885 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5886 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5887 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5888 (const_string "double")
5889 (const_string "none")))])
5891 ;; Moving DFmode between fp/general registers through memory
5892 ;; (the top of the stack) is faster than moving through fpul even for
5893 ;; little endian. Because the type of an instruction is important for its
5894 ;; scheduling, it is beneficial to split these operations, rather than
5895 ;; emitting them in one single chunk, even if this will expose a stack
5896 ;; use that will prevent scheduling of other stack accesses beyond this
5899 [(set (match_operand:DF 0 "register_operand" "")
5900 (match_operand:DF 1 "register_operand" ""))
5901 (use (match_operand:PSI 2 "fpscr_operand" ""))
5902 (clobber (match_scratch:SI 3 "=X"))]
5903 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5904 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5910 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5912 emit_move_insn (stack_pointer_rtx,
5913 plus_constant (stack_pointer_rtx, -8));
5914 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5917 tos = gen_tmp_stack_mem (DFmode,
5918 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5919 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5920 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5921 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5922 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5923 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5925 tos = gen_tmp_stack_mem (DFmode,
5926 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5927 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5928 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5929 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5931 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5935 ;; local-alloc sometimes allocates scratch registers even when not required,
5936 ;; so we must be prepared to handle these.
5938 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5940 [(set (match_operand:DF 0 "general_movdst_operand" "")
5941 (match_operand:DF 1 "general_movsrc_operand" ""))
5942 (use (match_operand:PSI 2 "fpscr_operand" ""))
5943 (clobber (match_scratch:SI 3 ""))]
5944 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5946 && true_regnum (operands[0]) < 16
5947 && true_regnum (operands[1]) < 16"
5948 [(set (match_dup 0) (match_dup 1))]
5951 /* If this was a reg <-> mem operation with base + index reg addressing,
5952 we have to handle this in a special way. */
5953 rtx mem = operands[0];
5955 if (! memory_operand (mem, DFmode))
5960 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5961 mem = SUBREG_REG (mem);
5962 if (GET_CODE (mem) == MEM)
5964 rtx addr = XEXP (mem, 0);
5965 if (GET_CODE (addr) == PLUS
5966 && GET_CODE (XEXP (addr, 0)) == REG
5967 && GET_CODE (XEXP (addr, 1)) == REG)
5970 rtx reg0 = gen_rtx_REG (Pmode, 0);
5971 rtx regop = operands[store_p], word0 ,word1;
5973 if (GET_CODE (regop) == SUBREG)
5974 alter_subreg (®op);
5975 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5979 mem = copy_rtx (mem);
5980 PUT_MODE (mem, SImode);
5981 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5982 alter_subreg (&word0);
5983 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5984 alter_subreg (&word1);
5985 if (store_p || ! refers_to_regno_p (REGNO (word0),
5986 REGNO (word0) + 1, addr, 0))
5989 ? gen_movsi_ie (mem, word0)
5990 : gen_movsi_ie (word0, mem));
5991 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5992 mem = copy_rtx (mem);
5994 ? gen_movsi_ie (mem, word1)
5995 : gen_movsi_ie (word1, mem));
5996 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6000 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6001 emit_insn (gen_movsi_ie (word1, mem));
6002 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6003 mem = copy_rtx (mem);
6004 emit_insn (gen_movsi_ie (word0, mem));
6011 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6013 [(set (match_operand:DF 0 "register_operand" "")
6014 (match_operand:DF 1 "memory_operand" ""))
6015 (use (match_operand:PSI 2 "fpscr_operand" ""))
6016 (clobber (reg:SI R0_REG))]
6017 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6018 [(parallel [(set (match_dup 0) (match_dup 1))
6020 (clobber (scratch:SI))])]
6023 (define_expand "reload_indf__frn"
6024 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6025 (match_operand:DF 1 "immediate_operand" "FQ"))
6026 (use (reg:PSI FPSCR_REG))
6027 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6031 (define_expand "reload_outdf__RnFRm"
6032 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6033 (match_operand:DF 1 "register_operand" "af,r"))
6034 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6038 ;; Simplify no-op moves.
6040 [(set (match_operand:SF 0 "register_operand" "")
6041 (match_operand:SF 1 "register_operand" ""))
6042 (use (match_operand:PSI 2 "fpscr_operand" ""))
6043 (clobber (match_scratch:SI 3 ""))]
6044 "TARGET_SH2E && reload_completed
6045 && true_regnum (operands[0]) == true_regnum (operands[1])"
6046 [(set (match_dup 0) (match_dup 0))]
6049 ;; fmovd substitute post-reload splits
6051 [(set (match_operand:DF 0 "register_operand" "")
6052 (match_operand:DF 1 "register_operand" ""))
6053 (use (match_operand:PSI 2 "fpscr_operand" ""))
6054 (clobber (match_scratch:SI 3 ""))]
6055 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6056 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6057 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6061 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6062 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6063 gen_rtx_REG (SFmode, src), operands[2]));
6064 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6065 gen_rtx_REG (SFmode, src + 1), operands[2]));
6070 [(set (match_operand:DF 0 "register_operand" "")
6071 (mem:DF (match_operand:SI 1 "register_operand" "")))
6072 (use (match_operand:PSI 2 "fpscr_operand" ""))
6073 (clobber (match_scratch:SI 3 ""))]
6074 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6075 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6076 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6080 int regno = true_regnum (operands[0]);
6082 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6084 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6085 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6086 regno + !! TARGET_LITTLE_ENDIAN),
6087 mem2, operands[2]));
6088 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6089 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6090 regno + ! TARGET_LITTLE_ENDIAN),
6091 change_address (mem, SFmode, NULL_RTX),
6097 [(set (match_operand:DF 0 "register_operand" "")
6098 (match_operand:DF 1 "memory_operand" ""))
6099 (use (match_operand:PSI 2 "fpscr_operand" ""))
6100 (clobber (match_scratch:SI 3 ""))]
6101 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6102 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6106 int regno = true_regnum (operands[0]);
6107 rtx addr, insn, adjust = NULL_RTX;
6108 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6109 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6110 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6112 operands[1] = copy_rtx (mem2);
6113 addr = XEXP (mem2, 0);
6114 if (GET_CODE (addr) != POST_INC)
6116 /* If we have to modify the stack pointer, the value that we have
6117 read with post-increment might be modified by an interrupt,
6118 so write it back. */
6119 if (REGNO (addr) == STACK_POINTER_REGNUM)
6120 adjust = gen_push_e (reg0);
6122 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6123 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6125 addr = XEXP (addr, 0);
6126 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6127 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6128 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6132 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6137 [(set (match_operand:DF 0 "memory_operand" "")
6138 (match_operand:DF 1 "register_operand" ""))
6139 (use (match_operand:PSI 2 "fpscr_operand" ""))
6140 (clobber (match_scratch:SI 3 ""))]
6141 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6142 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6146 int regno = true_regnum (operands[1]);
6147 rtx insn, addr, adjust = NULL_RTX;
6149 operands[0] = copy_rtx (operands[0]);
6150 PUT_MODE (operands[0], SFmode);
6151 insn = emit_insn (gen_movsf_ie (operands[0],
6152 gen_rtx_REG (SFmode,
6153 regno + ! TARGET_LITTLE_ENDIAN),
6155 operands[0] = copy_rtx (operands[0]);
6156 addr = XEXP (operands[0], 0);
6157 if (GET_CODE (addr) != PRE_DEC)
6159 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6160 emit_insn_before (adjust, insn);
6161 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6163 addr = XEXP (addr, 0);
6165 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6166 insn = emit_insn (gen_movsf_ie (operands[0],
6167 gen_rtx_REG (SFmode,
6168 regno + !! TARGET_LITTLE_ENDIAN),
6170 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6174 ;; If the output is a register and the input is memory or a register, we have
6175 ;; to be careful and see which word needs to be loaded first.
6178 [(set (match_operand:DF 0 "general_movdst_operand" "")
6179 (match_operand:DF 1 "general_movsrc_operand" ""))]
6180 "TARGET_SH1 && reload_completed"
6181 [(set (match_dup 2) (match_dup 3))
6182 (set (match_dup 4) (match_dup 5))]
6187 if ((GET_CODE (operands[0]) == MEM
6188 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6189 || (GET_CODE (operands[1]) == MEM
6190 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6193 switch (GET_CODE (operands[0]))
6196 regno = REGNO (operands[0]);
6199 regno = subreg_regno (operands[0]);
6209 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6211 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6212 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6213 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6214 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6218 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6219 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6220 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6221 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6224 if (operands[2] == 0 || operands[3] == 0
6225 || operands[4] == 0 || operands[5] == 0)
6229 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6230 ;; used only once, let combine add in the index again.
6233 [(set (match_operand:SI 0 "register_operand" "")
6234 (match_operand:SI 1 "" ""))
6235 (clobber (match_operand 2 "register_operand" ""))]
6236 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6237 && ALLOW_INDEXED_ADDRESS"
6238 [(use (reg:SI R0_REG))]
6241 rtx addr, reg, const_int;
6243 if (GET_CODE (operands[1]) != MEM)
6245 addr = XEXP (operands[1], 0);
6246 if (GET_CODE (addr) != PLUS)
6248 reg = XEXP (addr, 0);
6249 const_int = XEXP (addr, 1);
6250 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6251 && GET_CODE (const_int) == CONST_INT))
6253 emit_move_insn (operands[2], const_int);
6254 emit_move_insn (operands[0],
6255 change_address (operands[1], VOIDmode,
6256 gen_rtx_PLUS (SImode, reg, operands[2])));
6261 [(set (match_operand:SI 1 "" "")
6262 (match_operand:SI 0 "register_operand" ""))
6263 (clobber (match_operand 2 "register_operand" ""))]
6264 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6265 && ALLOW_INDEXED_ADDRESS"
6266 [(use (reg:SI R0_REG))]
6269 rtx addr, reg, const_int;
6271 if (GET_CODE (operands[1]) != MEM)
6273 addr = XEXP (operands[1], 0);
6274 if (GET_CODE (addr) != PLUS)
6276 reg = XEXP (addr, 0);
6277 const_int = XEXP (addr, 1);
6278 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6279 && GET_CODE (const_int) == CONST_INT))
6281 emit_move_insn (operands[2], const_int);
6282 emit_move_insn (change_address (operands[1], VOIDmode,
6283 gen_rtx_PLUS (SImode, reg, operands[2])),
6288 (define_expand "movdf"
6289 [(set (match_operand:DF 0 "general_movdst_operand" "")
6290 (match_operand:DF 1 "general_movsrc_operand" ""))]
6294 if (prepare_move_operands (operands, DFmode)) DONE;
6297 if (TARGET_SHMEDIA_FPU)
6298 emit_insn (gen_movdf_media (operands[0], operands[1]));
6300 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6303 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6305 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6310 ;;This is incompatible with the way gcc uses subregs.
6311 ;;(define_insn "movv2sf_i"
6312 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6313 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6314 ;; "TARGET_SHMEDIA_FPU
6315 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6316 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6320 ;; fst%M0.p %m0, %1"
6321 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6323 (define_insn_and_split "movv2sf_i"
6324 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6325 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6326 "TARGET_SHMEDIA_FPU"
6328 "TARGET_SHMEDIA_FPU && reload_completed"
6329 [(set (match_dup 0) (match_dup 1))]
6332 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6333 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6336 (define_expand "movv2sf"
6337 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6338 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6339 "TARGET_SHMEDIA_FPU"
6342 if (prepare_move_operands (operands, V2SFmode))
6346 (define_expand "addv2sf3"
6347 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6348 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6349 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6350 "TARGET_SHMEDIA_FPU"
6353 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6357 (define_expand "subv2sf3"
6358 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6359 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6360 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6361 "TARGET_SHMEDIA_FPU"
6364 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6368 (define_expand "mulv2sf3"
6369 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6370 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6371 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6372 "TARGET_SHMEDIA_FPU"
6375 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6379 (define_expand "divv2sf3"
6380 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6381 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6382 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6383 "TARGET_SHMEDIA_FPU"
6386 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6390 (define_insn_and_split "*movv4sf_i"
6391 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6392 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6393 "TARGET_SHMEDIA_FPU"
6395 "&& reload_completed"
6401 for (i = 0; i < 4/2; i++)
6405 if (GET_CODE (operands[0]) == MEM)
6406 x = adjust_address (operands[0], V2SFmode,
6407 i * GET_MODE_SIZE (V2SFmode));
6409 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6411 if (GET_CODE (operands[1]) == MEM)
6412 y = adjust_address (operands[1], V2SFmode,
6413 i * GET_MODE_SIZE (V2SFmode));
6415 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6417 emit_insn (gen_movv2sf_i (x, y));
6422 [(set_attr "length" "8")])
6424 (define_expand "movv4sf"
6425 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6426 (match_operand:V4SF 1 "general_operand" ""))]
6427 "TARGET_SHMEDIA_FPU"
6430 if (prepare_move_operands (operands, V4SFmode))
6434 (define_insn_and_split "*movv16sf_i"
6435 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6436 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6437 "TARGET_SHMEDIA_FPU"
6439 "&& reload_completed"
6445 for (i = 0; i < 16/2; i++)
6449 if (GET_CODE (operands[0]) == MEM)
6450 x = adjust_address (operands[0], V2SFmode,
6451 i * GET_MODE_SIZE (V2SFmode));
6454 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6458 if (GET_CODE (operands[1]) == MEM)
6459 y = adjust_address (operands[1], V2SFmode,
6460 i * GET_MODE_SIZE (V2SFmode));
6463 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6467 emit_insn (gen_movv2sf_i (x, y));
6472 [(set_attr "length" "32")])
6474 (define_expand "movv16sf"
6475 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6476 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6477 "TARGET_SHMEDIA_FPU"
6480 if (prepare_move_operands (operands, V16SFmode))
6484 (define_insn "movsf_media"
6485 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6486 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6488 && (register_operand (operands[0], SFmode)
6489 || sh_register_operand (operands[1], SFmode))"
6500 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6501 (set (attr "highpart")
6502 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6503 (const_string "user")]
6504 (const_string "ignore")))])
6506 (define_insn "movsf_media_nofpu"
6507 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6508 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6510 && (register_operand (operands[0], SFmode)
6511 || sh_register_operand (operands[1], SFmode))"
6517 [(set_attr "type" "arith_media,*,load_media,store_media")
6518 (set (attr "highpart")
6519 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6520 (const_string "user")]
6521 (const_string "ignore")))])
6524 [(set (match_operand:SF 0 "arith_reg_dest" "")
6525 (match_operand:SF 1 "immediate_operand" ""))]
6526 "TARGET_SHMEDIA && reload_completed
6527 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6528 [(set (match_dup 3) (match_dup 2))]
6532 REAL_VALUE_TYPE value;
6534 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6535 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6536 operands[2] = GEN_INT (values);
6538 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6541 (define_insn "movsf_i"
6542 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6543 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6546 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6547 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6548 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6549 && (arith_reg_operand (operands[0], SFmode)
6550 || arith_reg_operand (operands[1], SFmode))"
6559 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6561 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6562 ;; update_flow_info would not know where to put REG_EQUAL notes
6563 ;; when the destination changes mode.
6564 (define_insn "movsf_ie"
6565 [(set (match_operand:SF 0 "general_movdst_operand"
6566 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6567 (match_operand:SF 1 "general_movsrc_operand"
6568 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6569 (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"))
6570 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6573 && (arith_reg_operand (operands[0], SFmode)
6574 || arith_reg_operand (operands[1], SFmode)
6575 || arith_reg_operand (operands[3], SImode)
6576 || (fpul_operand (operands[0], SFmode)
6577 && memory_operand (operands[1], SFmode)
6578 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6579 || (fpul_operand (operands[1], SFmode)
6580 && memory_operand (operands[0], SFmode)
6581 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6601 ! move optimized away"
6602 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6603 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6604 (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6605 (set_attr_alternative "length"
6612 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6613 (const_int 4) (const_int 2))
6615 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6616 (const_int 4) (const_int 2))
6629 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6630 (const_string "single")
6631 (const_string "none")))])
6634 [(set (match_operand:SF 0 "register_operand" "")
6635 (match_operand:SF 1 "register_operand" ""))
6636 (use (match_operand:PSI 2 "fpscr_operand" ""))
6637 (clobber (reg:SI FPUL_REG))]
6639 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6641 (clobber (scratch:SI))])
6642 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6644 (clobber (scratch:SI))])]
6647 (define_expand "movsf"
6648 [(set (match_operand:SF 0 "general_movdst_operand" "")
6649 (match_operand:SF 1 "general_movsrc_operand" ""))]
6653 if (prepare_move_operands (operands, SFmode))
6657 if (TARGET_SHMEDIA_FPU)
6658 emit_insn (gen_movsf_media (operands[0], operands[1]));
6660 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6665 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6670 (define_insn "mov_nop"
6671 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6674 [(set_attr "length" "0")
6675 (set_attr "type" "nil")])
6677 (define_expand "reload_insf__frn"
6678 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6679 (match_operand:SF 1 "immediate_operand" "FQ"))
6680 (use (reg:PSI FPSCR_REG))
6681 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6685 (define_expand "reload_insi__i_fpul"
6686 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6687 (match_operand:SI 1 "immediate_operand" "i"))
6688 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6692 (define_expand "ptabs"
6693 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6697 if (!TARGET_PT_FIXED)
6699 rtx eq = operands[1];
6701 /* ??? For canonical RTL we really should remove any CONST from EQ
6702 before wrapping it in the AND, and finally wrap the EQ into a
6703 const if is constant. However, for reload we must expose the
6704 input register or symbolic constant, and we can't have
6705 different insn structures outside of the operands for different
6706 alternatives of the same pattern. */
6707 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6710 = (gen_rtx_IF_THEN_ELSE
6713 gen_rtx_MEM (PDImode, operands[1]),
6714 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6715 PDImode, operands[1])));
6719 ;; expanded by ptabs expander.
6720 (define_insn "*extendsipdi_media"
6721 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6722 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6726 (mem:PDI (match_dup 1))
6727 (sign_extend:PDI (match_dup 1))))]
6728 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6732 [(set_attr "type" "ptabs_media,pt_media")
6733 (set_attr "length" "4,*")])
6735 (define_insn "*truncdipdi_media"
6736 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6737 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6741 (mem:PDI (match_dup 1))
6742 (truncate:PDI (match_dup 1))))]
6743 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6747 [(set_attr "type" "ptabs_media,pt_media")
6748 (set_attr "length" "4,*")])
6750 (define_insn "*movsi_y"
6751 [(set (match_operand:SI 0 "register_operand" "=y,y")
6752 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6753 (clobber (match_scratch:SI 2 "=&z,r"))]
6755 && (reload_in_progress || reload_completed)"
6757 [(set_attr "length" "4")
6758 (set_attr "type" "pcload,move")])
6761 [(set (match_operand:SI 0 "register_operand" "")
6762 (match_operand:SI 1 "immediate_operand" ""))
6763 (clobber (match_operand:SI 2 "register_operand" ""))]
6765 [(set (match_dup 2) (match_dup 1))
6766 (set (match_dup 0) (match_dup 2))]
6770 [(set (match_operand:SI 0 "register_operand" "")
6771 (match_operand:SI 1 "memory_operand" ""))
6772 (clobber (reg:SI R0_REG))]
6774 [(set (match_dup 0) (match_dup 1))]
6777 ;; ------------------------------------------------------------------------
6778 ;; Define the real conditional branch instructions.
6779 ;; ------------------------------------------------------------------------
6781 (define_insn "branch_true"
6782 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6783 (label_ref (match_operand 0 "" ""))
6786 "* return output_branch (1, insn, operands);"
6787 [(set_attr "type" "cbranch")])
6789 (define_insn "branch_false"
6790 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6791 (label_ref (match_operand 0 "" ""))
6794 "* return output_branch (0, insn, operands);"
6795 [(set_attr "type" "cbranch")])
6797 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6798 ;; which destination is too far away.
6799 ;; The const_int_operand is distinct for each branch target; it avoids
6800 ;; unwanted matches with redundant_insn.
6801 (define_insn "block_branch_redirect"
6802 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6805 [(set_attr "length" "0")])
6807 ;; This one has the additional purpose to record a possible scratch register
6808 ;; for the following branch.
6809 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6810 ;; because the insn then might be deemed dead and deleted. And we can't
6811 ;; make the use in the jump insn explicit because that would disable
6812 ;; delay slot scheduling from the target.
6813 (define_insn "indirect_jump_scratch"
6814 [(set (match_operand:SI 0 "register_operand" "=r")
6815 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6816 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6819 [(set_attr "length" "0")])
6821 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6822 ;; being pulled into the delay slot of a condbranch that has been made to
6823 ;; jump around the unconditional jump because it was out of range.
6824 (define_insn "stuff_delay_slot"
6826 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6827 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6830 [(set_attr "length" "0")
6831 (set_attr "cond_delay_slot" "yes")])
6833 ;; Conditional branch insns
6835 (define_expand "beq_media"
6837 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6838 (match_operand:DI 2 "arith_operand" "r,I06"))
6839 (match_operand 0 "" "")
6842 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6844 (define_insn "*beq_media_i"
6846 (if_then_else (match_operator 3 "equality_comparison_operator"
6847 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6848 (match_operand:DI 2 "arith_operand" "r,I06")])
6849 (match_operand 0 "target_operand" "b,b")
6854 b%o3i%' %1, %2, %0%>"
6855 [(set_attr "type" "cbranch_media")])
6857 (define_insn "*beq_media_i32"
6859 (if_then_else (match_operator 3 "equality_comparison_operator"
6860 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6861 (match_operand:SI 2 "arith_operand" "r,I06")])
6862 (match_operand 0 "target_operand" "b,b")
6867 b%o3i%' %1, %2, %0%>"
6868 [(set_attr "type" "cbranch_media")])
6870 (define_expand "bne_media"
6872 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6873 (match_operand:DI 2 "arith_operand" "r,I06"))
6874 (match_operand 0 "" "")
6877 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6879 (define_expand "bgt_media"
6881 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6882 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6883 (match_operand 0 "" "")
6886 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6888 (define_expand "bge_media"
6890 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6891 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6892 (match_operand 0 "" "")
6895 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6897 (define_expand "bgtu_media"
6899 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6900 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6901 (match_operand 0 "" "")
6904 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6906 (define_expand "bgeu_media"
6908 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6909 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6910 (match_operand 0 "" "")
6913 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6915 (define_insn "*bgt_media_i"
6917 (if_then_else (match_operator 3 "greater_comparison_operator"
6918 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6919 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6920 (match_operand 0 "target_operand" "b")
6923 "b%o3%' %N1, %N2, %0%>"
6924 [(set_attr "type" "cbranch_media")])
6926 (define_insn "*bgt_media_i32"
6928 (if_then_else (match_operator 3 "greater_comparison_operator"
6929 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6930 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6931 (match_operand 0 "target_operand" "b")
6934 "b%o3%' %N1, %N2, %0%>"
6935 [(set_attr "type" "cbranch_media")])
6937 ;; These are only needed to make invert_jump() happy - otherwise, jump
6938 ;; optimization will be silently disabled.
6939 (define_insn "*blt_media_i"
6941 (if_then_else (match_operator 3 "less_comparison_operator"
6942 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6943 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6944 (match_operand 0 "target_operand" "b")
6947 "b%o3%' %N2, %N1, %0%>"
6948 [(set_attr "type" "cbranch_media")])
6950 (define_insn "*blt_media_i32"
6952 (if_then_else (match_operator 3 "less_comparison_operator"
6953 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6954 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6955 (match_operand 0 "target_operand" "b")
6958 "b%o3%' %N2, %N1, %0%>"
6959 [(set_attr "type" "cbranch_media")])
6961 (define_expand "beq"
6963 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6964 (label_ref (match_operand 0 "" ""))
6971 enum machine_mode mode = GET_MODE (sh_compare_op0);
6973 if (mode != DImode && mode != SImode)
6975 rtx tmp = gen_reg_rtx (DImode);
6977 emit_insn (gen_seq (tmp));
6978 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6982 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6983 if (CONSTANT_P (sh_compare_op1)
6984 && (GET_CODE (sh_compare_op1) != CONST_INT
6985 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6986 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6987 emit_jump_insn (gen_beq_media (operands[0],
6988 sh_compare_op0, sh_compare_op1));
6992 from_compare (operands, EQ);
6995 (define_expand "bne"
6997 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6998 (label_ref (match_operand 0 "" ""))
7005 enum machine_mode mode = GET_MODE (sh_compare_op0);
7007 if (mode != DImode && mode != SImode)
7009 rtx tmp = gen_reg_rtx (DImode);
7011 emit_insn (gen_seq (tmp));
7012 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7016 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7017 if (CONSTANT_P (sh_compare_op1)
7018 && (GET_CODE (sh_compare_op1) != CONST_INT
7019 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
7020 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7021 emit_jump_insn (gen_bne_media (operands[0],
7022 sh_compare_op0, sh_compare_op1));
7026 from_compare (operands, EQ);
7029 (define_expand "bgt"
7031 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7032 (label_ref (match_operand 0 "" ""))
7039 enum machine_mode mode = GET_MODE (sh_compare_op0);
7041 if (mode != DImode && mode != SImode)
7043 rtx tmp = gen_reg_rtx (DImode);
7045 emit_insn (gen_sgt (tmp));
7046 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7050 if (sh_compare_op0 != const0_rtx)
7051 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7052 if (sh_compare_op1 != const0_rtx)
7053 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7054 emit_jump_insn (gen_bgt_media (operands[0],
7055 sh_compare_op0, sh_compare_op1));
7059 from_compare (operands, GT);
7062 (define_expand "blt"
7064 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7065 (label_ref (match_operand 0 "" ""))
7072 enum machine_mode mode = GET_MODE (sh_compare_op0);
7074 if (mode != DImode && mode != SImode)
7076 rtx tmp = gen_reg_rtx (DImode);
7078 emit_insn (gen_slt (tmp));
7079 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7083 if (sh_compare_op0 != const0_rtx)
7084 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7085 if (sh_compare_op1 != const0_rtx)
7086 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7087 emit_jump_insn (gen_bgt_media (operands[0],
7088 sh_compare_op1, sh_compare_op0));
7092 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7094 rtx tmp = sh_compare_op0;
7095 sh_compare_op0 = sh_compare_op1;
7096 sh_compare_op1 = tmp;
7097 emit_insn (gen_bgt (operands[0]));
7100 from_compare (operands, GE);
7103 (define_expand "ble"
7105 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7106 (label_ref (match_operand 0 "" ""))
7113 enum machine_mode mode = GET_MODE (sh_compare_op0);
7115 if (mode != DImode && mode != SImode)
7117 rtx tmp = gen_reg_rtx (DImode);
7119 emit_insn (gen_sle (tmp));
7120 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7124 if (sh_compare_op0 != const0_rtx)
7125 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7126 if (sh_compare_op1 != const0_rtx)
7127 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7128 emit_jump_insn (gen_bge_media (operands[0],
7129 sh_compare_op1, sh_compare_op0));
7135 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7137 rtx tmp = sh_compare_op0;
7138 sh_compare_op0 = sh_compare_op1;
7139 sh_compare_op1 = tmp;
7140 emit_insn (gen_bge (operands[0]));
7143 from_compare (operands, GT);
7146 (define_expand "bge"
7148 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7149 (label_ref (match_operand 0 "" ""))
7156 enum machine_mode mode = GET_MODE (sh_compare_op0);
7158 if (mode != DImode && mode != SImode)
7160 rtx tmp = gen_reg_rtx (DImode);
7162 emit_insn (gen_sge (tmp));
7163 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7167 if (sh_compare_op0 != const0_rtx)
7168 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7169 if (sh_compare_op1 != const0_rtx)
7170 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7171 emit_jump_insn (gen_bge_media (operands[0],
7172 sh_compare_op0, sh_compare_op1));
7178 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7180 rtx tmp = sh_compare_op0;
7181 sh_compare_op0 = sh_compare_op1;
7182 sh_compare_op1 = tmp;
7183 emit_insn (gen_ble (operands[0]));
7186 from_compare (operands, GE);
7189 (define_expand "bgtu"
7191 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7192 (label_ref (match_operand 0 "" ""))
7199 enum machine_mode mode = GET_MODE (sh_compare_op0);
7201 if (sh_compare_op0 != const0_rtx)
7202 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7203 if (sh_compare_op1 != const0_rtx)
7204 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7205 emit_jump_insn (gen_bgtu_media (operands[0],
7206 sh_compare_op0, sh_compare_op1));
7210 from_compare (operands, GTU);
7213 (define_expand "bltu"
7215 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7216 (label_ref (match_operand 0 "" ""))
7223 enum machine_mode mode = GET_MODE (sh_compare_op0);
7225 if (sh_compare_op0 != const0_rtx)
7226 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7227 if (sh_compare_op1 != const0_rtx)
7228 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7229 emit_jump_insn (gen_bgtu_media (operands[0],
7230 sh_compare_op1, sh_compare_op0));
7234 from_compare (operands, GEU);
7237 (define_expand "bgeu"
7239 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7240 (label_ref (match_operand 0 "" ""))
7247 enum machine_mode mode = GET_MODE (sh_compare_op0);
7249 if (sh_compare_op0 != const0_rtx)
7250 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7251 if (sh_compare_op1 != const0_rtx)
7252 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7253 emit_jump_insn (gen_bgeu_media (operands[0],
7254 sh_compare_op0, sh_compare_op1));
7258 from_compare (operands, GEU);
7261 (define_expand "bleu"
7263 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7264 (label_ref (match_operand 0 "" ""))
7271 enum machine_mode mode = GET_MODE (sh_compare_op0);
7273 if (sh_compare_op0 != const0_rtx)
7274 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7275 if (sh_compare_op1 != const0_rtx)
7276 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7277 emit_jump_insn (gen_bgeu_media (operands[0],
7278 sh_compare_op1, sh_compare_op0));
7282 from_compare (operands, GTU);
7285 (define_expand "bunordered"
7286 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7288 (if_then_else (ne (match_dup 1) (const_int 0))
7289 (match_operand 0 "" "")
7294 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7295 operands[1] = gen_reg_rtx (SImode);
7296 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7297 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7300 ;; combiner splitter for test-and-branch on single bit in register. This
7301 ;; is endian dependent because the non-paradoxical subreg looks different
7306 (match_operator 3 "equality_comparison_operator"
7307 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7308 "extend_reg_operand" "")
7312 "const_int_operand" "")) 0)
7314 (match_operand 0 "target_operand" "")
7316 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7317 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7318 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7319 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7323 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7324 operands[6] = (GET_CODE (operands[3]) == EQ
7325 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7326 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7329 ;; ------------------------------------------------------------------------
7330 ;; Jump and linkage insns
7331 ;; ------------------------------------------------------------------------
7333 (define_insn "jump_compact"
7335 (label_ref (match_operand 0 "" "")))]
7339 /* The length is 16 if the delay slot is unfilled. */
7340 if (get_attr_length(insn) > 4)
7341 return output_far_jump(insn, operands[0]);
7343 return \"bra %l0%#\";
7345 [(set_attr "type" "jump")
7346 (set_attr "needs_delay_slot" "yes")])
7348 ;; ??? It would be much saner to explicitly use the scratch register
7349 ;; in the jump insn, and have indirect_jump_scratch only set it,
7350 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7351 ;; from the target then, as it uses simplejump_p.
7352 ;;(define_insn "jump_compact_far"
7354 ;; (label_ref (match_operand 0 "" "")))
7355 ;; (use (match_operand 1 "register_operand" "r")]
7357 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7358 ;; [(set_attr "type" "jump")
7359 ;; (set_attr "needs_delay_slot" "yes")])
7361 (define_insn "jump_media"
7363 (match_operand 0 "target_operand" "b"))]
7366 [(set_attr "type" "jump_media")])
7368 (define_expand "jump"
7370 (label_ref (match_operand 0 "" "")))]
7375 emit_jump_insn (gen_jump_compact (operands[0]));
7376 else if (TARGET_SHMEDIA)
7378 if (reload_in_progress || reload_completed)
7380 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7386 (define_insn "force_mode_for_call"
7387 [(use (reg:PSI FPSCR_REG))]
7390 [(set_attr "length" "0")
7391 (set (attr "fp_mode")
7392 (if_then_else (eq_attr "fpu_single" "yes")
7393 (const_string "single") (const_string "double")))])
7395 (define_insn "calli"
7396 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7397 (match_operand 1 "" ""))
7398 (use (reg:PSI FPSCR_REG))
7399 (clobber (reg:SI PR_REG))]
7402 [(set_attr "type" "call")
7403 (set (attr "fp_mode")
7404 (if_then_else (eq_attr "fpu_single" "yes")
7405 (const_string "single") (const_string "double")))
7406 (set_attr "needs_delay_slot" "yes")
7407 (set_attr "fp_set" "unknown")])
7409 ;; This is a pc-rel call, using bsrf, for use with PIC.
7411 (define_insn "calli_pcrel"
7412 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7413 (match_operand 1 "" ""))
7414 (use (reg:PSI FPSCR_REG))
7415 (use (reg:SI PIC_REG))
7416 (use (match_operand 2 "" ""))
7417 (clobber (reg:SI PR_REG))]
7420 [(set_attr "type" "call")
7421 (set (attr "fp_mode")
7422 (if_then_else (eq_attr "fpu_single" "yes")
7423 (const_string "single") (const_string "double")))
7424 (set_attr "needs_delay_slot" "yes")
7425 (set_attr "fp_set" "unknown")])
7427 (define_insn_and_split "call_pcrel"
7428 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7429 (match_operand 1 "" ""))
7430 (use (reg:PSI FPSCR_REG))
7431 (use (reg:SI PIC_REG))
7432 (clobber (reg:SI PR_REG))
7433 (clobber (match_scratch:SI 2 "=r"))]
7440 rtx lab = PATTERN (gen_call_site ());
7442 if (SYMBOL_REF_LOCAL_P (operands[0]))
7443 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7445 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7446 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7449 [(set_attr "type" "call")
7450 (set (attr "fp_mode")
7451 (if_then_else (eq_attr "fpu_single" "yes")
7452 (const_string "single") (const_string "double")))
7453 (set_attr "needs_delay_slot" "yes")
7454 (set_attr "fp_set" "unknown")])
7456 (define_insn "call_compact"
7457 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7458 (match_operand 1 "" ""))
7459 (match_operand 2 "immediate_operand" "n")
7460 (use (reg:SI R0_REG))
7461 (use (reg:SI R1_REG))
7462 (use (reg:PSI FPSCR_REG))
7463 (clobber (reg:SI PR_REG))]
7464 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7466 [(set_attr "type" "call")
7467 (set (attr "fp_mode")
7468 (if_then_else (eq_attr "fpu_single" "yes")
7469 (const_string "single") (const_string "double")))
7470 (set_attr "needs_delay_slot" "yes")])
7472 (define_insn "call_compact_rettramp"
7473 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7474 (match_operand 1 "" ""))
7475 (match_operand 2 "immediate_operand" "n")
7476 (use (reg:SI R0_REG))
7477 (use (reg:SI R1_REG))
7478 (use (reg:PSI FPSCR_REG))
7479 (clobber (reg:SI R10_REG))
7480 (clobber (reg:SI PR_REG))]
7481 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7483 [(set_attr "type" "call")
7484 (set (attr "fp_mode")
7485 (if_then_else (eq_attr "fpu_single" "yes")
7486 (const_string "single") (const_string "double")))
7487 (set_attr "needs_delay_slot" "yes")])
7489 (define_insn "call_media"
7490 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7491 (match_operand 1 "" ""))
7492 (clobber (reg:DI PR_MEDIA_REG))]
7495 [(set_attr "type" "jump_media")])
7497 (define_insn "call_valuei"
7498 [(set (match_operand 0 "" "=rf")
7499 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7500 (match_operand 2 "" "")))
7501 (use (reg:PSI FPSCR_REG))
7502 (clobber (reg:SI PR_REG))]
7505 [(set_attr "type" "call")
7506 (set (attr "fp_mode")
7507 (if_then_else (eq_attr "fpu_single" "yes")
7508 (const_string "single") (const_string "double")))
7509 (set_attr "needs_delay_slot" "yes")
7510 (set_attr "fp_set" "unknown")])
7512 (define_insn "call_valuei_pcrel"
7513 [(set (match_operand 0 "" "=rf")
7514 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7515 (match_operand 2 "" "")))
7516 (use (reg:PSI FPSCR_REG))
7517 (use (reg:SI PIC_REG))
7518 (use (match_operand 3 "" ""))
7519 (clobber (reg:SI PR_REG))]
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")
7527 (set_attr "fp_set" "unknown")])
7529 (define_insn_and_split "call_value_pcrel"
7530 [(set (match_operand 0 "" "=rf")
7531 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7532 (match_operand 2 "" "")))
7533 (use (reg:PSI FPSCR_REG))
7534 (use (reg:SI PIC_REG))
7535 (clobber (reg:SI PR_REG))
7536 (clobber (match_scratch:SI 3 "=r"))]
7543 rtx lab = PATTERN (gen_call_site ());
7545 if (SYMBOL_REF_LOCAL_P (operands[1]))
7546 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7548 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7549 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7550 operands[2], copy_rtx (lab)));
7553 [(set_attr "type" "call")
7554 (set (attr "fp_mode")
7555 (if_then_else (eq_attr "fpu_single" "yes")
7556 (const_string "single") (const_string "double")))
7557 (set_attr "needs_delay_slot" "yes")
7558 (set_attr "fp_set" "unknown")])
7560 (define_insn "call_value_compact"
7561 [(set (match_operand 0 "" "=rf")
7562 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7563 (match_operand 2 "" "")))
7564 (match_operand 3 "immediate_operand" "n")
7565 (use (reg:SI R0_REG))
7566 (use (reg:SI R1_REG))
7567 (use (reg:PSI FPSCR_REG))
7568 (clobber (reg:SI PR_REG))]
7569 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7571 [(set_attr "type" "call")
7572 (set (attr "fp_mode")
7573 (if_then_else (eq_attr "fpu_single" "yes")
7574 (const_string "single") (const_string "double")))
7575 (set_attr "needs_delay_slot" "yes")])
7577 (define_insn "call_value_compact_rettramp"
7578 [(set (match_operand 0 "" "=rf")
7579 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7580 (match_operand 2 "" "")))
7581 (match_operand 3 "immediate_operand" "n")
7582 (use (reg:SI R0_REG))
7583 (use (reg:SI R1_REG))
7584 (use (reg:PSI FPSCR_REG))
7585 (clobber (reg:SI R10_REG))
7586 (clobber (reg:SI PR_REG))]
7587 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7589 [(set_attr "type" "call")
7590 (set (attr "fp_mode")
7591 (if_then_else (eq_attr "fpu_single" "yes")
7592 (const_string "single") (const_string "double")))
7593 (set_attr "needs_delay_slot" "yes")])
7595 (define_insn "call_value_media"
7596 [(set (match_operand 0 "" "=rf")
7597 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7598 (match_operand 2 "" "")))
7599 (clobber (reg:DI PR_MEDIA_REG))]
7602 [(set_attr "type" "jump_media")])
7604 (define_expand "call"
7605 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7606 (match_operand 1 "" ""))
7607 (match_operand 2 "" "")
7608 (use (reg:PSI FPSCR_REG))
7609 (clobber (reg:SI PR_REG))])]
7615 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7616 emit_call_insn (gen_call_media (operands[0], operands[1]));
7619 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7621 rtx cookie_rtx = operands[2];
7622 long cookie = INTVAL (cookie_rtx);
7623 rtx func = XEXP (operands[0], 0);
7628 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7630 rtx reg = gen_reg_rtx (Pmode);
7632 emit_insn (gen_symGOTPLT2reg (reg, func));
7636 func = legitimize_pic_address (func, Pmode, 0);
7639 r0 = gen_rtx_REG (SImode, R0_REG);
7640 r1 = gen_rtx_REG (SImode, R1_REG);
7642 /* Since such a call function may use all call-clobbered
7643 registers, we force a mode switch earlier, so that we don't
7644 run out of registers when adjusting fpscr for the call. */
7645 emit_insn (gen_force_mode_for_call ());
7648 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7650 operands[0] = force_reg (SImode, operands[0]);
7652 emit_move_insn (r0, func);
7653 emit_move_insn (r1, cookie_rtx);
7655 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7656 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7659 emit_call_insn (gen_call_compact (operands[0], operands[1],
7664 else if (TARGET_SHCOMPACT && flag_pic
7665 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7666 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7668 rtx reg = gen_reg_rtx (Pmode);
7670 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7671 XEXP (operands[0], 0) = reg;
7673 if (flag_pic && TARGET_SH2
7674 && GET_CODE (operands[0]) == MEM
7675 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7677 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7682 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7683 operands[1] = operands[2];
7686 emit_call_insn (gen_calli (operands[0], operands[1]));
7690 (define_insn "call_pop_compact"
7691 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7692 (match_operand 1 "" ""))
7693 (match_operand 2 "immediate_operand" "n")
7694 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7695 (match_operand 3 "immediate_operand" "n")))
7696 (use (reg:SI R0_REG))
7697 (use (reg:SI R1_REG))
7698 (use (reg:PSI FPSCR_REG))
7699 (clobber (reg:SI PR_REG))]
7700 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7702 [(set_attr "type" "call")
7703 (set (attr "fp_mode")
7704 (if_then_else (eq_attr "fpu_single" "yes")
7705 (const_string "single") (const_string "double")))
7706 (set_attr "needs_delay_slot" "yes")])
7708 (define_insn "call_pop_compact_rettramp"
7709 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7710 (match_operand 1 "" ""))
7711 (match_operand 2 "immediate_operand" "n")
7712 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7713 (match_operand 3 "immediate_operand" "n")))
7714 (use (reg:SI R0_REG))
7715 (use (reg:SI R1_REG))
7716 (use (reg:PSI FPSCR_REG))
7717 (clobber (reg:SI R10_REG))
7718 (clobber (reg:SI PR_REG))]
7719 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7721 [(set_attr "type" "call")
7722 (set (attr "fp_mode")
7723 (if_then_else (eq_attr "fpu_single" "yes")
7724 (const_string "single") (const_string "double")))
7725 (set_attr "needs_delay_slot" "yes")])
7727 (define_expand "call_pop"
7728 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7729 (match_operand 1 "" ""))
7730 (match_operand 2 "" "")
7731 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7732 (match_operand 3 "" "")))])]
7741 gcc_assert (operands[2] && INTVAL (operands[2]));
7742 cookie_rtx = operands[2];
7743 cookie = INTVAL (cookie_rtx);
7744 func = XEXP (operands[0], 0);
7748 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7750 rtx reg = gen_reg_rtx (Pmode);
7751 emit_insn (gen_symGOTPLT2reg (reg, func));
7755 func = legitimize_pic_address (func, Pmode, 0);
7758 r0 = gen_rtx_REG (SImode, R0_REG);
7759 r1 = gen_rtx_REG (SImode, R1_REG);
7761 /* Since such a call function may use all call-clobbered
7762 registers, we force a mode switch earlier, so that we don't
7763 run out of registers when adjusting fpscr for the call. */
7764 emit_insn (gen_force_mode_for_call ());
7766 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7768 operands[0] = force_reg (SImode, operands[0]);
7770 emit_move_insn (r0, func);
7771 emit_move_insn (r1, cookie_rtx);
7773 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7774 emit_call_insn (gen_call_pop_compact_rettramp
7775 (operands[0], operands[1], operands[2], operands[3]));
7777 emit_call_insn (gen_call_pop_compact
7778 (operands[0], operands[1], operands[2], operands[3]));
7783 (define_expand "call_value"
7784 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7785 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7786 (match_operand 2 "" "")))
7787 (match_operand 3 "" "")
7788 (use (reg:PSI FPSCR_REG))
7789 (clobber (reg:SI PR_REG))])]
7795 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7796 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7800 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7802 rtx cookie_rtx = operands[3];
7803 long cookie = INTVAL (cookie_rtx);
7804 rtx func = XEXP (operands[1], 0);
7809 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7811 rtx reg = gen_reg_rtx (Pmode);
7813 emit_insn (gen_symGOTPLT2reg (reg, func));
7817 func = legitimize_pic_address (func, Pmode, 0);
7820 r0 = gen_rtx_REG (SImode, R0_REG);
7821 r1 = gen_rtx_REG (SImode, R1_REG);
7823 /* Since such a call function may use all call-clobbered
7824 registers, we force a mode switch earlier, so that we don't
7825 run out of registers when adjusting fpscr for the call. */
7826 emit_insn (gen_force_mode_for_call ());
7829 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7831 operands[1] = force_reg (SImode, operands[1]);
7833 emit_move_insn (r0, func);
7834 emit_move_insn (r1, cookie_rtx);
7836 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7837 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7842 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7843 operands[2], operands[3]));
7847 else if (TARGET_SHCOMPACT && flag_pic
7848 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7849 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7851 rtx reg = gen_reg_rtx (Pmode);
7853 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7854 XEXP (operands[1], 0) = reg;
7856 if (flag_pic && TARGET_SH2
7857 && GET_CODE (operands[1]) == MEM
7858 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7860 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7865 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7867 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7871 (define_insn "sibcalli"
7872 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7873 (match_operand 1 "" ""))
7874 (use (reg:PSI FPSCR_REG))
7878 [(set_attr "needs_delay_slot" "yes")
7879 (set (attr "fp_mode")
7880 (if_then_else (eq_attr "fpu_single" "yes")
7881 (const_string "single") (const_string "double")))
7882 (set_attr "type" "jump_ind")])
7884 (define_insn "sibcalli_pcrel"
7885 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7886 (match_operand 1 "" ""))
7887 (use (match_operand 2 "" ""))
7888 (use (reg:PSI FPSCR_REG))
7892 [(set_attr "needs_delay_slot" "yes")
7893 (set (attr "fp_mode")
7894 (if_then_else (eq_attr "fpu_single" "yes")
7895 (const_string "single") (const_string "double")))
7896 (set_attr "type" "jump_ind")])
7898 ;; This uses an unspec to describe that the symbol_ref is very close.
7899 (define_insn "sibcalli_thunk"
7900 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7902 (match_operand 1 "" ""))
7903 (use (reg:PSI FPSCR_REG))
7907 [(set_attr "needs_delay_slot" "yes")
7908 (set (attr "fp_mode")
7909 (if_then_else (eq_attr "fpu_single" "yes")
7910 (const_string "single") (const_string "double")))
7911 (set_attr "type" "jump")
7912 (set_attr "length" "2")])
7914 (define_insn_and_split "sibcall_pcrel"
7915 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7916 (match_operand 1 "" ""))
7917 (use (reg:PSI FPSCR_REG))
7918 (clobber (match_scratch:SI 2 "=k"))
7926 rtx lab = PATTERN (gen_call_site ());
7929 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7930 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7932 SIBLING_CALL_P (call_insn) = 1;
7935 [(set_attr "needs_delay_slot" "yes")
7936 (set (attr "fp_mode")
7937 (if_then_else (eq_attr "fpu_single" "yes")
7938 (const_string "single") (const_string "double")))
7939 (set_attr "type" "jump_ind")])
7941 (define_insn "sibcall_compact"
7942 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7943 (match_operand 1 "" ""))
7945 (use (match_operand:SI 2 "register_operand" "z,x"))
7946 (use (reg:SI R1_REG))
7947 (use (reg:PSI FPSCR_REG))
7948 ;; We want to make sure the `x' above will only match MACH_REG
7949 ;; because sibcall_epilogue may clobber MACL_REG.
7950 (clobber (reg:SI MACL_REG))]
7954 jmp @%0\\n sts %2, r0"
7955 [(set_attr "needs_delay_slot" "yes,no")
7956 (set_attr "length" "2,4")
7957 (set (attr "fp_mode") (const_string "single"))
7958 (set_attr "type" "jump_ind")])
7960 (define_insn "sibcall_media"
7961 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7962 (match_operand 1 "" ""))
7963 (use (reg:SI PR_MEDIA_REG))
7967 [(set_attr "type" "jump_media")])
7969 (define_expand "sibcall"
7971 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7972 (match_operand 1 "" ""))
7973 (match_operand 2 "" "")
7974 (use (reg:PSI FPSCR_REG))
7981 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7982 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7985 else if (TARGET_SHCOMPACT && operands[2]
7986 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7988 rtx cookie_rtx = operands[2];
7989 long cookie = INTVAL (cookie_rtx);
7990 rtx func = XEXP (operands[0], 0);
7995 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7997 rtx reg = gen_reg_rtx (Pmode);
7999 emit_insn (gen_symGOT2reg (reg, func));
8003 func = legitimize_pic_address (func, Pmode, 0);
8006 /* FIXME: if we could tell whether all argument registers are
8007 already taken, we could decide whether to force the use of
8008 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8009 simple way to tell. We could use the CALL_COOKIE, but we
8010 can't currently tell a register used for regular argument
8011 passing from one that is unused. If we leave it up to reload
8012 to decide which register to use, it seems to always choose
8013 R0_REG, which leaves no available registers in SIBCALL_REGS
8014 to hold the address of the trampoline. */
8015 mach = gen_rtx_REG (SImode, MACH_REG);
8016 r1 = gen_rtx_REG (SImode, R1_REG);
8018 /* Since such a call function may use all call-clobbered
8019 registers, we force a mode switch earlier, so that we don't
8020 run out of registers when adjusting fpscr for the call. */
8021 emit_insn (gen_force_mode_for_call ());
8024 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8026 operands[0] = force_reg (SImode, operands[0]);
8028 /* We don't need a return trampoline, since the callee will
8029 return directly to the upper caller. */
8030 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8032 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8033 cookie_rtx = GEN_INT (cookie);
8036 emit_move_insn (mach, func);
8037 emit_move_insn (r1, cookie_rtx);
8039 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8042 else if (TARGET_SHCOMPACT && flag_pic
8043 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8044 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8046 rtx reg = gen_reg_rtx (Pmode);
8048 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8049 XEXP (operands[0], 0) = reg;
8051 if (flag_pic && TARGET_SH2
8052 && GET_CODE (operands[0]) == MEM
8053 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8054 /* The PLT needs the PIC register, but the epilogue would have
8055 to restore it, so we can only use PC-relative PIC calls for
8056 static functions. */
8057 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8059 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8063 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8065 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8069 (define_expand "sibcall_value"
8070 [(set (match_operand 0 "" "")
8071 (call (match_operand 1 "" "")
8072 (match_operand 2 "" "")))
8073 (match_operand 3 "" "")]
8077 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
8081 (define_insn "call_value_pop_compact"
8082 [(set (match_operand 0 "" "=rf")
8083 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8084 (match_operand 2 "" "")))
8085 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8086 (match_operand 4 "immediate_operand" "n")))
8087 (match_operand 3 "immediate_operand" "n")
8088 (use (reg:SI R0_REG))
8089 (use (reg:SI R1_REG))
8090 (use (reg:PSI FPSCR_REG))
8091 (clobber (reg:SI PR_REG))]
8092 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8094 [(set_attr "type" "call")
8095 (set (attr "fp_mode")
8096 (if_then_else (eq_attr "fpu_single" "yes")
8097 (const_string "single") (const_string "double")))
8098 (set_attr "needs_delay_slot" "yes")])
8100 (define_insn "call_value_pop_compact_rettramp"
8101 [(set (match_operand 0 "" "=rf")
8102 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8103 (match_operand 2 "" "")))
8104 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8105 (match_operand 4 "immediate_operand" "n")))
8106 (match_operand 3 "immediate_operand" "n")
8107 (use (reg:SI R0_REG))
8108 (use (reg:SI R1_REG))
8109 (use (reg:PSI FPSCR_REG))
8110 (clobber (reg:SI R10_REG))
8111 (clobber (reg:SI PR_REG))]
8112 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8114 [(set_attr "type" "call")
8115 (set (attr "fp_mode")
8116 (if_then_else (eq_attr "fpu_single" "yes")
8117 (const_string "single") (const_string "double")))
8118 (set_attr "needs_delay_slot" "yes")])
8120 (define_expand "call_value_pop"
8121 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8122 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8123 (match_operand 2 "" "")))
8124 (match_operand 3 "" "")
8125 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8126 (match_operand 4 "" "")))])]
8135 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8136 cookie_rtx = operands[3];
8137 cookie = INTVAL (cookie_rtx);
8138 func = XEXP (operands[1], 0);
8142 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8144 rtx reg = gen_reg_rtx (Pmode);
8146 emit_insn (gen_symGOTPLT2reg (reg, func));
8150 func = legitimize_pic_address (func, Pmode, 0);
8153 r0 = gen_rtx_REG (SImode, R0_REG);
8154 r1 = gen_rtx_REG (SImode, R1_REG);
8156 /* Since such a call function may use all call-clobbered
8157 registers, we force a mode switch earlier, so that we don't
8158 run out of registers when adjusting fpscr for the call. */
8159 emit_insn (gen_force_mode_for_call ());
8161 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8163 operands[1] = force_reg (SImode, operands[1]);
8165 emit_move_insn (r0, func);
8166 emit_move_insn (r1, cookie_rtx);
8168 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8169 emit_call_insn (gen_call_value_pop_compact_rettramp
8170 (operands[0], operands[1], operands[2],
8171 operands[3], operands[4]));
8173 emit_call_insn (gen_call_value_pop_compact
8174 (operands[0], operands[1], operands[2],
8175 operands[3], operands[4]));
8180 (define_expand "sibcall_epilogue"
8185 sh_expand_epilogue (1);
8186 if (TARGET_SHCOMPACT)
8190 /* If epilogue clobbers r0, preserve it in macl. */
8191 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8192 if ((set = single_set (insn))
8193 && GET_CODE (SET_DEST (set)) == REG
8194 && REGNO (SET_DEST (set)) == R0_REG)
8196 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8197 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8200 /* We can't tell at this point whether the sibcall is a
8201 sibcall_compact and, if it is, whether it uses r0 or
8202 mach as operand 2, so let the instructions that
8203 preserve r0 be optimized away if r0 turns out to be
8205 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8206 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8208 i = emit_move_insn (r0, tmp);
8209 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8217 (define_insn "indirect_jump_compact"
8219 (match_operand:SI 0 "arith_reg_operand" "r"))]
8222 [(set_attr "needs_delay_slot" "yes")
8223 (set_attr "type" "jump_ind")])
8225 (define_expand "indirect_jump"
8227 (match_operand 0 "register_operand" ""))]
8231 if (GET_MODE (operands[0]) != Pmode)
8232 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8235 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8236 ;; which can be present in structured code from indirect jumps which can not
8237 ;; be present in structured code. This allows -fprofile-arcs to work.
8239 ;; For SH1 processors.
8240 (define_insn "casesi_jump_1"
8242 (match_operand:SI 0 "register_operand" "r"))
8243 (use (label_ref (match_operand 1 "" "")))]
8246 [(set_attr "needs_delay_slot" "yes")
8247 (set_attr "type" "jump_ind")])
8249 ;; For all later processors.
8250 (define_insn "casesi_jump_2"
8251 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8252 (label_ref (match_operand 1 "" ""))))
8253 (use (label_ref (match_operand 2 "" "")))]
8255 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8257 [(set_attr "needs_delay_slot" "yes")
8258 (set_attr "type" "jump_ind")])
8260 (define_insn "casesi_jump_media"
8261 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8262 (use (label_ref (match_operand 1 "" "")))]
8265 [(set_attr "type" "jump_media")])
8267 ;; Call subroutine returning any type.
8268 ;; ??? This probably doesn't work.
8270 (define_expand "untyped_call"
8271 [(parallel [(call (match_operand 0 "" "")
8273 (match_operand 1 "" "")
8274 (match_operand 2 "" "")])]
8275 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8280 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8282 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8284 rtx set = XVECEXP (operands[2], 0, i);
8285 emit_move_insn (SET_DEST (set), SET_SRC (set));
8288 /* The optimizer does not know that the call sets the function value
8289 registers we stored in the result block. We avoid problems by
8290 claiming that all hard registers are used and clobbered at this
8292 emit_insn (gen_blockage ());
8297 ;; ------------------------------------------------------------------------
8299 ;; ------------------------------------------------------------------------
8302 [(set (reg:SI T_REG)
8303 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8304 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8307 [(set_attr "type" "arith")])
8314 ;; Load address of a label. This is only generated by the casesi expand,
8315 ;; and by machine_dependent_reorg (fixing up fp moves).
8316 ;; This must use unspec, because this only works for labels that are
8320 [(set (reg:SI R0_REG)
8321 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8324 [(set_attr "in_delay_slot" "no")
8325 (set_attr "type" "arith")])
8327 ;; machine_dependent_reorg will make this a `mova'.
8328 (define_insn "mova_const"
8329 [(set (reg:SI R0_REG)
8330 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8333 [(set_attr "in_delay_slot" "no")
8334 (set_attr "type" "arith")])
8336 (define_expand "GOTaddr2picreg"
8337 [(set (reg:SI R0_REG)
8338 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8340 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8341 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8344 if (TARGET_VXWORKS_RTP)
8346 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8347 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8348 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8352 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8353 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8357 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8358 rtx pic = operands[0];
8359 rtx lab = PATTERN (gen_call_site ());
8362 equiv = operands[1];
8363 operands[1] = gen_rtx_MINUS (Pmode,
8367 gen_rtx_MINUS (Pmode,
8368 gen_rtx_CONST (Pmode,
8371 operands[1] = gen_sym2PIC (operands[1]);
8372 PUT_MODE (operands[1], Pmode);
8374 if (Pmode == SImode)
8376 emit_insn (gen_movsi_const (pic, operands[1]));
8377 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8381 emit_insn (gen_movdi_const (pic, operands[1]));
8382 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8385 insn = emit_move_insn (operands[0], tr);
8387 set_unique_reg_note (insn, REG_EQUAL, equiv);
8394 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8397 (define_expand "vxworks_picreg"
8398 [(set (reg:SI PIC_REG)
8399 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8400 (set (reg:SI R0_REG)
8401 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8402 (set (reg:SI PIC_REG)
8403 (mem:SI (reg:SI PIC_REG)))
8404 (set (reg:SI PIC_REG)
8405 (mem:SI (plus:SI (reg:SI PIC_REG)
8407 "TARGET_VXWORKS_RTP")
8410 [(set (match_operand 0 "target_reg_operand" "=b")
8411 (const (unspec [(match_operand 1 "" "Csy")]
8412 UNSPEC_DATALABEL)))]
8413 "TARGET_SHMEDIA && flag_pic
8414 && EXTRA_CONSTRAINT_Csy (operands[1])"
8415 "ptb/u datalabel %1, %0"
8416 [(set_attr "type" "ptabs_media")
8417 (set_attr "length" "*")])
8419 (define_insn "ptrel_si"
8420 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8421 (plus:SI (match_operand:SI 1 "register_operand" "r")
8423 (match_operand:SI 2 "" "")]
8425 "%O2: ptrel/u %1, %0"
8426 [(set_attr "type" "ptabs_media")])
8428 (define_insn "ptrel_di"
8429 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8430 (plus:DI (match_operand:DI 1 "register_operand" "r")
8432 (match_operand:DI 2 "" "")]
8434 "%O2: ptrel/u %1, %0"
8435 [(set_attr "type" "ptabs_media")])
8437 (define_expand "builtin_setjmp_receiver"
8438 [(match_operand 0 "" "")]
8442 emit_insn (gen_GOTaddr2picreg ());
8446 (define_expand "call_site"
8447 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8451 static HOST_WIDE_INT i = 0;
8452 operands[0] = GEN_INT (i);
8456 (define_expand "sym_label2reg"
8457 [(set (match_operand:SI 0 "" "")
8460 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8463 (match_operand:SI 2 "" "")
8467 (define_expand "symGOT_load"
8468 [(set (match_dup 2) (match_operand 1 "" ""))
8469 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8470 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8476 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8477 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8481 rtx reg = operands[2];
8483 if (Pmode == DImode)
8486 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8488 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8493 emit_insn (gen_movsi_const (reg, operands[1]));
8495 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8499 emit_move_insn (operands[2], operands[1]);
8501 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8503 gen_rtx_REG (Pmode, PIC_REG)));
8505 /* N.B. This is not constant for a GOTPLT relocation. */
8506 mem = gen_rtx_MEM (Pmode, operands[3]);
8507 MEM_NOTRAP_P (mem) = 1;
8508 /* ??? Should we have a special alias set for the GOT? */
8509 insn = emit_move_insn (operands[0], mem);
8511 set_unique_reg_note (insn, REG_EQUAL,
8512 XVECEXP (XEXP (operands[1], 0), 0, 0));
8517 (define_expand "sym2GOT"
8518 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8522 (define_expand "symGOT2reg"
8523 [(match_operand 0 "" "") (match_operand 1 "" "")]
8529 gotsym = gen_sym2GOT (operands[1]);
8530 PUT_MODE (gotsym, Pmode);
8531 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8533 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8538 (define_expand "symGOTPLT2reg"
8539 [(match_operand 0 "" "") (match_operand 1 "" "")]
8543 rtx pltsym = gen_rtx_CONST (Pmode,
8544 gen_rtx_UNSPEC (Pmode,
8545 gen_rtvec (1, operands[1]),
8547 emit_insn (gen_symGOT_load (operands[0], pltsym));
8551 (define_expand "sym2GOTOFF"
8552 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8556 (define_expand "symGOTOFF2reg"
8557 [(match_operand 0 "" "") (match_operand 1 "" "")]
8561 rtx gotoffsym, insn;
8562 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8564 gotoffsym = gen_sym2GOTOFF (operands[1]);
8565 PUT_MODE (gotoffsym, Pmode);
8566 emit_move_insn (t, gotoffsym);
8567 insn = emit_move_insn (operands[0],
8568 gen_rtx_PLUS (Pmode, t,
8569 gen_rtx_REG (Pmode, PIC_REG)));
8571 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8576 (define_expand "symPLT_label2reg"
8577 [(set (match_operand:SI 0 "" "")
8580 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8584 (match_operand:SI 2 "" "")
8586 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8587 ;; Even though the PIC register is not really used by the call
8588 ;; sequence in which this is expanded, the PLT code assumes the PIC
8589 ;; register is set, so we must not skip its initialization. Since
8590 ;; we only use this expand as part of calling sequences, and never
8591 ;; to take the address of a function, this is the best point to
8592 ;; insert the (use). Using the PLT to take the address of a
8593 ;; function would be wrong, not only because the PLT entry could
8594 ;; then be called from a function that doesn't initialize the PIC
8595 ;; register to the proper GOT, but also because pointers to the
8596 ;; same function might not compare equal, should they be set by
8597 ;; different shared libraries.
8598 (use (reg:SI PIC_REG))]
8602 (define_expand "sym2PIC"
8603 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8607 ;; TLS code generation.
8608 ;; ??? this should be a define_insn_and_split
8609 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8610 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8613 (define_insn "tls_global_dynamic"
8614 [(set (match_operand:SI 0 "register_operand" "=&z")
8615 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8618 (use (reg:PSI FPSCR_REG))
8619 (use (reg:SI PIC_REG))
8620 (clobber (reg:SI PR_REG))
8621 (clobber (scratch:SI))]
8627 \\tmova\\t2f,r0\\n\\
8628 \\tmov.l\\t2f,r1\\n\\
8631 \\tadd\\tr12,r4\\n\\
8635 1:\\t.long\\t%a1@TLSGD\\n\\
8636 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8639 [(set_attr "type" "tls_load")
8640 (set_attr "length" "26")])
8642 (define_insn "tls_local_dynamic"
8643 [(set (match_operand:SI 0 "register_operand" "=&z")
8644 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8647 (use (reg:PSI FPSCR_REG))
8648 (use (reg:SI PIC_REG))
8649 (clobber (reg:SI PR_REG))
8650 (clobber (scratch:SI))]
8656 \\tmova\\t2f,r0\\n\\
8657 \\tmov.l\\t2f,r1\\n\\
8660 \\tadd\\tr12,r4\\n\\
8664 1:\\t.long\\t%a1@TLSLDM\\n\\
8665 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8668 [(set_attr "type" "tls_load")
8669 (set_attr "length" "26")])
8671 (define_expand "sym2DTPOFF"
8672 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8676 (define_expand "symDTPOFF2reg"
8677 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8681 rtx dtpoffsym, insn;
8682 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8684 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8685 PUT_MODE (dtpoffsym, Pmode);
8686 emit_move_insn (t, dtpoffsym);
8687 insn = emit_move_insn (operands[0],
8688 gen_rtx_PLUS (Pmode, t, operands[2]));
8692 (define_expand "sym2GOTTPOFF"
8693 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8697 (define_insn "tls_initial_exec"
8698 [(set (match_operand:SI 0 "register_operand" "=&r")
8699 (unspec:SI [(match_operand:SI 1 "" "")]
8701 (use (reg:SI GBR_REG))
8702 (use (reg:SI PIC_REG))
8703 (clobber (reg:SI R0_REG))]
8709 \\tstc\\tgbr,%0\\n\\
8710 \\tmov.l\\t@(r0,r12),r0\\n\\
8714 1:\\t.long\\t%a1\\n\\
8717 [(set_attr "type" "tls_load")
8718 (set_attr "length" "16")])
8720 (define_expand "sym2TPOFF"
8721 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8725 (define_expand "symTPOFF2reg"
8726 [(match_operand 0 "" "") (match_operand 1 "" "")]
8732 tpoffsym = gen_sym2TPOFF (operands[1]);
8733 PUT_MODE (tpoffsym, Pmode);
8734 insn = emit_move_insn (operands[0], tpoffsym);
8738 (define_insn "load_gbr"
8739 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8740 (use (reg:SI GBR_REG))]
8743 [(set_attr "type" "tls_load")])
8745 ;; case instruction for switch statements.
8747 ;; Operand 0 is index
8748 ;; operand 1 is the minimum bound
8749 ;; operand 2 is the maximum bound - minimum bound + 1
8750 ;; operand 3 is CODE_LABEL for the table;
8751 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8753 (define_expand "casesi"
8754 [(match_operand:SI 0 "arith_reg_operand" "")
8755 (match_operand:SI 1 "arith_reg_operand" "")
8756 (match_operand:SI 2 "arith_reg_operand" "")
8757 (match_operand 3 "" "") (match_operand 4 "" "")]
8761 rtx reg = gen_reg_rtx (SImode);
8762 rtx reg2 = gen_reg_rtx (SImode);
8765 rtx reg = gen_reg_rtx (DImode);
8766 rtx reg2 = gen_reg_rtx (DImode);
8767 rtx reg3 = gen_reg_rtx (Pmode);
8768 rtx reg4 = gen_reg_rtx (Pmode);
8769 rtx reg5 = gen_reg_rtx (Pmode);
8772 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8773 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8774 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8776 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8777 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8778 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8779 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8780 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8781 (Pmode, operands[3])));
8782 /* Messy: can we subreg to clean this up? */
8783 if (Pmode == DImode)
8784 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8786 load = gen_casesi_load_media (reg4,
8787 gen_rtx_SUBREG (DImode, reg3, 0),
8789 PUT_MODE (SET_SRC (load), Pmode);
8791 /* ??? The following add could be eliminated if we used ptrel. */
8792 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8793 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8797 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8798 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8799 /* If optimizing, casesi_worker depends on the mode of the instruction
8800 before label it 'uses' - operands[3]. */
8801 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8803 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8805 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8807 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8808 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8809 operands[3], but to lab. We will fix this up in
8810 machine_dependent_reorg. */
8815 (define_expand "casesi_0"
8816 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8817 (set (match_dup 4) (minus:SI (match_dup 4)
8818 (match_operand:SI 1 "arith_operand" "")))
8820 (gtu:SI (match_dup 4)
8821 (match_operand:SI 2 "arith_reg_operand" "")))
8823 (if_then_else (ne (reg:SI T_REG)
8825 (label_ref (match_operand 3 "" ""))
8830 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8831 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8832 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8834 (define_insn "casesi_worker_0"
8835 [(set (match_operand:SI 0 "register_operand" "=r,r")
8836 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8837 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8838 (clobber (match_scratch:SI 3 "=X,1"))
8839 (clobber (match_scratch:SI 4 "=&z,z"))]
8844 [(set (match_operand:SI 0 "register_operand" "")
8845 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8846 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8847 (clobber (match_scratch:SI 3 ""))
8848 (clobber (match_scratch:SI 4 ""))]
8849 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8850 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8851 (parallel [(set (match_dup 0)
8852 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8853 (label_ref (match_dup 2))] UNSPEC_CASESI))
8854 (clobber (match_dup 3))])
8855 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8856 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8859 [(set (match_operand:SI 0 "register_operand" "")
8860 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8861 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8862 (clobber (match_scratch:SI 3 ""))
8863 (clobber (match_scratch:SI 4 ""))]
8864 "TARGET_SH2 && reload_completed"
8865 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8866 (parallel [(set (match_dup 0)
8867 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8868 (label_ref (match_dup 2))] UNSPEC_CASESI))
8869 (clobber (match_dup 3))])]
8870 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8872 (define_insn "casesi_worker_1"
8873 [(set (match_operand:SI 0 "register_operand" "=r,r")
8874 (unspec:SI [(reg:SI R0_REG)
8875 (match_operand:SI 1 "register_operand" "0,r")
8876 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8877 (clobber (match_scratch:SI 3 "=X,1"))]
8881 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8883 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8885 switch (GET_MODE (diff_vec))
8888 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8890 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8892 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8893 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8894 return \"mov.b @(r0,%1),%0\";
8899 [(set_attr "length" "4")])
8901 (define_insn "casesi_worker_2"
8902 [(set (match_operand:SI 0 "register_operand" "=r,r")
8903 (unspec:SI [(reg:SI R0_REG)
8904 (match_operand:SI 1 "register_operand" "0,r")
8905 (label_ref (match_operand 2 "" ""))
8906 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8907 (clobber (match_operand:SI 4 "" "=X,1"))]
8908 "TARGET_SH2 && reload_completed && flag_pic"
8911 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8914 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8916 switch (GET_MODE (diff_vec))
8919 output_asm_insn (\"shll2 %1\", operands);
8920 load = \"mov.l @(r0,%1),%0\"; break;
8922 output_asm_insn (\"add %1,%1\", operands);
8923 load = \"mov.w @(r0,%1),%0\"; break;
8925 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8926 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8928 load = \"mov.b @(r0,%1),%0\";
8933 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8936 [(set_attr "length" "8")])
8938 (define_insn "casesi_shift_media"
8939 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8940 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8941 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8946 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8948 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8950 switch (GET_MODE (diff_vec))
8953 return \"shlli %1, 2, %0\";
8955 return \"shlli %1, 1, %0\";
8957 if (rtx_equal_p (operands[0], operands[1]))
8959 return \"add %1, r63, %0\";
8964 [(set_attr "type" "arith_media")])
8966 (define_insn "casesi_load_media"
8967 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8968 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8969 (match_operand:DI 2 "arith_reg_operand" "r")
8970 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8974 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8976 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8978 switch (GET_MODE (diff_vec))
8981 return \"ldx.l %1, %2, %0\";
8984 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8985 return \"ldx.uw %1, %2, %0\";
8987 return \"ldx.w %1, %2, %0\";
8989 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8990 return \"ldx.ub %1, %2, %0\";
8991 return \"ldx.b %1, %2, %0\";
8996 [(set_attr "type" "load_media")])
8998 (define_expand "return"
9000 "reload_completed && ! sh_need_epilogue ()"
9005 emit_jump_insn (gen_return_media ());
9009 if (TARGET_SHCOMPACT
9010 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9012 emit_jump_insn (gen_shcompact_return_tramp ());
9017 (define_insn "*return_i"
9019 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9020 && (current_function_args_info.call_cookie
9021 & CALL_COOKIE_RET_TRAMP (1)))
9023 && lookup_attribute (\"trap_exit\",
9024 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9026 [(set_attr "type" "return")
9027 (set_attr "needs_delay_slot" "yes")])
9029 ;; trapa has no delay slot.
9030 (define_insn "*return_trapa"
9032 "TARGET_SH1 && !TARGET_SHCOMPACT
9033 && reload_completed"
9035 [(set_attr "type" "return")])
9037 (define_expand "shcompact_return_tramp"
9040 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9043 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9045 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9046 emit_jump_insn (gen_shcompact_return_tramp_i ());
9050 (define_insn "shcompact_return_tramp_i"
9051 [(parallel [(return) (use (reg:SI R0_REG))])]
9053 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9055 [(set_attr "type" "jump_ind")
9056 (set_attr "needs_delay_slot" "yes")])
9058 (define_insn "return_media_i"
9059 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9060 "TARGET_SHMEDIA && reload_completed"
9062 [(set_attr "type" "jump_media")])
9064 (define_insn "return_media_rte"
9066 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9068 [(set_attr "type" "jump_media")])
9070 (define_expand "return_media"
9072 "TARGET_SHMEDIA && reload_completed"
9075 int tr_regno = sh_media_register_for_return ();
9078 if (current_function_interrupt)
9080 emit_jump_insn (gen_return_media_rte ());
9085 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9087 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9089 tr = gen_rtx_REG (Pmode, tr_regno);
9090 emit_move_insn (tr, r18);
9093 tr = gen_rtx_REG (Pmode, tr_regno);
9095 emit_jump_insn (gen_return_media_i (tr));
9099 (define_insn "shcompact_preserve_incoming_args"
9100 [(set (match_operand:SI 0 "register_operand" "+r")
9101 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9104 [(set_attr "length" "0")])
9106 (define_insn "shcompact_incoming_args"
9107 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9108 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9109 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9110 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9111 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9112 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9113 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9114 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9115 (set (mem:BLK (reg:SI MACL_REG))
9116 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9117 (use (reg:SI R0_REG))
9118 (clobber (reg:SI R0_REG))
9119 (clobber (reg:SI MACL_REG))
9120 (clobber (reg:SI MACH_REG))
9121 (clobber (reg:SI PR_REG))]
9124 [(set_attr "needs_delay_slot" "yes")])
9126 (define_insn "shmedia_save_restore_regs_compact"
9127 [(set (reg:SI SP_REG)
9128 (plus:SI (reg:SI SP_REG)
9129 (match_operand:SI 0 "immediate_operand" "i")))
9130 (use (reg:SI R0_REG))
9131 (clobber (reg:SI PR_REG))]
9133 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9134 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9136 [(set_attr "needs_delay_slot" "yes")])
9138 (define_expand "prologue"
9141 "sh_expand_prologue (); DONE;")
9143 (define_expand "epilogue"
9148 sh_expand_epilogue (0);
9149 emit_jump_insn (gen_return ());
9153 (define_expand "eh_return"
9154 [(use (match_operand 0 "register_operand" ""))]
9157 rtx ra = operands[0];
9159 if (TARGET_SHMEDIA64)
9160 emit_insn (gen_eh_set_ra_di (ra));
9162 emit_insn (gen_eh_set_ra_si (ra));
9167 ;; Clobber the return address on the stack. We can't expand this
9168 ;; until we know where it will be put in the stack frame.
9170 (define_insn "eh_set_ra_si"
9171 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9172 (clobber (match_scratch:SI 1 "=&r"))]
9173 "! TARGET_SHMEDIA64"
9176 (define_insn "eh_set_ra_di"
9177 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9178 (clobber (match_scratch:DI 1 "=&r"))]
9183 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9184 (clobber (match_scratch 1 ""))]
9189 sh_set_return_address (operands[0], operands[1]);
9193 (define_insn "blockage"
9194 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9197 [(set_attr "length" "0")])
9199 ;; ------------------------------------------------------------------------
9201 ;; ------------------------------------------------------------------------
9204 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9205 (eq:SI (reg:SI T_REG) (const_int 1)))]
9208 [(set_attr "type" "arith")])
9210 (define_expand "seq"
9211 [(set (match_operand:SI 0 "arith_reg_dest" "")
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),
9226 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9228 if (GET_MODE (operands[0]) != SImode)
9229 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9231 switch (GET_MODE (sh_compare_op0))
9234 emit_insn (gen_cmpeqsi_media (operands[0],
9235 sh_compare_op0, sh_compare_op1));
9239 emit_insn (gen_cmpeqdi_media (operands[0],
9240 sh_compare_op0, sh_compare_op1));
9244 if (! TARGET_SHMEDIA_FPU)
9246 emit_insn (gen_cmpeqsf_media (operands[0],
9247 sh_compare_op0, sh_compare_op1));
9251 if (! TARGET_SHMEDIA_FPU)
9253 emit_insn (gen_cmpeqdf_media (operands[0],
9254 sh_compare_op0, sh_compare_op1));
9264 if (GET_MODE (operands[0]) != SImode)
9265 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9266 : gen_reg_rtx (SImode);
9268 switch (GET_MODE (sh_compare_op0))
9271 emit_insn (gen_cmpeqsi_media (reg,
9272 sh_compare_op0, sh_compare_op1));
9276 emit_insn (gen_cmpeqdi_media (reg,
9277 sh_compare_op0, sh_compare_op1));
9281 if (! TARGET_SHMEDIA_FPU)
9283 emit_insn (gen_cmpeqsf_media (reg,
9284 sh_compare_op0, sh_compare_op1));
9288 if (! TARGET_SHMEDIA_FPU)
9290 emit_insn (gen_cmpeqdf_media (reg,
9291 sh_compare_op0, sh_compare_op1));
9298 if (GET_MODE (operands[0]) == DImode)
9299 emit_insn (gen_extendsidi2 (operands[0], reg));
9303 if (sh_expand_t_scc (EQ, operands[0]))
9305 if (! currently_expanding_to_rtl)
9307 operands[1] = prepare_scc_operands (EQ);
9310 (define_expand "slt"
9311 [(set (match_operand:SI 0 "arith_reg_operand" "")
9320 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9321 if (sh_compare_op1 != const0_rtx)
9322 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9323 ? GET_MODE (sh_compare_op0)
9324 : GET_MODE (sh_compare_op1),
9328 if (GET_MODE (operands[0]) != SImode)
9329 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9330 : gen_reg_rtx (SImode);
9332 switch (GET_MODE (sh_compare_op0))
9335 emit_insn (gen_cmpgtsi_media (reg,
9336 sh_compare_op1, sh_compare_op0));
9340 emit_insn (gen_cmpgtdi_media (reg,
9341 sh_compare_op1, sh_compare_op0));
9345 if (! TARGET_SHMEDIA_FPU)
9347 emit_insn (gen_cmpgtsf_media (reg,
9348 sh_compare_op1, sh_compare_op0));
9352 if (! TARGET_SHMEDIA_FPU)
9354 emit_insn (gen_cmpgtdf_media (reg,
9355 sh_compare_op1, sh_compare_op0));
9362 if (GET_MODE (operands[0]) == DImode)
9363 emit_insn (gen_extendsidi2 (operands[0], reg));
9367 if (! currently_expanding_to_rtl)
9369 operands[1] = prepare_scc_operands (LT);
9372 (define_expand "sle"
9373 [(match_operand:SI 0 "arith_reg_operand" "")]
9377 rtx tmp = sh_compare_op0;
9383 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9384 if (sh_compare_op1 != const0_rtx)
9385 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9386 ? GET_MODE (sh_compare_op0)
9387 : GET_MODE (sh_compare_op1),
9391 if (GET_MODE (operands[0]) != SImode)
9392 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9393 : gen_reg_rtx (SImode);
9395 switch (GET_MODE (sh_compare_op0))
9399 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9401 emit_insn (gen_cmpgtsi_media (tmp,
9402 sh_compare_op0, sh_compare_op1));
9403 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9409 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9411 emit_insn (gen_cmpgtdi_media (tmp,
9412 sh_compare_op0, sh_compare_op1));
9413 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9418 if (! TARGET_SHMEDIA_FPU)
9420 emit_insn (gen_cmpgesf_media (reg,
9421 sh_compare_op1, sh_compare_op0));
9425 if (! TARGET_SHMEDIA_FPU)
9427 emit_insn (gen_cmpgedf_media (reg,
9428 sh_compare_op1, sh_compare_op0));
9435 if (GET_MODE (operands[0]) == DImode)
9436 emit_insn (gen_extendsidi2 (operands[0], reg));
9441 sh_compare_op0 = sh_compare_op1;
9442 sh_compare_op1 = tmp;
9443 emit_insn (gen_sge (operands[0]));
9447 (define_expand "sgt"
9448 [(set (match_operand:SI 0 "arith_reg_operand" "")
9458 if (GET_MODE (operands[0]) != SImode)
9459 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9460 : gen_reg_rtx (SImode);
9461 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9462 if (sh_compare_op1 != const0_rtx)
9463 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9464 ? GET_MODE (sh_compare_op0)
9465 : GET_MODE (sh_compare_op1),
9468 switch (GET_MODE (sh_compare_op0))
9471 emit_insn (gen_cmpgtsi_media (reg,
9472 sh_compare_op0, sh_compare_op1));
9476 emit_insn (gen_cmpgtdi_media (reg,
9477 sh_compare_op0, sh_compare_op1));
9481 if (! TARGET_SHMEDIA_FPU)
9483 emit_insn (gen_cmpgtsf_media (reg,
9484 sh_compare_op0, sh_compare_op1));
9488 if (! TARGET_SHMEDIA_FPU)
9490 emit_insn (gen_cmpgtdf_media (reg,
9491 sh_compare_op0, sh_compare_op1));
9498 if (GET_MODE (operands[0]) == DImode)
9499 emit_insn (gen_extendsidi2 (operands[0], reg));
9503 if (! currently_expanding_to_rtl)
9505 operands[1] = prepare_scc_operands (GT);
9508 (define_expand "sge"
9509 [(set (match_operand:SI 0 "arith_reg_operand" "")
9517 enum machine_mode mode = GET_MODE (sh_compare_op0);
9519 if ((mode) == VOIDmode)
9520 mode = GET_MODE (sh_compare_op1);
9522 if (GET_MODE (operands[0]) != SImode)
9523 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9524 : gen_reg_rtx (SImode);
9525 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9526 if (sh_compare_op1 != const0_rtx)
9527 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9533 rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9535 emit_insn (gen_cmpgtsi_media (tmp,
9536 sh_compare_op1, sh_compare_op0));
9537 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9543 rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9545 emit_insn (gen_cmpgtdi_media (tmp,
9546 sh_compare_op1, sh_compare_op0));
9547 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9552 if (! TARGET_SHMEDIA_FPU)
9554 emit_insn (gen_cmpgesf_media (reg,
9555 sh_compare_op0, sh_compare_op1));
9559 if (! TARGET_SHMEDIA_FPU)
9561 emit_insn (gen_cmpgedf_media (reg,
9562 sh_compare_op0, sh_compare_op1));
9569 if (GET_MODE (operands[0]) == DImode)
9570 emit_insn (gen_extendsidi2 (operands[0], reg));
9575 if (! currently_expanding_to_rtl)
9577 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9581 rtx lab = gen_label_rtx ();
9582 prepare_scc_operands (EQ);
9583 emit_jump_insn (gen_branch_true (lab));
9584 prepare_scc_operands (GT);
9586 emit_insn (gen_movt (operands[0]));
9589 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9592 operands[1] = prepare_scc_operands (GE);
9595 (define_expand "sgtu"
9596 [(set (match_operand:SI 0 "arith_reg_operand" "")
9606 if (GET_MODE (operands[0]) == DImode)
9607 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9608 : gen_reg_rtx (SImode);
9609 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9610 if (sh_compare_op1 != const0_rtx)
9611 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9612 ? GET_MODE (sh_compare_op0)
9613 : GET_MODE (sh_compare_op1),
9616 emit_insn (gen_cmpgtudi_media (reg,
9617 sh_compare_op0, sh_compare_op1));
9618 if (GET_MODE (operands[0]) == DImode)
9619 emit_insn (gen_extendsidi2 (operands[0], reg));
9623 if (! currently_expanding_to_rtl)
9625 operands[1] = prepare_scc_operands (GTU);
9628 (define_expand "sltu"
9629 [(set (match_operand:SI 0 "arith_reg_operand" "")
9639 if (GET_MODE (operands[0]) == DImode)
9640 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9641 : gen_reg_rtx (SImode);
9642 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9643 if (sh_compare_op1 != const0_rtx)
9644 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9645 ? GET_MODE (sh_compare_op0)
9646 : GET_MODE (sh_compare_op1),
9649 emit_insn (gen_cmpgtudi_media (reg,
9650 sh_compare_op1, sh_compare_op0));
9651 if (GET_MODE (operands[0]) == DImode)
9652 emit_insn (gen_extendsidi2 (operands[0], reg));
9656 if (! currently_expanding_to_rtl)
9658 operands[1] = prepare_scc_operands (LTU);
9661 (define_expand "sleu"
9662 [(set (match_operand:SI 0 "arith_reg_operand" "")
9672 if (GET_MODE (operands[0]) != SImode)
9673 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9674 : gen_reg_rtx (SImode);
9675 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9676 if (sh_compare_op1 != const0_rtx)
9677 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9678 ? GET_MODE (sh_compare_op0)
9679 : GET_MODE (sh_compare_op1),
9682 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9684 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9685 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9686 if (GET_MODE (operands[0]) == DImode)
9687 emit_insn (gen_extendsidi2 (operands[0], reg));
9691 if (! currently_expanding_to_rtl)
9693 operands[1] = prepare_scc_operands (LEU);
9696 (define_expand "sgeu"
9697 [(set (match_operand:SI 0 "arith_reg_operand" "")
9707 if (GET_MODE (operands[0]) != SImode)
9708 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9709 : gen_reg_rtx (SImode);
9710 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9711 if (sh_compare_op1 != const0_rtx)
9712 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9713 ? GET_MODE (sh_compare_op0)
9714 : GET_MODE (sh_compare_op1),
9717 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9719 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9720 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9721 if (GET_MODE (operands[0]) == DImode)
9722 emit_insn (gen_extendsidi2 (operands[0], reg));
9727 if (! currently_expanding_to_rtl)
9729 operands[1] = prepare_scc_operands (GEU);
9732 ;; sne moves the complement of the T reg to DEST like this:
9736 ;; This is better than xoring compare result with 1 because it does
9737 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9740 (define_expand "sne"
9741 [(set (match_dup 2) (const_int -1))
9742 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9743 (neg:SI (plus:SI (match_dup 1)
9746 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9756 if (GET_MODE (operands[0]) != SImode)
9757 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9758 : gen_reg_rtx (SImode);
9759 if (! TARGET_SHMEDIA_FPU
9760 && GET_MODE (sh_compare_op0) != DImode
9761 && GET_MODE (sh_compare_op0) != SImode)
9764 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9765 if (sh_compare_op1 != const0_rtx)
9766 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9767 ? GET_MODE (sh_compare_op0)
9768 : GET_MODE (sh_compare_op1),
9771 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9773 emit_insn (gen_seq (tmp));
9774 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9775 if (GET_MODE (operands[0]) == DImode)
9776 emit_insn (gen_extendsidi2 (operands[0], reg));
9781 if (sh_expand_t_scc (NE, operands[0]))
9783 if (! currently_expanding_to_rtl)
9785 operands[1] = prepare_scc_operands (EQ);
9786 operands[2] = gen_reg_rtx (SImode);
9789 (define_expand "sunordered"
9790 [(set (match_operand:SI 0 "arith_reg_operand" "")
9791 (unordered:SI (match_dup 1) (match_dup 2)))]
9792 "TARGET_SHMEDIA_FPU"
9795 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9796 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9799 ;; Use the same trick for FP sle / sge
9801 ;; Apart from the constant use and the T setting, this is like movt,
9802 ;; except that it uses the logically negated value of T, i.e.
9803 ;; operand[0] := T ? 0 : 1.
9804 (define_expand "movnegt"
9805 [(set (match_dup 2) (const_int -1))
9806 (parallel [(set (match_operand 0 "" "")
9807 (neg:SI (plus:SI (match_dup 1)
9810 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9813 "operands[2] = gen_reg_rtx (SImode);")
9815 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9816 ;; This prevents a regression that occurred when we switched from xor to
9820 [(set (match_operand:SI 0 "arith_reg_dest" "")
9821 (plus:SI (reg:SI T_REG)
9824 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9825 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9828 ;; -------------------------------------------------------------------------
9829 ;; Instructions to cope with inline literal tables
9830 ;; -------------------------------------------------------------------------
9832 ; 2 byte integer in line
9834 (define_insn "consttable_2"
9835 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9836 (match_operand 1 "" "")]
9841 if (operands[1] != const0_rtx)
9842 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9845 [(set_attr "length" "2")
9846 (set_attr "in_delay_slot" "no")])
9848 ; 4 byte integer in line
9850 (define_insn "consttable_4"
9851 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9852 (match_operand 1 "" "")]
9857 if (operands[1] != const0_rtx)
9858 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9861 [(set_attr "length" "4")
9862 (set_attr "in_delay_slot" "no")])
9864 ; 8 byte integer in line
9866 (define_insn "consttable_8"
9867 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9868 (match_operand 1 "" "")]
9873 if (operands[1] != const0_rtx)
9874 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9877 [(set_attr "length" "8")
9878 (set_attr "in_delay_slot" "no")])
9880 ; 4 byte floating point
9882 (define_insn "consttable_sf"
9883 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9884 (match_operand 1 "" "")]
9889 if (operands[1] != const0_rtx)
9892 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9893 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9897 [(set_attr "length" "4")
9898 (set_attr "in_delay_slot" "no")])
9900 ; 8 byte floating point
9902 (define_insn "consttable_df"
9903 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9904 (match_operand 1 "" "")]
9909 if (operands[1] != const0_rtx)
9912 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9913 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9917 [(set_attr "length" "8")
9918 (set_attr "in_delay_slot" "no")])
9920 ;; Alignment is needed for some constant tables; it may also be added for
9921 ;; Instructions at the start of loops, or after unconditional branches.
9922 ;; ??? We would get more accurate lengths if we did instruction
9923 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9924 ;; here is too conservative.
9926 ; align to a two byte boundary
9928 (define_expand "align_2"
9929 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9933 ; align to a four byte boundary
9934 ;; align_4 and align_log are instructions for the starts of loops, or
9935 ;; after unconditional branches, which may take up extra room.
9937 (define_expand "align_4"
9938 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9942 ; align to a cache line boundary
9944 (define_insn "align_log"
9945 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9948 [(set_attr "length" "0")
9949 (set_attr "in_delay_slot" "no")])
9951 ; emitted at the end of the literal table, used to emit the
9952 ; 32bit branch labels if needed.
9954 (define_insn "consttable_end"
9955 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9957 "* return output_jump_label_table ();"
9958 [(set_attr "in_delay_slot" "no")])
9960 ; emitted at the end of the window in the literal table.
9962 (define_insn "consttable_window_end"
9963 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9966 [(set_attr "length" "0")
9967 (set_attr "in_delay_slot" "no")])
9969 ;; -------------------------------------------------------------------------
9971 ;; -------------------------------------------------------------------------
9973 ;; String/block move insn.
9975 (define_expand "movmemsi"
9976 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9977 (mem:BLK (match_operand:BLK 1 "" "")))
9978 (use (match_operand:SI 2 "nonmemory_operand" ""))
9979 (use (match_operand:SI 3 "immediate_operand" ""))
9980 (clobber (reg:SI PR_REG))
9981 (clobber (reg:SI R4_REG))
9982 (clobber (reg:SI R5_REG))
9983 (clobber (reg:SI R0_REG))])]
9984 "TARGET_SH1 && ! TARGET_SH5"
9987 if(expand_block_move (operands))
9992 (define_insn "block_move_real"
9993 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9994 (mem:BLK (reg:SI R5_REG)))
9995 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9996 (clobber (reg:SI PR_REG))
9997 (clobber (reg:SI R0_REG))])]
9998 "TARGET_SH1 && ! TARGET_HARD_SH4"
10000 [(set_attr "type" "sfunc")
10001 (set_attr "needs_delay_slot" "yes")])
10003 (define_insn "block_lump_real"
10004 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10005 (mem:BLK (reg:SI R5_REG)))
10006 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10007 (use (reg:SI R6_REG))
10008 (clobber (reg:SI PR_REG))
10009 (clobber (reg:SI T_REG))
10010 (clobber (reg:SI R4_REG))
10011 (clobber (reg:SI R5_REG))
10012 (clobber (reg:SI R6_REG))
10013 (clobber (reg:SI R0_REG))])]
10014 "TARGET_SH1 && ! TARGET_HARD_SH4"
10016 [(set_attr "type" "sfunc")
10017 (set_attr "needs_delay_slot" "yes")])
10019 (define_insn "block_move_real_i4"
10020 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10021 (mem:BLK (reg:SI R5_REG)))
10022 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10023 (clobber (reg:SI PR_REG))
10024 (clobber (reg:SI R0_REG))
10025 (clobber (reg:SI R1_REG))
10026 (clobber (reg:SI R2_REG))])]
10029 [(set_attr "type" "sfunc")
10030 (set_attr "needs_delay_slot" "yes")])
10032 (define_insn "block_lump_real_i4"
10033 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10034 (mem:BLK (reg:SI R5_REG)))
10035 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10036 (use (reg:SI R6_REG))
10037 (clobber (reg:SI PR_REG))
10038 (clobber (reg:SI T_REG))
10039 (clobber (reg:SI R4_REG))
10040 (clobber (reg:SI R5_REG))
10041 (clobber (reg:SI R6_REG))
10042 (clobber (reg:SI R0_REG))
10043 (clobber (reg:SI R1_REG))
10044 (clobber (reg:SI R2_REG))
10045 (clobber (reg:SI R3_REG))])]
10048 [(set_attr "type" "sfunc")
10049 (set_attr "needs_delay_slot" "yes")])
10051 ;; -------------------------------------------------------------------------
10052 ;; Floating point instructions.
10053 ;; -------------------------------------------------------------------------
10055 ;; ??? All patterns should have a type attribute.
10057 (define_expand "movpsi"
10058 [(set (match_operand:PSI 0 "register_operand" "")
10059 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10060 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10063 ;; The c / m alternative is a fake to guide reload to load directly into
10064 ;; fpscr, since reload doesn't know how to use post-increment.
10065 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10066 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10067 ;; predicate after reload.
10068 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10069 ;; like a mac -> gpr move.
10070 (define_insn "fpu_switch"
10071 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10072 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10074 && (! reload_completed
10075 || true_regnum (operands[0]) != FPSCR_REG
10076 || GET_CODE (operands[1]) != MEM
10077 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10079 ! precision stays the same
10088 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10089 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10092 [(set (reg:PSI FPSCR_REG)
10093 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10094 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10097 rtx fpscr, mem, new_insn;
10099 fpscr = SET_DEST (PATTERN (curr_insn));
10100 mem = SET_SRC (PATTERN (curr_insn));
10101 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10103 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10104 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10109 [(set (reg:PSI FPSCR_REG)
10110 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10111 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10112 && (flag_peephole2 ? flow2_completed : reload_completed)"
10115 rtx fpscr, mem, new_insn;
10117 fpscr = SET_DEST (PATTERN (curr_insn));
10118 mem = SET_SRC (PATTERN (curr_insn));
10119 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10121 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10122 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10124 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10125 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10129 ;; ??? This uses the fp unit, but has no type indicating that.
10130 ;; If we did that, this would either give a bogus latency or introduce
10131 ;; a bogus FIFO constraint.
10132 ;; Since this insn is currently only used for prologues/epilogues,
10133 ;; it is probably best to claim no function unit, which matches the
10134 ;; current setting.
10135 (define_insn "toggle_sz"
10136 [(set (reg:PSI FPSCR_REG)
10137 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10138 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10140 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10142 ;; There's no way we can use it today, since optimize mode switching
10143 ;; doesn't enable us to know from which mode we're switching to the
10144 ;; mode it requests, to tell whether we can use a relative mode switch
10145 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10147 (define_insn "toggle_pr"
10148 [(set (reg:PSI FPSCR_REG)
10149 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10150 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10152 [(set_attr "type" "fpscr_toggle")])
10154 (define_expand "addsf3"
10155 [(set (match_operand:SF 0 "arith_reg_operand" "")
10156 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10157 (match_operand:SF 2 "arith_reg_operand" "")))]
10158 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10163 expand_sf_binop (&gen_addsf3_i, operands);
10168 (define_insn "*addsf3_media"
10169 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10170 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10171 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10172 "TARGET_SHMEDIA_FPU"
10173 "fadd.s %1, %2, %0"
10174 [(set_attr "type" "fparith_media")])
10176 (define_insn_and_split "unary_sf_op"
10177 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10182 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10183 (match_operator:SF 2 "unary_float_operator"
10184 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10185 (parallel [(match_operand 4
10186 "const_int_operand" "n")]))]))
10187 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10188 "TARGET_SHMEDIA_FPU"
10190 "TARGET_SHMEDIA_FPU && reload_completed"
10191 [(set (match_dup 5) (match_dup 6))]
10194 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10195 rtx op1 = gen_rtx_REG (SFmode,
10196 (true_regnum (operands[1])
10197 + (INTVAL (operands[4]) ^ endian)));
10199 operands[7] = gen_rtx_REG (SFmode,
10200 (true_regnum (operands[0])
10201 + (INTVAL (operands[3]) ^ endian)));
10202 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10204 [(set_attr "type" "fparith_media")])
10206 (define_insn_and_split "binary_sf_op"
10207 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10212 (parallel [(match_operand 7 "const_int_operand" "n")]))
10213 (match_operator:SF 3 "binary_float_operator"
10214 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10215 (parallel [(match_operand 5
10216 "const_int_operand" "n")]))
10217 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10218 (parallel [(match_operand 6
10219 "const_int_operand" "n")]))]))
10220 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10221 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10223 "&& reload_completed"
10224 [(set (match_dup 8) (match_dup 9))]
10227 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10228 rtx op1 = gen_rtx_REG (SFmode,
10229 (true_regnum (operands[1])
10230 + (INTVAL (operands[5]) ^ endian)));
10231 rtx op2 = gen_rtx_REG (SFmode,
10232 (true_regnum (operands[2])
10233 + (INTVAL (operands[6]) ^ endian)));
10235 operands[8] = gen_rtx_REG (SFmode,
10236 (true_regnum (operands[0])
10237 + (INTVAL (operands[4]) ^ endian)));
10238 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10240 [(set_attr "type" "fparith_media")])
10242 (define_insn "addsf3_i"
10243 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10244 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10245 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10246 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10249 [(set_attr "type" "fp")
10250 (set_attr "fp_mode" "single")])
10252 (define_expand "subsf3"
10253 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10254 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10255 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10256 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10261 expand_sf_binop (&gen_subsf3_i, operands);
10266 (define_insn "*subsf3_media"
10267 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10268 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10269 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10270 "TARGET_SHMEDIA_FPU"
10271 "fsub.s %1, %2, %0"
10272 [(set_attr "type" "fparith_media")])
10274 (define_insn "subsf3_i"
10275 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10276 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10277 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10278 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10281 [(set_attr "type" "fp")
10282 (set_attr "fp_mode" "single")])
10284 (define_expand "mulsf3"
10285 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10286 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10287 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10288 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10291 (define_insn "*mulsf3_media"
10292 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10293 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10294 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10295 "TARGET_SHMEDIA_FPU"
10296 "fmul.s %1, %2, %0"
10297 [(set_attr "type" "fparith_media")])
10299 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10300 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10301 ;; we start out with a mulsf pattern that does not depend on fpscr.
10302 ;; This is split after combine to introduce the dependency, in order to
10303 ;; get mode switching and scheduling right.
10304 (define_insn_and_split "mulsf3_ie"
10305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10306 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10307 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10310 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10314 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10315 get_fpscr_rtx ()));
10318 [(set_attr "type" "fp")])
10320 (define_insn "mulsf3_i4"
10321 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10322 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10323 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10324 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10327 [(set_attr "type" "fp")
10328 (set_attr "fp_mode" "single")])
10330 (define_insn "mac_media"
10331 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10332 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10333 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10334 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10335 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10336 "fmac.s %1, %2, %0"
10337 [(set_attr "type" "fparith_media")])
10339 (define_insn "*macsf3"
10340 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10341 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10342 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10343 (match_operand:SF 3 "arith_reg_operand" "0")))
10344 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10345 "TARGET_SH2E && TARGET_FMAC"
10347 [(set_attr "type" "fp")
10348 (set_attr "fp_mode" "single")])
10350 (define_expand "divsf3"
10351 [(set (match_operand:SF 0 "arith_reg_operand" "")
10352 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10353 (match_operand:SF 2 "arith_reg_operand" "")))]
10354 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10359 expand_sf_binop (&gen_divsf3_i, operands);
10364 (define_insn "*divsf3_media"
10365 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10366 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10367 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10368 "TARGET_SHMEDIA_FPU"
10369 "fdiv.s %1, %2, %0"
10370 [(set_attr "type" "fdiv_media")])
10372 (define_insn "divsf3_i"
10373 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10374 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10375 (match_operand:SF 2 "arith_reg_operand" "f")))
10376 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10379 [(set_attr "type" "fdiv")
10380 (set_attr "fp_mode" "single")])
10382 (define_insn "floatdisf2"
10383 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10384 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10385 "TARGET_SHMEDIA_FPU"
10387 [(set_attr "type" "fpconv_media")])
10389 (define_expand "floatsisf2"
10390 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10391 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10392 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10395 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10397 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10402 (define_insn "*floatsisf2_media"
10403 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10404 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10405 "TARGET_SHMEDIA_FPU"
10407 [(set_attr "type" "fpconv_media")])
10409 (define_insn "floatsisf2_i4"
10410 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10411 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10412 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10413 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10415 [(set_attr "type" "fp")
10416 (set_attr "fp_mode" "single")])
10418 (define_insn "*floatsisf2_ie"
10419 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10420 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10421 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10423 [(set_attr "type" "fp")])
10425 (define_insn "fix_truncsfdi2"
10426 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10427 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10428 "TARGET_SHMEDIA_FPU"
10430 [(set_attr "type" "fpconv_media")])
10432 (define_expand "fix_truncsfsi2"
10433 [(set (match_operand:SI 0 "fpul_operand" "=y")
10434 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10435 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10438 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10440 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10445 (define_insn "*fix_truncsfsi2_media"
10446 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10447 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10448 "TARGET_SHMEDIA_FPU"
10450 [(set_attr "type" "fpconv_media")])
10452 (define_insn "fix_truncsfsi2_i4"
10453 [(set (match_operand:SI 0 "fpul_operand" "=y")
10454 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10455 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10456 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10458 [(set_attr "type" "ftrc_s")
10459 (set_attr "fp_mode" "single")])
10461 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10462 ;; fix_truncsfsi2_i4.
10463 ;; (define_insn "fix_truncsfsi2_i4_2"
10464 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10465 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10466 ;; (use (reg:PSI FPSCR_REG))
10467 ;; (clobber (reg:SI FPUL_REG))]
10470 ;; [(set_attr "length" "4")
10471 ;; (set_attr "fp_mode" "single")])
10474 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10475 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10476 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10477 ;; (clobber (reg:SI FPUL_REG))]
10479 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10480 ;; (use (match_dup 2))])
10481 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10483 (define_insn "*fixsfsi"
10484 [(set (match_operand:SI 0 "fpul_operand" "=y")
10485 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10486 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10488 [(set_attr "type" "fp")])
10490 (define_insn "cmpgtsf_t"
10491 [(set (reg:SI T_REG)
10492 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10493 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10494 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10496 [(set_attr "type" "fp_cmp")
10497 (set_attr "fp_mode" "single")])
10499 (define_insn "cmpeqsf_t"
10500 [(set (reg:SI T_REG)
10501 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10502 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10503 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10505 [(set_attr "type" "fp_cmp")
10506 (set_attr "fp_mode" "single")])
10508 (define_insn "ieee_ccmpeqsf_t"
10509 [(set (reg:SI T_REG)
10510 (ior:SI (reg:SI T_REG)
10511 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10512 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10513 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10514 "* return output_ieee_ccmpeq (insn, operands);"
10515 [(set_attr "length" "4")])
10518 (define_insn "cmpgtsf_t_i4"
10519 [(set (reg:SI T_REG)
10520 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10521 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10522 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10523 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10525 [(set_attr "type" "fp_cmp")
10526 (set_attr "fp_mode" "single")])
10528 (define_insn "cmpeqsf_t_i4"
10529 [(set (reg:SI T_REG)
10530 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10531 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10532 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10533 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10535 [(set_attr "type" "fp_cmp")
10536 (set_attr "fp_mode" "single")])
10538 (define_insn "*ieee_ccmpeqsf_t_4"
10539 [(set (reg:SI T_REG)
10540 (ior:SI (reg:SI T_REG)
10541 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10542 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10543 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10544 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10545 "* return output_ieee_ccmpeq (insn, operands);"
10546 [(set_attr "length" "4")
10547 (set_attr "fp_mode" "single")])
10549 (define_insn "cmpeqsf_media"
10550 [(set (match_operand:SI 0 "register_operand" "=r")
10551 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10552 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10553 "TARGET_SHMEDIA_FPU"
10554 "fcmpeq.s %1, %2, %0"
10555 [(set_attr "type" "fcmp_media")])
10557 (define_insn "cmpgtsf_media"
10558 [(set (match_operand:SI 0 "register_operand" "=r")
10559 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10560 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10561 "TARGET_SHMEDIA_FPU"
10562 "fcmpgt.s %1, %2, %0"
10563 [(set_attr "type" "fcmp_media")])
10565 (define_insn "cmpgesf_media"
10566 [(set (match_operand:SI 0 "register_operand" "=r")
10567 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10568 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10569 "TARGET_SHMEDIA_FPU"
10570 "fcmpge.s %1, %2, %0"
10571 [(set_attr "type" "fcmp_media")])
10573 (define_insn "cmpunsf_media"
10574 [(set (match_operand:SI 0 "register_operand" "=r")
10575 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10576 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10577 "TARGET_SHMEDIA_FPU"
10578 "fcmpun.s %1, %2, %0"
10579 [(set_attr "type" "fcmp_media")])
10581 (define_expand "cmpsf"
10582 [(set (reg:SI T_REG)
10583 (compare (match_operand:SF 0 "arith_operand" "")
10584 (match_operand:SF 1 "arith_operand" "")))]
10585 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10588 sh_compare_op0 = operands[0];
10589 sh_compare_op1 = operands[1];
10593 (define_expand "negsf2"
10594 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10595 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10596 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10601 expand_sf_unop (&gen_negsf2_i, operands);
10606 (define_insn "*negsf2_media"
10607 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10608 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10609 "TARGET_SHMEDIA_FPU"
10611 [(set_attr "type" "fmove_media")])
10613 (define_insn "negsf2_i"
10614 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10615 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10616 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10619 [(set_attr "type" "fmove")
10620 (set_attr "fp_mode" "single")])
10622 (define_expand "sqrtsf2"
10623 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10624 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10625 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10630 expand_sf_unop (&gen_sqrtsf2_i, operands);
10635 (define_insn "*sqrtsf2_media"
10636 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10637 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10638 "TARGET_SHMEDIA_FPU"
10640 [(set_attr "type" "fdiv_media")])
10642 (define_insn "sqrtsf2_i"
10643 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10644 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10645 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10648 [(set_attr "type" "fdiv")
10649 (set_attr "fp_mode" "single")])
10651 (define_insn "rsqrtsf2"
10652 [(set (match_operand:SF 0 "register_operand" "=f")
10653 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10654 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10655 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10656 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10657 && operands[1] == CONST1_RTX (SFmode)"
10659 [(set_attr "type" "fsrra")
10660 (set_attr "fp_mode" "single")])
10662 (define_insn "fsca"
10663 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10665 (unspec:SF [(mult:SF
10666 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10667 (match_operand:SF 2 "immediate_operand" "i"))
10669 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10671 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10672 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10673 && operands[2] == sh_fsca_int2sf ()"
10675 [(set_attr "type" "fsca")
10676 (set_attr "fp_mode" "single")])
10678 (define_expand "sinsf2"
10679 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10680 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10682 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10685 rtx scaled = gen_reg_rtx (SFmode);
10686 rtx truncated = gen_reg_rtx (SImode);
10687 rtx fsca = gen_reg_rtx (V2SFmode);
10688 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10690 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10691 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10692 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10693 get_fpscr_rtx ()));
10694 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10698 (define_expand "cossf2"
10699 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10700 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10702 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10705 rtx scaled = gen_reg_rtx (SFmode);
10706 rtx truncated = gen_reg_rtx (SImode);
10707 rtx fsca = gen_reg_rtx (V2SFmode);
10708 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10710 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10711 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10712 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10713 get_fpscr_rtx ()));
10714 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10718 (define_expand "sindf2"
10719 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10720 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10722 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10725 rtx scaled = gen_reg_rtx (DFmode);
10726 rtx truncated = gen_reg_rtx (SImode);
10727 rtx fsca = gen_reg_rtx (V2SFmode);
10728 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10729 rtx sfresult = gen_reg_rtx (SFmode);
10731 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10732 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10733 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10734 get_fpscr_rtx ()));
10735 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10736 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10740 (define_expand "cosdf2"
10741 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10742 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10744 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10747 rtx scaled = gen_reg_rtx (DFmode);
10748 rtx truncated = gen_reg_rtx (SImode);
10749 rtx fsca = gen_reg_rtx (V2SFmode);
10750 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10751 rtx sfresult = gen_reg_rtx (SFmode);
10753 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10754 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10755 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10756 get_fpscr_rtx ()));
10757 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10758 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10762 (define_expand "abssf2"
10763 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10764 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10765 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10770 expand_sf_unop (&gen_abssf2_i, operands);
10775 (define_insn "*abssf2_media"
10776 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10777 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10778 "TARGET_SHMEDIA_FPU"
10780 [(set_attr "type" "fmove_media")])
10782 (define_insn "abssf2_i"
10783 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10784 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10785 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10788 [(set_attr "type" "fmove")
10789 (set_attr "fp_mode" "single")])
10791 (define_expand "adddf3"
10792 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10793 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10794 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10795 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10798 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10800 expand_df_binop (&gen_adddf3_i, operands);
10805 (define_insn "*adddf3_media"
10806 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10807 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10808 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10809 "TARGET_SHMEDIA_FPU"
10810 "fadd.d %1, %2, %0"
10811 [(set_attr "type" "dfparith_media")])
10813 (define_insn "adddf3_i"
10814 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10815 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10816 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10817 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10818 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10820 [(set_attr "type" "dfp_arith")
10821 (set_attr "fp_mode" "double")])
10823 (define_expand "subdf3"
10824 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10825 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10826 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10827 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10830 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10832 expand_df_binop (&gen_subdf3_i, operands);
10837 (define_insn "*subdf3_media"
10838 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10839 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10840 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10841 "TARGET_SHMEDIA_FPU"
10842 "fsub.d %1, %2, %0"
10843 [(set_attr "type" "dfparith_media")])
10845 (define_insn "subdf3_i"
10846 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10847 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10848 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10849 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10850 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10852 [(set_attr "type" "dfp_arith")
10853 (set_attr "fp_mode" "double")])
10855 (define_expand "muldf3"
10856 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10857 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10858 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10859 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10862 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10864 expand_df_binop (&gen_muldf3_i, operands);
10869 (define_insn "*muldf3_media"
10870 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10871 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10872 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10873 "TARGET_SHMEDIA_FPU"
10874 "fmul.d %1, %2, %0"
10875 [(set_attr "type" "dfmul_media")])
10877 (define_insn "muldf3_i"
10878 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10879 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10880 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10881 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10882 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10884 [(set_attr "type" "dfp_mul")
10885 (set_attr "fp_mode" "double")])
10887 (define_expand "divdf3"
10888 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10889 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10890 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10891 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10894 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10896 expand_df_binop (&gen_divdf3_i, operands);
10901 (define_insn "*divdf3_media"
10902 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10903 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10904 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10905 "TARGET_SHMEDIA_FPU"
10906 "fdiv.d %1, %2, %0"
10907 [(set_attr "type" "dfdiv_media")])
10909 (define_insn "divdf3_i"
10910 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10911 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10912 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10913 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10914 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10916 [(set_attr "type" "dfdiv")
10917 (set_attr "fp_mode" "double")])
10919 (define_insn "floatdidf2"
10920 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10921 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10922 "TARGET_SHMEDIA_FPU"
10924 [(set_attr "type" "dfpconv_media")])
10926 (define_expand "floatsidf2"
10927 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10928 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10929 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10932 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10934 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10935 get_fpscr_rtx ()));
10940 (define_insn "*floatsidf2_media"
10941 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10942 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10943 "TARGET_SHMEDIA_FPU"
10945 [(set_attr "type" "dfpconv_media")])
10947 (define_insn "floatsidf2_i"
10948 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10949 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10950 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10951 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10953 [(set_attr "type" "dfp_conv")
10954 (set_attr "fp_mode" "double")])
10956 (define_insn "fix_truncdfdi2"
10957 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10958 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10959 "TARGET_SHMEDIA_FPU"
10961 [(set_attr "type" "dfpconv_media")])
10963 (define_expand "fix_truncdfsi2"
10964 [(set (match_operand:SI 0 "fpul_operand" "")
10965 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10966 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10969 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10971 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10972 get_fpscr_rtx ()));
10977 (define_insn "*fix_truncdfsi2_media"
10978 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10979 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10980 "TARGET_SHMEDIA_FPU"
10982 [(set_attr "type" "dfpconv_media")])
10984 (define_insn "fix_truncdfsi2_i"
10985 [(set (match_operand:SI 0 "fpul_operand" "=y")
10986 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10987 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10988 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10990 [(set_attr "type" "dfp_conv")
10991 (set_attr "dfp_comp" "no")
10992 (set_attr "fp_mode" "double")])
10994 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10995 ;; fix_truncdfsi2_i.
10996 ;; (define_insn "fix_truncdfsi2_i4"
10997 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10998 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10999 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11000 ;; (clobber (reg:SI FPUL_REG))]
11003 ;; [(set_attr "length" "4")
11004 ;; (set_attr "fp_mode" "double")])
11007 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11008 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11009 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11010 ;; (clobber (reg:SI FPUL_REG))]
11012 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11013 ;; (use (match_dup 2))])
11014 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11016 (define_insn "cmpgtdf_t"
11017 [(set (reg:SI T_REG)
11018 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11019 (match_operand:DF 1 "arith_reg_operand" "f")))
11020 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11021 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11023 [(set_attr "type" "dfp_cmp")
11024 (set_attr "fp_mode" "double")])
11026 (define_insn "cmpeqdf_t"
11027 [(set (reg:SI T_REG)
11028 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11029 (match_operand:DF 1 "arith_reg_operand" "f")))
11030 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11031 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11033 [(set_attr "type" "dfp_cmp")
11034 (set_attr "fp_mode" "double")])
11036 (define_insn "*ieee_ccmpeqdf_t"
11037 [(set (reg:SI T_REG)
11038 (ior:SI (reg:SI T_REG)
11039 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11040 (match_operand:DF 1 "arith_reg_operand" "f"))))
11041 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11042 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11043 "* return output_ieee_ccmpeq (insn, operands);"
11044 [(set_attr "length" "4")
11045 (set_attr "fp_mode" "double")])
11047 (define_insn "cmpeqdf_media"
11048 [(set (match_operand:SI 0 "register_operand" "=r")
11049 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11050 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11051 "TARGET_SHMEDIA_FPU"
11052 "fcmpeq.d %1,%2,%0"
11053 [(set_attr "type" "fcmp_media")])
11055 (define_insn "cmpgtdf_media"
11056 [(set (match_operand:SI 0 "register_operand" "=r")
11057 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11058 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11059 "TARGET_SHMEDIA_FPU"
11060 "fcmpgt.d %1,%2,%0"
11061 [(set_attr "type" "fcmp_media")])
11063 (define_insn "cmpgedf_media"
11064 [(set (match_operand:SI 0 "register_operand" "=r")
11065 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11066 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11067 "TARGET_SHMEDIA_FPU"
11068 "fcmpge.d %1,%2,%0"
11069 [(set_attr "type" "fcmp_media")])
11071 (define_insn "cmpundf_media"
11072 [(set (match_operand:SI 0 "register_operand" "=r")
11073 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11074 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11075 "TARGET_SHMEDIA_FPU"
11076 "fcmpun.d %1,%2,%0"
11077 [(set_attr "type" "fcmp_media")])
11079 (define_expand "cmpdf"
11080 [(set (reg:SI T_REG)
11081 (compare (match_operand:DF 0 "arith_operand" "")
11082 (match_operand:DF 1 "arith_operand" "")))]
11083 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11086 sh_compare_op0 = operands[0];
11087 sh_compare_op1 = operands[1];
11091 (define_expand "negdf2"
11092 [(set (match_operand:DF 0 "arith_reg_operand" "")
11093 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11094 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11097 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11099 expand_df_unop (&gen_negdf2_i, operands);
11104 (define_insn "*negdf2_media"
11105 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11106 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11107 "TARGET_SHMEDIA_FPU"
11109 [(set_attr "type" "fmove_media")])
11111 (define_insn "negdf2_i"
11112 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11113 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11114 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11115 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11117 [(set_attr "type" "fmove")
11118 (set_attr "fp_mode" "double")])
11120 (define_expand "sqrtdf2"
11121 [(set (match_operand:DF 0 "arith_reg_operand" "")
11122 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11123 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11126 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11128 expand_df_unop (&gen_sqrtdf2_i, operands);
11133 (define_insn "*sqrtdf2_media"
11134 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11135 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11136 "TARGET_SHMEDIA_FPU"
11138 [(set_attr "type" "dfdiv_media")])
11140 (define_insn "sqrtdf2_i"
11141 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11142 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11143 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11144 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11146 [(set_attr "type" "dfdiv")
11147 (set_attr "fp_mode" "double")])
11149 (define_expand "absdf2"
11150 [(set (match_operand:DF 0 "arith_reg_operand" "")
11151 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11152 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11155 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11157 expand_df_unop (&gen_absdf2_i, operands);
11162 (define_insn "*absdf2_media"
11163 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11164 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11165 "TARGET_SHMEDIA_FPU"
11167 [(set_attr "type" "fmove_media")])
11169 (define_insn "absdf2_i"
11170 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11171 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11172 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11173 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11175 [(set_attr "type" "fmove")
11176 (set_attr "fp_mode" "double")])
11178 (define_expand "extendsfdf2"
11179 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11180 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11181 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11184 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11186 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11187 get_fpscr_rtx ()));
11192 (define_insn "*extendsfdf2_media"
11193 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11194 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11195 "TARGET_SHMEDIA_FPU"
11197 [(set_attr "type" "dfpconv_media")])
11199 (define_insn "extendsfdf2_i4"
11200 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11201 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11202 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11203 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11205 [(set_attr "type" "fp")
11206 (set_attr "fp_mode" "double")])
11208 (define_expand "truncdfsf2"
11209 [(set (match_operand:SF 0 "fpul_operand" "")
11210 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11211 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11214 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11216 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11217 get_fpscr_rtx ()));
11222 (define_insn "*truncdfsf2_media"
11223 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11224 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11225 "TARGET_SHMEDIA_FPU"
11227 [(set_attr "type" "dfpconv_media")])
11229 (define_insn "truncdfsf2_i4"
11230 [(set (match_operand:SF 0 "fpul_operand" "=y")
11231 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11232 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11233 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11235 [(set_attr "type" "fp")
11236 (set_attr "fp_mode" "double")])
11238 ;; Bit field extract patterns. These give better code for packed bitfields,
11239 ;; because they allow auto-increment addresses to be generated.
11241 (define_expand "insv"
11242 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11243 (match_operand:SI 1 "immediate_operand" "")
11244 (match_operand:SI 2 "immediate_operand" ""))
11245 (match_operand:SI 3 "general_operand" ""))]
11246 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11249 rtx addr_target, orig_address, shift_reg, qi_val;
11250 HOST_WIDE_INT bitsize, size, v = 0;
11251 rtx x = operands[3];
11253 /* ??? expmed doesn't care for non-register predicates. */
11254 if (! memory_operand (operands[0], VOIDmode)
11255 || ! immediate_operand (operands[1], VOIDmode)
11256 || ! immediate_operand (operands[2], VOIDmode)
11257 || ! general_operand (x, VOIDmode))
11259 /* If this isn't a 16 / 24 / 32 bit field, or if
11260 it doesn't start on a byte boundary, then fail. */
11261 bitsize = INTVAL (operands[1]);
11262 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11263 || (INTVAL (operands[2]) % 8) != 0)
11266 size = bitsize / 8;
11267 orig_address = XEXP (operands[0], 0);
11268 shift_reg = gen_reg_rtx (SImode);
11269 if (GET_CODE (x) == CONST_INT)
11272 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11276 emit_insn (gen_movsi (shift_reg, operands[3]));
11277 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11279 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11281 operands[0] = replace_equiv_address (operands[0], addr_target);
11282 emit_insn (gen_movqi (operands[0], qi_val));
11286 if (GET_CODE (x) == CONST_INT)
11288 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11291 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11292 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11294 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11295 emit_insn (gen_movqi (operands[0], qi_val));
11301 (define_insn "movua"
11302 [(set (match_operand:SI 0 "register_operand" "=z")
11303 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11307 [(set_attr "type" "movua")])
11309 ;; We shouldn't need this, but cse replaces increments with references
11310 ;; to other regs before flow has a chance to create post_inc
11311 ;; addressing modes, and only postreload's cse_move2add brings the
11312 ;; increments back to a usable form.
11314 [(set (match_operand:SI 0 "register_operand" "")
11315 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11316 (const_int 32) (const_int 0)))
11317 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11318 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11319 [(set (match_operand:SI 0 "register_operand" "")
11320 (sign_extract:SI (mem:SI (post_inc:SI
11321 (match_operand:SI 1 "register_operand" "")))
11322 (const_int 32) (const_int 0)))]
11325 (define_expand "extv"
11326 [(set (match_operand:SI 0 "register_operand" "")
11327 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11328 (match_operand 2 "const_int_operand" "")
11329 (match_operand 3 "const_int_operand" "")))]
11332 if (TARGET_SH4A_ARCH
11333 && INTVAL (operands[2]) == 32
11334 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11335 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11337 rtx src = adjust_address (operands[1], BLKmode, 0);
11338 set_mem_size (src, GEN_INT (4));
11339 emit_insn (gen_movua (operands[0], src));
11346 (define_expand "extzv"
11347 [(set (match_operand:SI 0 "register_operand" "")
11348 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11349 (match_operand 2 "const_int_operand" "")
11350 (match_operand 3 "const_int_operand" "")))]
11353 if (TARGET_SH4A_ARCH
11354 && INTVAL (operands[2]) == 32
11355 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11356 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11358 rtx src = adjust_address (operands[1], BLKmode, 0);
11359 set_mem_size (src, GEN_INT (4));
11360 emit_insn (gen_movua (operands[0], src));
11368 ;; -------------------------------------------------------------------------
11370 ;; -------------------------------------------------------------------------
11372 ;; This matches cases where a stack pointer increment at the start of the
11373 ;; epilogue combines with a stack slot read loading the return value.
11376 [(set (match_operand:SI 0 "arith_reg_operand" "")
11377 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11378 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11379 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11382 ;; See the comment on the dt combiner pattern above.
11385 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11386 (plus:SI (match_dup 0)
11388 (set (reg:SI T_REG)
11389 (eq:SI (match_dup 0)
11394 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11395 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11396 ;; reload when the constant is too large for a reg+offset address.
11398 ;; ??? We would get much better code if this was done in reload. This would
11399 ;; require modifying find_reloads_address to recognize that if the constant
11400 ;; is out-of-range for an immediate add, then we get better code by reloading
11401 ;; the constant into a register than by reloading the sum into a register,
11402 ;; since the former is one instruction shorter if the address does not need
11403 ;; to be offsettable. Unfortunately this does not work, because there is
11404 ;; only one register, r0, that can be used as an index register. This register
11405 ;; is also the function return value register. So, if we try to force reload
11406 ;; to use double-reg addresses, then we end up with some instructions that
11407 ;; need to use r0 twice. The only way to fix this is to change the calling
11408 ;; convention so that r0 is not used to return values.
11411 [(set (match_operand:SI 0 "register_operand" "=r")
11412 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11413 (set (mem:SI (match_dup 0))
11414 (match_operand:SI 2 "general_movsrc_operand" ""))]
11415 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11416 "mov.l %2,@(%0,%1)")
11419 [(set (match_operand:SI 0 "register_operand" "=r")
11420 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11421 (set (match_operand:SI 2 "general_movdst_operand" "")
11422 (mem:SI (match_dup 0)))]
11423 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11424 "mov.l @(%0,%1),%2")
11427 [(set (match_operand:SI 0 "register_operand" "=r")
11428 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11429 (set (mem:HI (match_dup 0))
11430 (match_operand:HI 2 "general_movsrc_operand" ""))]
11431 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11432 "mov.w %2,@(%0,%1)")
11435 [(set (match_operand:SI 0 "register_operand" "=r")
11436 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11437 (set (match_operand:HI 2 "general_movdst_operand" "")
11438 (mem:HI (match_dup 0)))]
11439 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11440 "mov.w @(%0,%1),%2")
11443 [(set (match_operand:SI 0 "register_operand" "=r")
11444 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11445 (set (mem:QI (match_dup 0))
11446 (match_operand:QI 2 "general_movsrc_operand" ""))]
11447 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11448 "mov.b %2,@(%0,%1)")
11451 [(set (match_operand:SI 0 "register_operand" "=r")
11452 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11453 (set (match_operand:QI 2 "general_movdst_operand" "")
11454 (mem:QI (match_dup 0)))]
11455 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11456 "mov.b @(%0,%1),%2")
11459 [(set (match_operand:SI 0 "register_operand" "=r")
11460 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11461 (set (mem:SF (match_dup 0))
11462 (match_operand:SF 2 "general_movsrc_operand" ""))]
11463 "TARGET_SH1 && REGNO (operands[0]) == 0
11464 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11465 || (GET_CODE (operands[2]) == SUBREG
11466 && REGNO (SUBREG_REG (operands[2])) < 16))
11467 && reg_unused_after (operands[0], insn)"
11468 "mov.l %2,@(%0,%1)")
11471 [(set (match_operand:SI 0 "register_operand" "=r")
11472 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11473 (set (match_operand:SF 2 "general_movdst_operand" "")
11475 (mem:SF (match_dup 0)))]
11476 "TARGET_SH1 && REGNO (operands[0]) == 0
11477 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11478 || (GET_CODE (operands[2]) == SUBREG
11479 && REGNO (SUBREG_REG (operands[2])) < 16))
11480 && reg_unused_after (operands[0], insn)"
11481 "mov.l @(%0,%1),%2")
11484 [(set (match_operand:SI 0 "register_operand" "=r")
11485 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11486 (set (mem:SF (match_dup 0))
11487 (match_operand:SF 2 "general_movsrc_operand" ""))]
11488 "TARGET_SH2E && REGNO (operands[0]) == 0
11489 && ((GET_CODE (operands[2]) == REG
11490 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11491 || (GET_CODE (operands[2]) == SUBREG
11492 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11493 && reg_unused_after (operands[0], insn)"
11494 "fmov{.s|} %2,@(%0,%1)")
11497 [(set (match_operand:SI 0 "register_operand" "=r")
11498 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11499 (set (match_operand:SF 2 "general_movdst_operand" "")
11501 (mem:SF (match_dup 0)))]
11502 "TARGET_SH2E && REGNO (operands[0]) == 0
11503 && ((GET_CODE (operands[2]) == REG
11504 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11505 || (GET_CODE (operands[2]) == SUBREG
11506 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11507 && reg_unused_after (operands[0], insn)"
11508 "fmov{.s|} @(%0,%1),%2")
11510 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11511 (define_insn "sp_switch_1"
11512 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11516 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11517 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11518 return \"mov r0,r15\";
11520 [(set_attr "length" "10")])
11522 ;; Switch back to the original stack for interrupt functions with the
11523 ;; sp_switch attribute. */
11524 (define_insn "sp_switch_2"
11527 "mov.l @r15+,r15\;mov.l @r15+,r0"
11528 [(set_attr "length" "4")])
11530 ;; Integer vector moves
11532 (define_expand "movv8qi"
11533 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11534 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11536 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11538 (define_insn "movv8qi_i"
11539 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11540 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11542 && (register_operand (operands[0], V8QImode)
11543 || sh_register_operand (operands[1], V8QImode))"
11550 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11551 (set_attr "length" "4,4,16,4,4")])
11554 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11555 (subreg:V8QI (const_int 0) 0))]
11557 [(set (match_dup 0)
11558 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11559 (const_int 0) (const_int 0) (const_int 0)
11560 (const_int 0) (const_int 0)]))])
11563 [(set (match_operand 0 "arith_reg_dest" "")
11564 (match_operand 1 "sh_rep_vec" ""))]
11565 "TARGET_SHMEDIA && reload_completed
11566 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11567 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11568 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11569 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11570 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11571 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11572 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11573 [(set (match_dup 0) (match_dup 1))
11577 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11578 rtx elt1 = XVECEXP (operands[1], 0, 1);
11581 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11585 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11586 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11588 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11589 operands[1] = XVECEXP (operands[1], 0, 0);
11592 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11594 = GEN_INT (TARGET_LITTLE_ENDIAN
11595 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11596 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11599 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11601 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11607 [(set (match_operand 0 "arith_reg_dest" "")
11608 (match_operand 1 "sh_const_vec" ""))]
11609 "TARGET_SHMEDIA && reload_completed
11610 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11611 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11612 [(set (match_dup 0) (match_dup 1))]
11615 rtx v = operands[1];
11616 enum machine_mode new_mode
11617 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11619 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11621 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11624 (define_expand "movv2hi"
11625 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11626 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11628 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11630 (define_insn "movv2hi_i"
11631 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11632 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11634 && (register_operand (operands[0], V2HImode)
11635 || sh_register_operand (operands[1], V2HImode))"
11642 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11643 (set_attr "length" "4,4,16,4,4")
11644 (set (attr "highpart")
11645 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11646 (const_string "user")]
11647 (const_string "ignore")))])
11649 (define_expand "movv4hi"
11650 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11651 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11653 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11655 (define_insn "movv4hi_i"
11656 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11657 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11659 && (register_operand (operands[0], V4HImode)
11660 || sh_register_operand (operands[1], V4HImode))"
11667 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11668 (set_attr "length" "4,4,16,4,4")
11669 (set_attr "highpart" "depend")])
11671 (define_expand "movv2si"
11672 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11673 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11675 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11677 (define_insn "movv2si_i"
11678 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11679 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11681 && (register_operand (operands[0], V2SImode)
11682 || sh_register_operand (operands[1], V2SImode))"
11689 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11690 (set_attr "length" "4,4,16,4,4")
11691 (set_attr "highpart" "depend")])
11693 ;; Multimedia Intrinsics
11695 (define_insn "absv2si2"
11696 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11697 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11700 [(set_attr "type" "mcmp_media")
11701 (set_attr "highpart" "depend")])
11703 (define_insn "absv4hi2"
11704 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11705 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11708 [(set_attr "type" "mcmp_media")
11709 (set_attr "highpart" "depend")])
11711 (define_insn "addv2si3"
11712 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11713 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11714 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11716 "madd.l %1, %2, %0"
11717 [(set_attr "type" "arith_media")
11718 (set_attr "highpart" "depend")])
11720 (define_insn "addv4hi3"
11721 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11722 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11723 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11725 "madd.w %1, %2, %0"
11726 [(set_attr "type" "arith_media")
11727 (set_attr "highpart" "depend")])
11729 (define_insn_and_split "addv2hi3"
11730 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11731 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11732 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11739 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11740 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11741 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11742 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11743 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11745 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11746 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11749 [(set_attr "highpart" "must_split")])
11751 (define_insn "ssaddv2si3"
11752 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11753 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11754 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11756 "madds.l %1, %2, %0"
11757 [(set_attr "type" "mcmp_media")
11758 (set_attr "highpart" "depend")])
11760 (define_insn "usaddv8qi3"
11761 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11762 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11763 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11765 "madds.ub %1, %2, %0"
11766 [(set_attr "type" "mcmp_media")
11767 (set_attr "highpart" "depend")])
11769 (define_insn "ssaddv4hi3"
11770 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11771 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11772 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11774 "madds.w %1, %2, %0"
11775 [(set_attr "type" "mcmp_media")
11776 (set_attr "highpart" "depend")])
11778 (define_insn "negcmpeqv8qi"
11779 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11780 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11781 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11783 "mcmpeq.b %N1, %N2, %0"
11784 [(set_attr "type" "mcmp_media")
11785 (set_attr "highpart" "depend")])
11787 (define_insn "negcmpeqv2si"
11788 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11789 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11790 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11792 "mcmpeq.l %N1, %N2, %0"
11793 [(set_attr "type" "mcmp_media")
11794 (set_attr "highpart" "depend")])
11796 (define_insn "negcmpeqv4hi"
11797 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11798 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11799 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11801 "mcmpeq.w %N1, %N2, %0"
11802 [(set_attr "type" "mcmp_media")
11803 (set_attr "highpart" "depend")])
11805 (define_insn "negcmpgtuv8qi"
11806 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11807 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11808 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11810 "mcmpgt.ub %N1, %N2, %0"
11811 [(set_attr "type" "mcmp_media")
11812 (set_attr "highpart" "depend")])
11814 (define_insn "negcmpgtv2si"
11815 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11816 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11817 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11819 "mcmpgt.l %N1, %N2, %0"
11820 [(set_attr "type" "mcmp_media")
11821 (set_attr "highpart" "depend")])
11823 (define_insn "negcmpgtv4hi"
11824 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11825 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11826 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11828 "mcmpgt.w %N1, %N2, %0"
11829 [(set_attr "type" "mcmp_media")
11830 (set_attr "highpart" "depend")])
11832 (define_insn "mcmv"
11833 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11834 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11835 (match_operand:DI 2 "arith_reg_operand" "r"))
11836 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11837 (not:DI (match_dup 2)))))]
11840 [(set_attr "type" "arith_media")
11841 (set_attr "highpart" "depend")])
11843 (define_insn "mcnvs_lw"
11844 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11846 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11847 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11849 "mcnvs.lw %N1, %N2, %0"
11850 [(set_attr "type" "mcmp_media")])
11852 (define_insn "mcnvs_wb"
11853 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11855 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11856 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11858 "mcnvs.wb %N1, %N2, %0"
11859 [(set_attr "type" "mcmp_media")])
11861 (define_insn "mcnvs_wub"
11862 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11864 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11865 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11867 "mcnvs.wub %N1, %N2, %0"
11868 [(set_attr "type" "mcmp_media")])
11870 (define_insn "mextr_rl"
11871 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11872 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11873 (match_operand:HI 3 "mextr_bit_offset" "i"))
11874 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11875 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11876 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11879 static char templ[21];
11881 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11882 (int) INTVAL (operands[3]) >> 3);
11885 [(set_attr "type" "arith_media")])
11887 (define_insn "*mextr_lr"
11888 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11889 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11890 (match_operand:HI 3 "mextr_bit_offset" "i"))
11891 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11892 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11893 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11896 static char templ[21];
11898 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11899 (int) INTVAL (operands[4]) >> 3);
11902 [(set_attr "type" "arith_media")])
11904 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11905 ; vector then varies depending on endianness.
11906 (define_expand "mextr1"
11907 [(match_operand:DI 0 "arith_reg_dest" "")
11908 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11909 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11913 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11914 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11918 (define_expand "mextr2"
11919 [(match_operand:DI 0 "arith_reg_dest" "")
11920 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11921 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11925 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11926 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11930 (define_expand "mextr3"
11931 [(match_operand:DI 0 "arith_reg_dest" "")
11932 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11933 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11937 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11938 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11942 (define_expand "mextr4"
11943 [(match_operand:DI 0 "arith_reg_dest" "")
11944 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11945 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11949 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11950 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11954 (define_expand "mextr5"
11955 [(match_operand:DI 0 "arith_reg_dest" "")
11956 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11957 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11961 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11962 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11966 (define_expand "mextr6"
11967 [(match_operand:DI 0 "arith_reg_dest" "")
11968 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11969 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11973 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11974 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11978 (define_expand "mextr7"
11979 [(match_operand:DI 0 "arith_reg_dest" "")
11980 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11981 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11985 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11986 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11990 (define_expand "mmacfx_wl"
11991 [(match_operand:V2SI 0 "arith_reg_dest" "")
11992 (match_operand:V2HI 1 "extend_reg_operand" "")
11993 (match_operand:V2HI 2 "extend_reg_operand" "")
11994 (match_operand:V2SI 3 "arith_reg_operand" "")]
11998 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11999 operands[1], operands[2]));
12003 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12005 (define_insn "mmacfx_wl_i"
12006 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12008 (match_operand:V2SI 1 "arith_reg_operand" "0")
12013 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12014 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12017 "mmacfx.wl %2, %3, %0"
12018 [(set_attr "type" "mac_media")
12019 (set_attr "highpart" "depend")])
12021 (define_expand "mmacnfx_wl"
12022 [(match_operand:V2SI 0 "arith_reg_dest" "")
12023 (match_operand:V2HI 1 "extend_reg_operand" "")
12024 (match_operand:V2HI 2 "extend_reg_operand" "")
12025 (match_operand:V2SI 3 "arith_reg_operand" "")]
12029 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12030 operands[1], operands[2]));
12034 (define_insn "mmacnfx_wl_i"
12035 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12037 (match_operand:V2SI 1 "arith_reg_operand" "0")
12042 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12043 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12046 "mmacnfx.wl %2, %3, %0"
12047 [(set_attr "type" "mac_media")
12048 (set_attr "highpart" "depend")])
12050 (define_insn "mulv2si3"
12051 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12052 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12053 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12055 "mmul.l %1, %2, %0"
12056 [(set_attr "type" "d2mpy_media")
12057 (set_attr "highpart" "depend")])
12059 (define_insn "mulv4hi3"
12060 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12061 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12062 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12064 "mmul.w %1, %2, %0"
12065 [(set_attr "type" "dmpy_media")
12066 (set_attr "highpart" "depend")])
12068 (define_insn "mmulfx_l"
12069 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12073 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12074 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12077 "mmulfx.l %1, %2, %0"
12078 [(set_attr "type" "d2mpy_media")
12079 (set_attr "highpart" "depend")])
12081 (define_insn "mmulfx_w"
12082 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12086 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12087 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12090 "mmulfx.w %1, %2, %0"
12091 [(set_attr "type" "dmpy_media")
12092 (set_attr "highpart" "depend")])
12094 (define_insn "mmulfxrp_w"
12095 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12100 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12101 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12105 "mmulfxrp.w %1, %2, %0"
12106 [(set_attr "type" "dmpy_media")
12107 (set_attr "highpart" "depend")])
12110 (define_expand "mmulhi_wl"
12111 [(match_operand:V2SI 0 "arith_reg_dest" "")
12112 (match_operand:V4HI 1 "arith_reg_operand" "")
12113 (match_operand:V4HI 2 "arith_reg_operand" "")]
12117 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12118 (operands[0], operands[1], operands[2]));
12122 (define_expand "mmullo_wl"
12123 [(match_operand:V2SI 0 "arith_reg_dest" "")
12124 (match_operand:V4HI 1 "arith_reg_operand" "")
12125 (match_operand:V4HI 2 "arith_reg_operand" "")]
12129 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12130 (operands[0], operands[1], operands[2]));
12134 (define_insn "mmul23_wl"
12135 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12138 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12139 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12140 (parallel [(const_int 2) (const_int 3)])))]
12142 "* return (TARGET_LITTLE_ENDIAN
12143 ? \"mmulhi.wl %1, %2, %0\"
12144 : \"mmullo.wl %1, %2, %0\");"
12145 [(set_attr "type" "dmpy_media")
12146 (set (attr "highpart")
12147 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12148 (const_string "user")))])
12150 (define_insn "mmul01_wl"
12151 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12154 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12155 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12156 (parallel [(const_int 0) (const_int 1)])))]
12158 "* return (TARGET_LITTLE_ENDIAN
12159 ? \"mmullo.wl %1, %2, %0\"
12160 : \"mmulhi.wl %1, %2, %0\");"
12161 [(set_attr "type" "dmpy_media")
12162 (set (attr "highpart")
12163 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12164 (const_string "user")))])
12167 (define_expand "mmulsum_wq"
12168 [(match_operand:DI 0 "arith_reg_dest" "")
12169 (match_operand:V4HI 1 "arith_reg_operand" "")
12170 (match_operand:V4HI 2 "arith_reg_operand" "")
12171 (match_operand:DI 3 "arith_reg_operand" "")]
12175 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12176 operands[1], operands[2]));
12180 (define_insn "mmulsum_wq_i"
12181 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12182 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12187 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12188 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12189 (parallel [(const_int 0)]))
12190 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12191 (sign_extend:V4DI (match_dup 3)))
12192 (parallel [(const_int 1)])))
12194 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12195 (sign_extend:V4DI (match_dup 3)))
12196 (parallel [(const_int 2)]))
12197 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12198 (sign_extend:V4DI (match_dup 3)))
12199 (parallel [(const_int 3)]))))))]
12201 "mmulsum.wq %2, %3, %0"
12202 [(set_attr "type" "mac_media")])
12204 (define_expand "mperm_w"
12205 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12206 (match_operand:V4HI 1 "arith_reg_operand" "r")
12207 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12211 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12212 (operands[0], operands[1], operands[2]));
12216 ; This use of vec_select isn't exactly correct according to rtl.texi
12217 ; (because not constant), but it seems a straightforward extension.
12218 (define_insn "mperm_w_little"
12219 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12221 (match_operand:V4HI 1 "arith_reg_operand" "r")
12223 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12224 (const_int 2) (const_int 0))
12225 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12226 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12227 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12228 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12229 "mperm.w %1, %N2, %0"
12230 [(set_attr "type" "arith_media")])
12232 (define_insn "mperm_w_big"
12233 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12235 (match_operand:V4HI 1 "arith_reg_operand" "r")
12237 [(zero_extract:QI (not:QI (match_operand:QI 2
12238 "extend_reg_or_0_operand" "rZ"))
12239 (const_int 2) (const_int 0))
12240 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12241 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12242 (zero_extract:QI (not:QI (match_dup 2))
12243 (const_int 2) (const_int 6))])))]
12244 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12245 "mperm.w %1, %N2, %0"
12246 [(set_attr "type" "arith_media")])
12248 (define_insn "mperm_w0"
12249 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12250 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12251 "trunc_hi_operand" "r"))))]
12253 "mperm.w %1, r63, %0"
12254 [(set_attr "type" "arith_media")
12255 (set_attr "highpart" "ignore")])
12257 (define_expand "msad_ubq"
12258 [(match_operand:DI 0 "arith_reg_dest" "")
12259 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12260 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12261 (match_operand:DI 3 "arith_reg_operand" "")]
12265 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12266 operands[1], operands[2]));
12270 (define_insn "msad_ubq_i"
12271 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12276 (match_operand:DI 1 "arith_reg_operand" "0")
12277 (abs:DI (vec_select:DI
12280 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12282 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12283 (parallel [(const_int 0)]))))
12284 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12285 (zero_extend:V8DI (match_dup 3)))
12286 (parallel [(const_int 1)]))))
12288 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12289 (zero_extend:V8DI (match_dup 3)))
12290 (parallel [(const_int 2)])))
12291 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12292 (zero_extend:V8DI (match_dup 3)))
12293 (parallel [(const_int 3)])))))
12296 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12297 (zero_extend:V8DI (match_dup 3)))
12298 (parallel [(const_int 4)])))
12299 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12300 (zero_extend:V8DI (match_dup 3)))
12301 (parallel [(const_int 5)]))))
12303 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12304 (zero_extend:V8DI (match_dup 3)))
12305 (parallel [(const_int 6)])))
12306 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12307 (zero_extend:V8DI (match_dup 3)))
12308 (parallel [(const_int 7)])))))))]
12310 "msad.ubq %N2, %N3, %0"
12311 [(set_attr "type" "mac_media")])
12313 (define_insn "mshalds_l"
12314 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12317 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12318 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12319 (const_int 31)))))]
12321 "mshalds.l %1, %2, %0"
12322 [(set_attr "type" "mcmp_media")
12323 (set_attr "highpart" "depend")])
12325 (define_insn "mshalds_w"
12326 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12329 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12330 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12331 (const_int 15)))))]
12333 "mshalds.w %1, %2, %0"
12334 [(set_attr "type" "mcmp_media")
12335 (set_attr "highpart" "depend")])
12337 (define_insn "ashrv2si3"
12338 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12339 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12340 (match_operand:DI 2 "arith_reg_operand" "r")))]
12342 "mshard.l %1, %2, %0"
12343 [(set_attr "type" "arith_media")
12344 (set_attr "highpart" "depend")])
12346 (define_insn "ashrv4hi3"
12347 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12348 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12349 (match_operand:DI 2 "arith_reg_operand" "r")))]
12351 "mshard.w %1, %2, %0"
12352 [(set_attr "type" "arith_media")
12353 (set_attr "highpart" "depend")])
12355 (define_insn "mshards_q"
12356 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12358 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12359 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12361 "mshards.q %1, %N2, %0"
12362 [(set_attr "type" "mcmp_media")])
12364 (define_expand "mshfhi_b"
12365 [(match_operand:V8QI 0 "arith_reg_dest" "")
12366 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12367 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12371 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12372 (operands[0], operands[1], operands[2]));
12376 (define_expand "mshflo_b"
12377 [(match_operand:V8QI 0 "arith_reg_dest" "")
12378 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12379 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12383 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12384 (operands[0], operands[1], operands[2]));
12388 (define_insn "mshf4_b"
12390 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12392 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12393 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12394 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12395 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12397 "* return (TARGET_LITTLE_ENDIAN
12398 ? \"mshfhi.b %N1, %N2, %0\"
12399 : \"mshflo.b %N1, %N2, %0\");"
12400 [(set_attr "type" "arith_media")
12401 (set (attr "highpart")
12402 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12403 (const_string "user")))])
12405 (define_insn "mshf0_b"
12407 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12409 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12410 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12411 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12412 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12414 "* return (TARGET_LITTLE_ENDIAN
12415 ? \"mshflo.b %N1, %N2, %0\"
12416 : \"mshfhi.b %N1, %N2, %0\");"
12417 [(set_attr "type" "arith_media")
12418 (set (attr "highpart")
12419 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12420 (const_string "user")))])
12422 (define_expand "mshfhi_l"
12423 [(match_operand:V2SI 0 "arith_reg_dest" "")
12424 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12425 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12429 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12430 (operands[0], operands[1], operands[2]));
12434 (define_expand "mshflo_l"
12435 [(match_operand:V2SI 0 "arith_reg_dest" "")
12436 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12437 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12441 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12442 (operands[0], operands[1], operands[2]));
12446 (define_insn "mshf4_l"
12447 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12449 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12450 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12451 (parallel [(const_int 1) (const_int 3)])))]
12453 "* return (TARGET_LITTLE_ENDIAN
12454 ? \"mshfhi.l %N1, %N2, %0\"
12455 : \"mshflo.l %N1, %N2, %0\");"
12456 [(set_attr "type" "arith_media")
12457 (set (attr "highpart")
12458 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12459 (const_string "user")))])
12461 (define_insn "mshf0_l"
12462 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12464 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12465 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12466 (parallel [(const_int 0) (const_int 2)])))]
12468 "* return (TARGET_LITTLE_ENDIAN
12469 ? \"mshflo.l %N1, %N2, %0\"
12470 : \"mshfhi.l %N1, %N2, %0\");"
12471 [(set_attr "type" "arith_media")
12472 (set (attr "highpart")
12473 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12474 (const_string "user")))])
12476 (define_expand "mshfhi_w"
12477 [(match_operand:V4HI 0 "arith_reg_dest" "")
12478 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12479 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12483 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12484 (operands[0], operands[1], operands[2]));
12488 (define_expand "mshflo_w"
12489 [(match_operand:V4HI 0 "arith_reg_dest" "")
12490 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12491 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12495 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12496 (operands[0], operands[1], operands[2]));
12500 (define_insn "mshf4_w"
12501 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12503 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12504 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12505 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12507 "* return (TARGET_LITTLE_ENDIAN
12508 ? \"mshfhi.w %N1, %N2, %0\"
12509 : \"mshflo.w %N1, %N2, %0\");"
12510 [(set_attr "type" "arith_media")
12511 (set (attr "highpart")
12512 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12513 (const_string "user")))])
12515 (define_insn "mshf0_w"
12516 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12518 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12519 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12520 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12522 "* return (TARGET_LITTLE_ENDIAN
12523 ? \"mshflo.w %N1, %N2, %0\"
12524 : \"mshfhi.w %N1, %N2, %0\");"
12525 [(set_attr "type" "arith_media")
12526 (set (attr "highpart")
12527 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12528 (const_string "user")))])
12530 (define_insn "mshflo_w_x"
12531 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12533 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12534 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12535 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12537 "mshflo.w %N1, %N2, %0"
12538 [(set_attr "type" "arith_media")
12539 (set_attr "highpart" "ignore")])
12541 /* These are useful to expand ANDs and as combiner patterns. */
12542 (define_insn_and_split "mshfhi_l_di"
12543 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12544 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12546 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12547 (const_int -4294967296))))]
12550 mshfhi.l %N1, %N2, %0
12552 "TARGET_SHMEDIA && reload_completed
12553 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12554 [(set (match_dup 3) (match_dup 4))
12555 (set (match_dup 5) (match_dup 6))]
12558 operands[3] = gen_lowpart (SImode, operands[0]);
12559 operands[4] = gen_highpart (SImode, operands[1]);
12560 operands[5] = gen_highpart (SImode, operands[0]);
12561 operands[6] = gen_highpart (SImode, operands[2]);
12563 [(set_attr "type" "arith_media")])
12565 (define_insn "*mshfhi_l_di_rev"
12566 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12567 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12568 (const_int -4294967296))
12569 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12572 "mshfhi.l %N2, %N1, %0"
12573 [(set_attr "type" "arith_media")])
12576 [(set (match_operand:DI 0 "arith_reg_dest" "")
12577 (ior:DI (zero_extend:DI (match_operand:SI 1
12578 "extend_reg_or_0_operand" ""))
12579 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12580 (const_int -4294967296))))
12581 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12586 emit_insn (gen_ashldi3_media (operands[3],
12587 simplify_gen_subreg (DImode, operands[1],
12590 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12594 (define_insn "mshflo_l_di"
12595 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12596 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12597 (const_int 4294967295))
12598 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12602 "mshflo.l %N1, %N2, %0"
12603 [(set_attr "type" "arith_media")
12604 (set_attr "highpart" "ignore")])
12606 (define_insn "*mshflo_l_di_rev"
12607 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12608 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12610 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12611 (const_int 4294967295))))]
12614 "mshflo.l %N2, %N1, %0"
12615 [(set_attr "type" "arith_media")
12616 (set_attr "highpart" "ignore")])
12618 ;; Combiner pattern for trampoline initialization.
12619 (define_insn_and_split "*double_shori"
12620 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12621 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12623 (match_operand:DI 2 "const_int_operand" "n")))]
12625 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12627 "rtx_equal_p (operands[0], operands[1])"
12631 HOST_WIDE_INT v = INTVAL (operands[2]);
12633 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12634 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12637 [(set_attr "highpart" "ignore")])
12640 (define_insn "*mshflo_l_di_x"
12641 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12642 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12644 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12648 "mshflo.l %N1, %N2, %0"
12649 [(set_attr "type" "arith_media")
12650 (set_attr "highpart" "ignore")])
12652 (define_insn_and_split "concat_v2sf"
12653 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12654 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12655 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12656 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12660 mshflo.l %N1, %N2, %0
12663 "TARGET_SHMEDIA && reload_completed
12664 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12665 [(set (match_dup 3) (match_dup 1))
12666 (set (match_dup 4) (match_dup 2))]
12669 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12670 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12672 [(set_attr "type" "arith_media")
12673 (set_attr "highpart" "ignore")])
12675 (define_insn "*mshflo_l_di_x_rev"
12676 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12677 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12679 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12682 "mshflo.l %N2, %N1, %0"
12683 [(set_attr "type" "arith_media")
12684 (set_attr "highpart" "ignore")])
12686 (define_insn "ashlv2si3"
12687 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12688 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12689 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12691 "mshlld.l %1, %2, %0"
12692 [(set_attr "type" "arith_media")
12693 (set_attr "highpart" "depend")])
12696 [(set (match_operand 0 "any_register_operand" "")
12697 (match_operator 3 "shift_operator"
12698 [(match_operand 1 "any_register_operand" "")
12699 (match_operand 2 "shift_count_reg_operand" "")]))]
12700 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12701 [(set (match_dup 0) (match_dup 3))]
12704 rtx count = operands[2];
12705 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12707 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12708 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12709 || GET_CODE (count) == TRUNCATE)
12710 count = XEXP (count, 0);
12711 inner_mode = GET_MODE (count);
12712 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12713 subreg_lowpart_offset (outer_mode, inner_mode));
12714 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12715 operands[1], count);
12718 (define_insn "ashlv4hi3"
12719 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12720 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12721 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12723 "mshlld.w %1, %2, %0"
12724 [(set_attr "type" "arith_media")
12725 (set_attr "highpart" "depend")])
12727 (define_insn "lshrv2si3"
12728 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12729 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12730 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12732 "mshlrd.l %1, %2, %0"
12733 [(set_attr "type" "arith_media")
12734 (set_attr "highpart" "depend")])
12736 (define_insn "lshrv4hi3"
12737 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12738 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12739 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12741 "mshlrd.w %1, %2, %0"
12742 [(set_attr "type" "arith_media")
12743 (set_attr "highpart" "depend")])
12745 (define_insn "subv2si3"
12746 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12747 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12748 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12750 "msub.l %N1, %2, %0"
12751 [(set_attr "type" "arith_media")
12752 (set_attr "highpart" "depend")])
12754 (define_insn "subv4hi3"
12755 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12756 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12757 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12759 "msub.w %N1, %2, %0"
12760 [(set_attr "type" "arith_media")
12761 (set_attr "highpart" "depend")])
12763 (define_insn_and_split "subv2hi3"
12764 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12765 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12766 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12773 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12774 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12775 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12776 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12777 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12779 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12780 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12783 [(set_attr "highpart" "must_split")])
12785 (define_insn "sssubv2si3"
12786 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12787 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12788 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12790 "msubs.l %N1, %2, %0"
12791 [(set_attr "type" "mcmp_media")
12792 (set_attr "highpart" "depend")])
12794 (define_insn "ussubv8qi3"
12795 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12796 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12797 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12799 "msubs.ub %N1, %2, %0"
12800 [(set_attr "type" "mcmp_media")
12801 (set_attr "highpart" "depend")])
12803 (define_insn "sssubv4hi3"
12804 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12805 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12806 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12808 "msubs.w %N1, %2, %0"
12809 [(set_attr "type" "mcmp_media")
12810 (set_attr "highpart" "depend")])
12812 ;; Floating Point Intrinsics
12814 (define_insn "fcosa_s"
12815 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12816 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12820 [(set_attr "type" "atrans_media")])
12822 (define_insn "fsina_s"
12823 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12824 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12828 [(set_attr "type" "atrans_media")])
12830 (define_insn "fipr"
12831 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12832 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12833 "fp_arith_reg_operand" "f")
12834 (match_operand:V4SF 2
12835 "fp_arith_reg_operand" "f"))
12836 (parallel [(const_int 0)]))
12837 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12838 (parallel [(const_int 1)])))
12839 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12840 (parallel [(const_int 2)]))
12841 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12842 (parallel [(const_int 3)])))))]
12844 "fipr.s %1, %2, %0"
12845 [(set_attr "type" "fparith_media")])
12847 (define_insn "fsrra_s"
12848 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12849 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12853 [(set_attr "type" "atrans_media")])
12855 (define_insn "ftrv"
12856 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12860 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12861 (parallel [(const_int 0) (const_int 5)
12862 (const_int 10) (const_int 15)]))
12863 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12865 (vec_select:V4SF (match_dup 1)
12866 (parallel [(const_int 4) (const_int 9)
12867 (const_int 14) (const_int 3)]))
12868 (vec_select:V4SF (match_dup 2)
12869 (parallel [(const_int 1) (const_int 2)
12870 (const_int 3) (const_int 0)]))))
12873 (vec_select:V4SF (match_dup 1)
12874 (parallel [(const_int 8) (const_int 13)
12875 (const_int 2) (const_int 7)]))
12876 (vec_select:V4SF (match_dup 2)
12877 (parallel [(const_int 2) (const_int 3)
12878 (const_int 0) (const_int 1)])))
12880 (vec_select:V4SF (match_dup 1)
12881 (parallel [(const_int 12) (const_int 1)
12882 (const_int 6) (const_int 11)]))
12883 (vec_select:V4SF (match_dup 2)
12884 (parallel [(const_int 3) (const_int 0)
12885 (const_int 1) (const_int 2)]))))))]
12887 "ftrv.s %1, %2, %0"
12888 [(set_attr "type" "fparith_media")])
12890 (define_insn "ldhi_l"
12891 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12893 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12896 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12900 [(set_attr "type" "load_media")])
12902 (define_insn "ldhi_q"
12903 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12905 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12908 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12912 [(set_attr "type" "load_media")])
12914 (define_insn_and_split "*ldhi_q_comb0"
12915 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12917 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12918 "register_operand" "r")
12919 (match_operand:SI 2
12920 "ua_offset" "I06"))
12923 (plus:SI (and:SI (match_dup 1) (const_int 7))
12926 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12930 "emit_insn (gen_ldhi_q (operands[0],
12931 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12935 (define_insn_and_split "*ldhi_q_comb1"
12936 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12938 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12939 "register_operand" "r")
12940 (match_operand:SI 2
12941 "ua_offset" "I06"))
12944 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12945 "ua_offset" "I06"))
12949 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12950 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12954 "emit_insn (gen_ldhi_q (operands[0],
12955 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12959 (define_insn "ldlo_l"
12960 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12962 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12964 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12965 (and:SI (match_dup 1) (const_int 3))))]
12968 [(set_attr "type" "load_media")])
12970 (define_insn "ldlo_q"
12971 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12973 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12975 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12976 (and:SI (match_dup 1) (const_int 7))))]
12979 [(set_attr "type" "load_media")])
12981 (define_insn_and_split "*ldlo_q_comb0"
12982 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12984 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12985 (match_operand:SI 2 "ua_offset" "I06"))
12987 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12988 (and:SI (match_dup 1) (const_int 7))))]
12989 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12993 "emit_insn (gen_ldlo_q (operands[0],
12994 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12997 (define_insn_and_split "*ldlo_q_comb1"
12998 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13000 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13001 (match_operand:SI 2 "ua_offset" "I06"))
13003 (minus:SI (const_int 8)
13004 (and:SI (plus:SI (match_dup 1)
13005 (match_operand:SI 3 "ua_offset" "I06"))
13007 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13008 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13009 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13013 "emit_insn (gen_ldlo_q (operands[0],
13014 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13017 (define_insn "sthi_l"
13018 [(set (zero_extract:SI
13019 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13022 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13024 (match_operand:SI 1 "arith_reg_operand" "r"))]
13027 [(set_attr "type" "ustore_media")])
13029 ;; All unaligned stores are considered to be 'narrow' because they typically
13030 ;; operate on less that a quadword, and when they operate on a full quadword,
13031 ;; the vanilla store high / store low sequence will cause a stall if not
13032 ;; scheduled apart.
13033 (define_insn "sthi_q"
13034 [(set (zero_extract:DI
13035 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13038 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13040 (match_operand:DI 1 "arith_reg_operand" "r"))]
13043 [(set_attr "type" "ustore_media")])
13045 (define_insn_and_split "*sthi_q_comb0"
13046 [(set (zero_extract:DI
13047 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13048 "register_operand" "r")
13049 (match_operand:SI 1 "ua_offset"
13053 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13055 (match_operand:DI 2 "arith_reg_operand" "r"))]
13056 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13060 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13064 (define_insn_and_split "*sthi_q_comb1"
13065 [(set (zero_extract:DI
13066 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13067 "register_operand" "r")
13068 (match_operand:SI 1 "ua_offset"
13072 (plus:SI (and:SI (plus:SI (match_dup 0)
13073 (match_operand:SI 2 "ua_offset" "I06"))
13077 (match_operand:DI 3 "arith_reg_operand" "r"))]
13078 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13079 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13083 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13087 ;; This is highpart user because the address is used as full 64 bit.
13088 (define_insn "stlo_l"
13089 [(set (zero_extract:SI
13090 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13092 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13093 (and:SI (match_dup 0) (const_int 3)))
13094 (match_operand:SI 1 "arith_reg_operand" "r"))]
13097 [(set_attr "type" "ustore_media")])
13099 (define_insn "stlo_q"
13100 [(set (zero_extract:DI
13101 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13103 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13104 (and:SI (match_dup 0) (const_int 7)))
13105 (match_operand:DI 1 "arith_reg_operand" "r"))]
13108 [(set_attr "type" "ustore_media")])
13110 (define_insn_and_split "*stlo_q_comb0"
13111 [(set (zero_extract:DI
13112 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13113 (match_operand:SI 1 "ua_offset" "I06"))
13115 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13116 (and:SI (match_dup 0) (const_int 7)))
13117 (match_operand:DI 2 "arith_reg_operand" "r"))]
13118 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13122 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13126 (define_insn_and_split "*stlo_q_comb1"
13127 [(set (zero_extract:DI
13128 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13129 (match_operand:SI 1 "ua_offset" "I06"))
13131 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13132 (match_operand:SI 2
13133 "ua_offset" "I06"))
13135 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13136 (match_operand:DI 3 "arith_reg_operand" "r"))]
13137 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13141 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13145 (define_insn "ldhi_l64"
13146 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13148 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13151 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13155 [(set_attr "type" "load_media")])
13157 (define_insn "ldhi_q64"
13158 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13160 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13163 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13167 [(set_attr "type" "load_media")])
13169 (define_insn "ldlo_l64"
13170 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13172 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13174 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13175 (and:DI (match_dup 1) (const_int 3))))]
13178 [(set_attr "type" "load_media")])
13180 (define_insn "ldlo_q64"
13181 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13183 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13185 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13186 (and:DI (match_dup 1) (const_int 7))))]
13189 [(set_attr "type" "load_media")])
13191 (define_insn "sthi_l64"
13192 [(set (zero_extract:SI
13193 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13196 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13198 (match_operand:SI 1 "arith_reg_operand" "r"))]
13201 [(set_attr "type" "ustore_media")])
13203 (define_insn "sthi_q64"
13204 [(set (zero_extract:DI
13205 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13208 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13210 (match_operand:DI 1 "arith_reg_operand" "r"))]
13213 [(set_attr "type" "ustore_media")])
13215 (define_insn "stlo_l64"
13216 [(set (zero_extract:SI
13217 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13219 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13220 (and:DI (match_dup 0) (const_int 3)))
13221 (match_operand:SI 1 "arith_reg_operand" "r"))]
13224 [(set_attr "type" "ustore_media")])
13226 (define_insn "stlo_q64"
13227 [(set (zero_extract:DI
13228 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13230 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13231 (and:DI (match_dup 0) (const_int 7)))
13232 (match_operand:DI 1 "arith_reg_operand" "r"))]
13235 [(set_attr "type" "ustore_media")])
13238 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13239 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13243 [(set_attr "type" "arith_media")])
13245 (define_insn "nsbsi"
13246 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13248 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13252 [(set_attr "type" "arith_media")])
13254 (define_insn "nsbdi"
13255 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13257 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13261 [(set_attr "type" "arith_media")])
13263 (define_expand "ffsdi2"
13264 [(set (match_operand:DI 0 "arith_reg_dest" "")
13265 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13269 rtx scratch = gen_reg_rtx (DImode);
13272 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13273 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13274 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13275 emit_insn (gen_nsbdi (scratch, scratch));
13276 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13277 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13278 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13279 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13284 (define_expand "ffssi2"
13285 [(set (match_operand:SI 0 "arith_reg_dest" "")
13286 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13290 rtx scratch = gen_reg_rtx (SImode);
13291 rtx discratch = gen_reg_rtx (DImode);
13294 emit_insn (gen_adddi3 (discratch,
13295 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13297 emit_insn (gen_andcdi3 (discratch,
13298 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13300 emit_insn (gen_nsbsi (scratch, discratch));
13301 last = emit_insn (gen_subsi3 (operands[0],
13302 force_reg (SImode, GEN_INT (63)), scratch));
13303 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13308 (define_insn "byterev"
13309 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13310 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13311 (parallel [(const_int 7) (const_int 6) (const_int 5)
13312 (const_int 4) (const_int 3) (const_int 2)
13313 (const_int 1) (const_int 0)])))]
13316 [(set_attr "type" "arith_media")])
13318 (define_insn "*prefetch_media"
13319 [(prefetch (match_operand:QI 0 "address_operand" "p")
13320 (match_operand:SI 1 "const_int_operand" "n")
13321 (match_operand:SI 2 "const_int_operand" "n"))]
13325 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13326 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13329 [(set_attr "type" "other")])
13331 (define_insn "*prefetch_i4"
13332 [(prefetch (match_operand:SI 0 "register_operand" "r")
13333 (match_operand:SI 1 "const_int_operand" "n")
13334 (match_operand:SI 2 "const_int_operand" "n"))]
13335 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13338 return \"pref @%0\";
13340 [(set_attr "type" "other")])
13342 (define_expand "prefetch"
13343 [(prefetch (match_operand 0 "address_operand" "p")
13344 (match_operand:SI 1 "const_int_operand" "n")
13345 (match_operand:SI 2 "const_int_operand" "n"))]
13346 "TARGET_HARD_SH4 || TARGET_SH5"
13349 if (GET_MODE (operands[0]) != Pmode
13350 || GET_CODE (operands[1]) != CONST_INT
13351 || GET_CODE (operands[2]) != CONST_INT)
13353 if (! TARGET_SHMEDIA)
13354 operands[0] = force_reg (Pmode, operands[0]);
13357 (define_insn "alloco_i"
13358 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13359 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13365 if (GET_CODE (operands[0]) == PLUS)
13367 xops[0] = XEXP (operands[0], 0);
13368 xops[1] = XEXP (operands[0], 1);
13372 xops[0] = operands[0];
13373 xops[1] = const0_rtx;
13375 output_asm_insn (\"alloco %0, %1\", xops);
13378 [(set_attr "type" "other")])
13381 [(set (match_operand 0 "any_register_operand" "")
13382 (match_operand 1 "" ""))]
13383 "TARGET_SHMEDIA && reload_completed"
13384 [(set (match_dup 0) (match_dup 1))]
13389 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13394 ; Stack Protector Patterns
13396 (define_expand "stack_protect_set"
13397 [(set (match_operand 0 "memory_operand" "")
13398 (match_operand 1 "memory_operand" ""))]
13401 if (TARGET_SHMEDIA)
13403 if (TARGET_SHMEDIA64)
13404 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13406 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13409 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13414 (define_insn "stack_protect_set_si"
13415 [(set (match_operand:SI 0 "memory_operand" "=m")
13416 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13417 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13419 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13420 [(set_attr "type" "other")
13421 (set_attr "length" "6")])
13423 (define_insn "stack_protect_set_si_media"
13424 [(set (match_operand:SI 0 "memory_operand" "=m")
13425 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13426 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13428 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13429 [(set_attr "type" "other")
13430 (set_attr "length" "12")])
13432 (define_insn "stack_protect_set_di_media"
13433 [(set (match_operand:DI 0 "memory_operand" "=m")
13434 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13435 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13437 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13438 [(set_attr "type" "other")
13439 (set_attr "length" "12")])
13441 (define_expand "stack_protect_test"
13442 [(match_operand 0 "memory_operand" "")
13443 (match_operand 1 "memory_operand" "")
13444 (match_operand 2 "" "")]
13447 if (TARGET_SHMEDIA)
13449 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13451 if (TARGET_SHMEDIA64)
13452 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13455 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13458 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13462 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13463 emit_jump_insn (gen_branch_true (operands[2]));
13469 (define_insn "stack_protect_test_si"
13470 [(set (reg:SI T_REG)
13471 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13472 (match_operand:SI 1 "memory_operand" "m")]
13474 (set (match_scratch:SI 2 "=&r") (const_int 0))
13475 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13477 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13478 [(set_attr "type" "other")
13479 (set_attr "length" "10")])
13481 (define_insn "stack_protect_test_si_media"
13482 [(set (match_operand:SI 0 "register_operand" "=&r")
13483 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13484 (match_operand:SI 2 "memory_operand" "m")]
13486 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13488 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13489 [(set_attr "type" "other")
13490 (set_attr "length" "16")])
13492 (define_insn "stack_protect_test_di_media"
13493 [(set (match_operand:DI 0 "register_operand" "=&r")
13494 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13495 (match_operand:DI 2 "memory_operand" "m")]
13497 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13499 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13500 [(set_attr "type" "other")
13501 (set_attr "length" "16")])