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 (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
425 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
426 (symbol_ref "code_for_indirect_jump_scratch")))
427 (cond [(eq_attr "braf_branch_p" "yes")
429 (eq (symbol_ref "flag_pic") (const_int 0))
431 (ne (symbol_ref "TARGET_SH2") (const_int 0))
432 (const_int 10)] (const_int 18))
433 (eq_attr "braf_branch_p" "yes")
435 ;; ??? using pc is not computed transitively.
436 (ne (match_dup 0) (match_dup 0))
438 (ne (symbol_ref ("flag_pic")) (const_int 0))
441 (eq_attr "type" "pt_media")
442 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
443 (const_int 20) (const_int 12))
444 (and (eq_attr "type" "jump_media")
445 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
447 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
451 ;; DFA descriptions for the pipelines
454 (include "shmedia.md")
457 (include "predicates.md")
459 ;; Definitions for filling delay slots
461 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
463 ;; ??? This should be (nil) instead of (const_int 0)
464 (define_attr "hit_stack" "yes,no"
465 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
468 (const_string "yes")))
470 (define_attr "interrupt_function" "no,yes"
471 (const (symbol_ref "current_function_interrupt")))
473 (define_attr "in_delay_slot" "yes,no"
474 (cond [(eq_attr "type" "cbranch") (const_string "no")
475 (eq_attr "type" "pcload,pcload_si") (const_string "no")
476 (eq_attr "needs_delay_slot" "yes") (const_string "no")
477 (eq_attr "length" "2") (const_string "yes")
478 ] (const_string "no")))
480 (define_attr "cond_delay_slot" "yes,no"
481 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
482 ] (const_string "no")))
484 (define_attr "is_sfunc" ""
485 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
487 (define_attr "is_mac_media" ""
488 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
490 (define_attr "branch_zero" "yes,no"
491 (cond [(eq_attr "type" "!cbranch") (const_string "no")
492 (ne (symbol_ref "(next_active_insn (insn)\
493 == (prev_active_insn\
494 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
495 && get_attr_length (next_active_insn (insn)) == 2")
497 (const_string "yes")]
498 (const_string "no")))
500 ;; SH4 Double-precision computation with double-precision result -
501 ;; the two halves are ready at different times.
502 (define_attr "dfp_comp" "yes,no"
503 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
504 (const_string "no")))
506 ;; Insns for which the latency of a preceding fp insn is decreased by one.
507 (define_attr "late_fp_use" "yes,no" (const_string "no"))
508 ;; And feeding insns for which this relevant.
509 (define_attr "any_fp_comp" "yes,no"
510 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
511 (const_string "yes")]
512 (const_string "no")))
514 (define_attr "any_int_load" "yes,no"
515 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
516 (const_string "yes")]
517 (const_string "no")))
519 (define_attr "highpart" "user, ignore, extend, depend, must_split"
520 (const_string "user"))
523 (eq_attr "needs_delay_slot" "yes")
524 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
526 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
527 ;; and thus we can't put a pop instruction in its delay slot.
528 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
529 ;; instruction can go in the delay slot.
531 ;; Since a normal return (rts) implicitly uses the PR register,
532 ;; we can't allow PR register loads in an rts delay slot.
535 (eq_attr "type" "return")
536 [(and (eq_attr "in_delay_slot" "yes")
537 (ior (and (eq_attr "interrupt_function" "no")
538 (eq_attr "type" "!pload,prset"))
539 (and (eq_attr "interrupt_function" "yes")
541 (ne (symbol_ref "TARGET_SH3") (const_int 0))
542 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
544 ;; Since a call implicitly uses the PR register, we can't allow
545 ;; a PR register store in a jsr delay slot.
548 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
549 [(and (eq_attr "in_delay_slot" "yes")
550 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
552 ;; Say that we have annulled true branches, since this gives smaller and
553 ;; faster code when branches are predicted as not taken.
555 ;; ??? The non-annulled condition should really be "in_delay_slot",
556 ;; but insns that can be filled in non-annulled get priority over insns
557 ;; that can only be filled in anulled.
560 (and (eq_attr "type" "cbranch")
561 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
562 ;; SH2e has a hardware bug that pretty much prohibits the use of
563 ;; annuled delay slots.
564 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
565 (not (eq_attr "cpu" "sh2e"))) (nil)])
567 ;; -------------------------------------------------------------------------
568 ;; SImode signed integer comparisons
569 ;; -------------------------------------------------------------------------
573 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
574 (match_operand:SI 1 "arith_operand" "K08,r"))
578 [(set_attr "type" "mt_group")])
580 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
581 ;; That would still allow reload to create cmpi instructions, but would
582 ;; perhaps allow forcing the constant into a register when that is better.
583 ;; Probably should use r0 for mem/imm compares, but force constant into a
584 ;; register for pseudo/imm compares.
586 (define_insn "cmpeqsi_t"
588 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
589 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
595 [(set_attr "type" "mt_group")])
597 (define_insn "cmpgtsi_t"
599 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
600 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
605 [(set_attr "type" "mt_group")])
607 (define_insn "cmpgesi_t"
609 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
610 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
615 [(set_attr "type" "mt_group")])
617 ;; -------------------------------------------------------------------------
618 ;; SImode compare and branch
619 ;; -------------------------------------------------------------------------
621 (define_expand "cbranchsi4"
623 (if_then_else (match_operator 0 "comparison_operator"
624 [(match_operand:SI 1 "arith_operand" "")
625 (match_operand:SI 2 "arith_operand" "")])
626 (label_ref (match_operand 3 "" ""))
628 (clobber (reg:SI T_REG))]
630 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
632 ;; -------------------------------------------------------------------------
633 ;; SImode unsigned integer comparisons
634 ;; -------------------------------------------------------------------------
636 (define_insn_and_split "cmpgeusi_t"
638 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
639 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
642 "&& operands[0] == CONST0_RTX (SImode)"
646 emit_insn (gen_sett ());
649 [(set_attr "type" "mt_group")])
651 (define_insn "cmpgtusi_t"
653 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
654 (match_operand:SI 1 "arith_reg_operand" "r")))]
657 [(set_attr "type" "mt_group")])
659 ;; We save the compare operands in the cmpxx patterns and use them when
660 ;; we generate the branch.
662 (define_expand "cmpsi"
664 (compare (match_operand:SI 0 "cmpsi_operand" "")
665 (match_operand:SI 1 "arith_operand" "")))]
666 "TARGET_SH1 || TARGET_SHMEDIA"
669 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
670 && GET_CODE (operands[1]) != CONST_INT)
671 operands[0] = copy_to_mode_reg (SImode, operands[0]);
672 sh_compare_op0 = operands[0];
673 sh_compare_op1 = operands[1];
677 ;; -------------------------------------------------------------------------
678 ;; DImode compare and branch
679 ;; -------------------------------------------------------------------------
682 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
683 ;; Therefore, we aim to have a set of three branches that go straight to the
684 ;; destination, i.e. only one of them is taken at any one time.
685 ;; This mechanism should also be slightly better for the sh4-200.
687 (define_expand "cbranchdi4"
689 (if_then_else (match_operator 0 "comparison_operator"
690 [(match_operand:DI 1 "arith_operand" "")
691 (match_operand:DI 2 "arith_operand" "")])
692 (label_ref (match_operand 3 "" ""))
694 (clobber (match_dup 4))
695 (clobber (reg:SI T_REG))]
699 enum rtx_code comparison;
701 if (TARGET_EXPAND_CBRANCHDI4)
703 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
706 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
707 if (comparison != GET_CODE (operands[0]))
709 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
710 operands[4] = gen_rtx_SCRATCH (SImode);
713 (define_insn_and_split "cbranchdi4_i"
715 (if_then_else (match_operator 0 "comparison_operator"
716 [(match_operand:DI 1 "arith_operand" "r,r")
717 (match_operand:DI 2 "arith_operand" "rN,i")])
718 (label_ref (match_operand 3 "" ""))
720 (clobber (match_scratch:SI 4 "=X,&r"))
721 (clobber (reg:SI T_REG))]
724 "&& reload_completed"
728 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
733 ;; -------------------------------------------------------------------------
734 ;; DImode signed integer comparisons
735 ;; -------------------------------------------------------------------------
739 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
740 (match_operand:DI 1 "arith_operand" "r"))
743 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
745 [(set_attr "length" "6")
746 (set_attr "type" "arith3b")])
748 (define_insn "cmpeqdi_t"
750 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
751 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
754 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
755 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
756 [(set_attr "length" "6")
757 (set_attr "type" "arith3b")])
761 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
762 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
763 ;; If we applied this split when not optimizing, it would only be
764 ;; applied during the machine-dependent reorg, when no new basic blocks
766 "TARGET_SH1 && reload_completed && optimize"
767 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
768 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
769 (label_ref (match_dup 6))
771 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
776 = gen_rtx_REG (SImode,
777 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
779 = (operands[1] == const0_rtx
781 : gen_rtx_REG (SImode,
782 true_regnum (operands[1])
783 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
784 operands[4] = gen_lowpart (SImode, operands[0]);
785 operands[5] = gen_lowpart (SImode, operands[1]);
786 operands[6] = gen_label_rtx ();
789 (define_insn "cmpgtdi_t"
791 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
792 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
795 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
796 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
797 [(set_attr "length" "8")
798 (set_attr "type" "arith3")])
800 (define_insn "cmpgedi_t"
802 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
803 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
806 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
808 [(set_attr "length" "8,2")
809 (set_attr "type" "arith3,mt_group")])
811 ;; -------------------------------------------------------------------------
812 ;; DImode unsigned integer comparisons
813 ;; -------------------------------------------------------------------------
815 (define_insn "cmpgeudi_t"
817 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
818 (match_operand:DI 1 "arith_reg_operand" "r")))]
820 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
821 [(set_attr "length" "8")
822 (set_attr "type" "arith3")])
824 (define_insn "cmpgtudi_t"
826 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827 (match_operand:DI 1 "arith_reg_operand" "r")))]
829 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
830 [(set_attr "length" "8")
831 (set_attr "type" "arith3")])
833 (define_insn "cmpeqsi_media"
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
836 (match_operand:SI 2 "cmp_operand" "Nr")))]
839 [(set_attr "type" "cmp_media")])
841 (define_insn "cmpeqdi_media"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (eq:SI (match_operand:DI 1 "register_operand" "%r")
844 (match_operand:DI 2 "cmp_operand" "Nr")))]
847 [(set_attr "type" "cmp_media")])
849 (define_insn "cmpgtsi_media"
850 [(set (match_operand:SI 0 "register_operand" "=r")
851 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
852 (match_operand:SI 2 "cmp_operand" "rN")))]
855 [(set_attr "type" "cmp_media")])
857 (define_insn "cmpgtdi_media"
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
860 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
863 [(set_attr "type" "cmp_media")])
865 (define_insn "cmpgtusi_media"
866 [(set (match_operand:SI 0 "register_operand" "=r")
867 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
868 (match_operand:SI 2 "cmp_operand" "rN")))]
870 "cmpgtu %N1, %N2, %0"
871 [(set_attr "type" "cmp_media")])
873 (define_insn "cmpgtudi_media"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
876 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
878 "cmpgtu %N1, %N2, %0"
879 [(set_attr "type" "cmp_media")])
881 ; These two patterns are for combine.
882 (define_insn "*cmpne0sisi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
887 [(set_attr "type" "cmp_media")])
889 ;; We save the compare operands in the cmpxx patterns and use them when
890 ;; we generate the branch.
892 (define_expand "cmpdi"
894 (compare (match_operand:DI 0 "arith_operand" "")
895 (match_operand:DI 1 "arith_operand" "")))]
896 "TARGET_SH2 || TARGET_SHMEDIA"
899 sh_compare_op0 = operands[0];
900 sh_compare_op1 = operands[1];
903 ;; -------------------------------------------------------------------------
904 ;; Conditional move instructions
905 ;; -------------------------------------------------------------------------
907 ;; The insn names may seem reversed, but note that cmveq performs the move
908 ;; if op1 == 0, and cmvne does it if op1 != 0.
910 (define_insn "movdicc_false"
911 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
912 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
914 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
915 (match_operand:DI 3 "arith_reg_operand" "0")))]
918 [(set_attr "type" "arith_media")])
920 (define_insn "movdicc_true"
921 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
922 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
924 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
925 (match_operand:DI 3 "arith_reg_operand" "0")))]
928 [(set_attr "type" "arith_media")])
931 [(set (match_operand:DI 0 "arith_reg_dest" "")
932 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
933 [(match_operand:DI 1 "arith_reg_operand" "")
935 (match_operand:DI 2 "arith_reg_dest" "")
937 (set (match_dup 2) (match_dup 0))]
938 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
940 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
943 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
944 VOIDmode, operands[1], CONST0_RTX (DImode));
948 [(set (match_operand:DI 0 "general_movdst_operand" "")
949 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
950 (set (match_operand:DI 2 "arith_reg_dest" "")
951 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
952 [(match_operand:DI 3 "arith_reg_operand" "")
956 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
958 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
961 (define_expand "movdicc"
962 [(set (match_operand:DI 0 "register_operand" "")
963 (if_then_else:DI (match_operand 1 "comparison_operator" "")
964 (match_operand:DI 2 "register_operand" "")
965 (match_operand:DI 3 "register_operand" "")))]
969 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
970 && GET_MODE (sh_compare_op0) == DImode
971 && sh_compare_op1 == const0_rtx)
972 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
973 sh_compare_op0, sh_compare_op1);
981 tmp = gen_reg_rtx (DImode);
983 switch (GET_CODE (operands[1]))
986 emit_insn (gen_seq (tmp));
987 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
991 emit_insn (gen_seq (tmp));
992 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
996 emit_insn (gen_sgt (tmp));
997 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1001 emit_insn (gen_slt (tmp));
1002 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1006 emit_insn (gen_slt (tmp));
1007 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1011 emit_insn (gen_sgt (tmp));
1012 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016 emit_insn (gen_sgtu (tmp));
1017 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1021 emit_insn (gen_sltu (tmp));
1022 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1026 emit_insn (gen_sltu (tmp));
1027 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1031 emit_insn (gen_sgtu (tmp));
1032 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1036 emit_insn (gen_sunordered (tmp));
1037 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1041 emit_insn (gen_sunordered (tmp));
1042 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1059 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1060 ;; SImode to DImode.
1061 (define_insn "movsicc_false"
1062 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1063 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1065 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1066 (match_operand:SI 3 "arith_reg_operand" "0")))]
1069 [(set_attr "type" "arith_media")])
1071 (define_insn "movsicc_true"
1072 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1073 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1075 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1076 (match_operand:SI 3 "arith_reg_operand" "0")))]
1079 [(set_attr "type" "arith_media")])
1082 [(set (match_operand:SI 0 "arith_reg_dest" "")
1083 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1084 [(match_operand:SI 1 "arith_reg_operand" "")
1086 (match_operand:SI 2 "arith_reg_dest" "")
1088 (set (match_dup 2) (match_dup 0))]
1089 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1091 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1094 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1095 VOIDmode, operands[1], CONST0_RTX (SImode));
1099 [(set (match_operand:SI 0 "general_movdst_operand" "")
1100 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1101 (set (match_operand:SI 2 "arith_reg_dest" "")
1102 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1103 [(match_operand:SI 3 "arith_reg_operand" "")
1107 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1108 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1110 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1113 replace_rtx (operands[4], operands[0], operands[1]);
1117 [(set (match_operand 0 "any_register_operand" "")
1118 (match_operand 1 "any_register_operand" ""))
1119 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1120 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1121 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1122 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1123 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1124 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1125 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1126 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1127 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1128 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1129 && (REGNO_REG_CLASS (REGNO (operands[0]))
1130 == REGNO_REG_CLASS (REGNO (operands[2])))
1131 && (REGNO_REG_CLASS (REGNO (operands[1]))
1132 == REGNO_REG_CLASS (REGNO (operands[0])))"
1133 [(set (match_dup 0) (match_dup 3))
1134 (set (match_dup 4) (match_dup 5))]
1138 rtx replacements[4];
1140 /* We want to replace occurrences of operands[0] with operands[1] and
1141 operands[2] with operands[0] in operands[4]/operands[5].
1142 Doing just two replace_rtx calls naively would result in the second
1143 replacement undoing all that the first did if operands[1] and operands[2]
1144 are identical, so we must do this simultaneously. */
1145 replacements[0] = operands[0];
1146 replacements[1] = operands[1];
1147 replacements[2] = operands[2];
1148 replacements[3] = operands[0];
1149 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1150 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1151 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1154 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1155 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1156 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1157 /* The operands array is aliased to recog_data.operand, which gets
1158 clobbered by extract_insn, so finish with it now. */
1159 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1160 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1161 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1162 always uses emit_insn. */
1163 /* Check that we don't violate matching constraints or earlyclobbers. */
1164 extract_insn (emit_insn (set1));
1165 if (! constrain_operands (1))
1167 extract_insn (emit (set2));
1168 if (! constrain_operands (1))
1172 tmp = replacements[0];
1173 replacements[0] = replacements[1];
1174 replacements[1] = tmp;
1175 tmp = replacements[2];
1176 replacements[2] = replacements[3];
1177 replacements[3] = tmp;
1178 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1179 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1180 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1186 ;; The register allocator is rather clumsy in handling multi-way conditional
1187 ;; moves, so allow the combiner to make them, and we split them up after
1189 (define_insn_and_split "*movsicc_umin"
1190 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1191 (umin:SI (if_then_else:SI
1192 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1194 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1195 (match_operand:SI 3 "register_operand" "0"))
1196 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1197 (clobber (match_scratch:SI 5 "=&r"))]
1198 "TARGET_SHMEDIA && no_new_pseudos"
1200 "TARGET_SHMEDIA && reload_completed"
1204 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1206 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1207 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1212 (define_insn "*movsicc_t_false"
1213 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1214 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1215 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1216 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1217 "TARGET_PRETEND_CMOVE
1218 && (arith_reg_operand (operands[1], SImode)
1219 || (immediate_operand (operands[1], SImode)
1220 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1221 "bt 0f\;mov %1,%0\\n0:"
1222 [(set_attr "type" "mt_group,arith") ;; poor approximation
1223 (set_attr "length" "4")])
1225 (define_insn "*movsicc_t_true"
1226 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1227 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1228 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1229 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1230 "TARGET_PRETEND_CMOVE
1231 && (arith_reg_operand (operands[1], SImode)
1232 || (immediate_operand (operands[1], SImode)
1233 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1234 "bf 0f\;mov %1,%0\\n0:"
1235 [(set_attr "type" "mt_group,arith") ;; poor approximation
1236 (set_attr "length" "4")])
1238 (define_expand "movsicc"
1239 [(set (match_operand:SI 0 "arith_reg_dest" "")
1240 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1241 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1242 (match_operand:SI 3 "arith_reg_operand" "")))]
1243 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1246 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1247 && GET_MODE (sh_compare_op0) == SImode
1249 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1250 && sh_compare_op1 == const0_rtx)
1251 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1252 sh_compare_op0, sh_compare_op1);
1253 else if (TARGET_PRETEND_CMOVE)
1255 enum rtx_code code = GET_CODE (operands[1]);
1256 enum rtx_code new_code = code;
1259 if (! currently_expanding_to_rtl)
1263 case LT: case LE: case LEU: case LTU:
1264 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1267 new_code = reverse_condition (code);
1269 case EQ: case GT: case GE: case GEU: case GTU:
1274 tmp = prepare_scc_operands (new_code);
1275 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1285 tmp = gen_reg_rtx (SImode);
1287 switch (GET_CODE (operands[1]))
1290 emit_insn (gen_seq (tmp));
1291 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1295 emit_insn (gen_seq (tmp));
1296 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1300 emit_insn (gen_sgt (tmp));
1301 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1305 emit_insn (gen_slt (tmp));
1306 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1310 emit_insn (gen_slt (tmp));
1311 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1315 emit_insn (gen_sgt (tmp));
1316 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1320 emit_insn (gen_sgtu (tmp));
1321 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1325 emit_insn (gen_sltu (tmp));
1326 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1330 emit_insn (gen_sltu (tmp));
1331 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1335 emit_insn (gen_sgtu (tmp));
1336 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1340 emit_insn (gen_sunordered (tmp));
1341 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1345 emit_insn (gen_sunordered (tmp));
1346 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1363 (define_expand "movqicc"
1364 [(set (match_operand:QI 0 "register_operand" "")
1365 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1366 (match_operand:QI 2 "register_operand" "")
1367 (match_operand:QI 3 "register_operand" "")))]
1371 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1372 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1373 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1374 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1378 ;; -------------------------------------------------------------------------
1379 ;; Addition instructions
1380 ;; -------------------------------------------------------------------------
1382 (define_expand "adddi3"
1383 [(set (match_operand:DI 0 "arith_reg_operand" "")
1384 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1385 (match_operand:DI 2 "arith_operand" "")))]
1391 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1393 operands[2] = force_reg (DImode, operands[2]);
1394 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1399 (define_insn "*adddi3_media"
1400 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1401 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1402 (match_operand:DI 2 "arith_operand" "r,I10")))]
1407 [(set_attr "type" "arith_media")])
1409 (define_insn "*adddisi3_media"
1410 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1411 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1412 (match_operand:DI 2 "arith_operand" "r,I10")))]
1417 [(set_attr "type" "arith_media")
1418 (set_attr "highpart" "ignore")])
1420 (define_insn "adddi3z_media"
1421 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1423 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1424 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1426 "addz.l %1, %N2, %0"
1427 [(set_attr "type" "arith_media")
1428 (set_attr "highpart" "ignore")])
1430 (define_insn "adddi3_compact"
1431 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1432 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1433 (match_operand:DI 2 "arith_reg_operand" "r")))
1434 (clobber (reg:SI T_REG))]
1437 [(set_attr "length" "6")])
1440 [(set (match_operand:DI 0 "arith_reg_dest" "")
1441 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1442 (match_operand:DI 2 "arith_reg_operand" "")))
1443 (clobber (reg:SI T_REG))]
1444 "TARGET_SH1 && reload_completed"
1448 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1449 high0 = gen_rtx_REG (SImode,
1450 true_regnum (operands[0])
1451 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1452 high2 = gen_rtx_REG (SImode,
1453 true_regnum (operands[2])
1454 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1455 emit_insn (gen_clrt ());
1456 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1457 emit_insn (gen_addc1 (high0, high0, high2));
1462 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1463 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1464 (match_operand:SI 2 "arith_reg_operand" "r"))
1467 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1470 [(set_attr "type" "arith")])
1472 (define_insn "addc1"
1473 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1474 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1475 (match_operand:SI 2 "arith_reg_operand" "r"))
1477 (clobber (reg:SI T_REG))]
1480 [(set_attr "type" "arith")])
1482 (define_expand "addsi3"
1483 [(set (match_operand:SI 0 "arith_reg_operand" "")
1484 (plus:SI (match_operand:SI 1 "arith_operand" "")
1485 (match_operand:SI 2 "arith_operand" "")))]
1490 operands[1] = force_reg (SImode, operands[1]);
1493 (define_insn "addsi3_media"
1494 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1495 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1496 (match_operand:SI 2 "arith_operand" "r,I10")))]
1501 [(set_attr "type" "arith_media")
1502 (set_attr "highpart" "ignore")])
1504 (define_insn "addsidi3_media"
1505 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1506 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1508 (match_operand:SI 2 "arith_operand"
1514 [(set_attr "type" "arith_media")
1515 (set_attr "highpart" "ignore")])
1517 (define_insn "*addsi3_compact"
1518 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1519 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1520 (match_operand:SI 2 "arith_operand" "rI08")))]
1523 [(set_attr "type" "arith")])
1525 ;; -------------------------------------------------------------------------
1526 ;; Subtraction instructions
1527 ;; -------------------------------------------------------------------------
1529 (define_expand "subdi3"
1530 [(set (match_operand:DI 0 "arith_reg_operand" "")
1531 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1532 (match_operand:DI 2 "arith_reg_operand" "")))]
1538 operands[1] = force_reg (DImode, operands[1]);
1539 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1544 (define_insn "*subdi3_media"
1545 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1546 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1547 (match_operand:DI 2 "arith_reg_operand" "r")))]
1550 [(set_attr "type" "arith_media")])
1552 (define_insn "subdisi3_media"
1553 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1554 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1555 (match_operand:DI 2 "arith_reg_operand" "r")))]
1558 [(set_attr "type" "arith_media")
1559 (set_attr "highpart" "ignore")])
1561 (define_insn "subdi3_compact"
1562 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1563 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1564 (match_operand:DI 2 "arith_reg_operand" "r")))
1565 (clobber (reg:SI T_REG))]
1568 [(set_attr "length" "6")])
1571 [(set (match_operand:DI 0 "arith_reg_dest" "")
1572 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1573 (match_operand:DI 2 "arith_reg_operand" "")))
1574 (clobber (reg:SI T_REG))]
1575 "TARGET_SH1 && reload_completed"
1579 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1580 high0 = gen_rtx_REG (SImode,
1581 true_regnum (operands[0])
1582 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1583 high2 = gen_rtx_REG (SImode,
1584 true_regnum (operands[2])
1585 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1586 emit_insn (gen_clrt ());
1587 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1588 emit_insn (gen_subc1 (high0, high0, high2));
1593 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1594 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1595 (match_operand:SI 2 "arith_reg_operand" "r"))
1598 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1603 [(set_attr "type" "arith")])
1605 (define_insn "subc1"
1606 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1607 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1608 (match_operand:SI 2 "arith_reg_operand" "r"))
1610 (clobber (reg:SI T_REG))]
1613 [(set_attr "type" "arith")])
1615 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1616 ;; pattern for this case. This helps multimedia applications that compute
1617 ;; the sum of absolute differences.
1618 (define_insn "mov_neg_si_t"
1619 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1622 [(set_attr "type" "arith")])
1624 (define_insn "*subsi3_internal"
1625 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1626 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1627 (match_operand:SI 2 "arith_reg_operand" "r")))]
1630 [(set_attr "type" "arith")])
1632 (define_insn_and_split "*subsi3_media"
1633 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1634 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1635 (match_operand:SI 2 "extend_reg_operand" "r")))]
1637 && (operands[1] != constm1_rtx
1638 || (GET_CODE (operands[2]) != TRUNCATE
1639 && GET_CODE (operands[2]) != SUBREG))"
1641 "operands[1] == constm1_rtx"
1642 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1644 [(set_attr "type" "arith_media")
1645 (set_attr "highpart" "ignore")])
1648 [(set (match_operand:SI 0 "arith_reg_dest" "")
1649 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1650 "general_extend_operand"
1652 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1653 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1654 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1658 [(set (match_operand:SI 0 "arith_reg_dest" "")
1659 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1660 "general_extend_operand"
1662 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1663 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1664 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1666 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1667 ;; will sometimes save one instruction. Otherwise we might get
1668 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1671 (define_expand "subsi3"
1672 [(set (match_operand:SI 0 "arith_reg_operand" "")
1673 (minus:SI (match_operand:SI 1 "arith_operand" "")
1674 (match_operand:SI 2 "arith_reg_operand" "")))]
1678 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1680 emit_insn (gen_negsi2 (operands[0], operands[2]));
1681 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1686 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1688 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1689 operands[1] = force_reg (SImode, operands[1]);
1693 ;; -------------------------------------------------------------------------
1694 ;; Division instructions
1695 ;; -------------------------------------------------------------------------
1697 ;; We take advantage of the library routines which don't clobber as many
1698 ;; registers as a normal function call would.
1700 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1701 ;; also has an effect on the register that holds the address of the sfunc.
1702 ;; To make this work, we have an extra dummy insn that shows the use
1703 ;; of this register for reorg.
1705 (define_insn "use_sfunc_addr"
1706 [(set (reg:SI PR_REG)
1707 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1708 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1710 [(set_attr "length" "0")])
1712 (define_insn "udivsi3_sh2a"
1713 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1714 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1715 (match_operand:SI 2 "arith_reg_operand" "z")))]
1718 [(set_attr "type" "arith")
1719 (set_attr "in_delay_slot" "no")])
1721 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1722 ;; hard register 0. If we used hard register 0, then the next instruction
1723 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1724 ;; gets allocated to a stack slot that needs its address reloaded, then
1725 ;; there is nothing to prevent reload from using r0 to reload the address.
1726 ;; This reload would clobber the value in r0 we are trying to store.
1727 ;; If we let reload allocate r0, then this problem can never happen.
1729 (define_insn "udivsi3_i1"
1730 [(set (match_operand:SI 0 "register_operand" "=z")
1731 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1732 (clobber (reg:SI T_REG))
1733 (clobber (reg:SI PR_REG))
1734 (clobber (reg:SI R4_REG))
1735 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1736 "TARGET_SH1 && ! TARGET_SH4"
1738 [(set_attr "type" "sfunc")
1739 (set_attr "needs_delay_slot" "yes")])
1741 ; Since shmedia-nofpu code could be linked against shcompact code, and
1742 ; the udivsi3 libcall has the same name, we must consider all registers
1743 ; clobbered that are in the union of the registers clobbered by the
1744 ; shmedia and the shcompact implementation. Note, if the shcompact
1745 ; implementation actually used shcompact code, we'd need to clobber
1746 ; also r23 and fr23.
1747 (define_insn "udivsi3_i1_media"
1748 [(set (match_operand:SI 0 "register_operand" "=z")
1749 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1750 (clobber (reg:SI T_MEDIA_REG))
1751 (clobber (reg:SI PR_MEDIA_REG))
1752 (clobber (reg:SI R20_REG))
1753 (clobber (reg:SI R21_REG))
1754 (clobber (reg:SI R22_REG))
1755 (clobber (reg:DI TR0_REG))
1756 (clobber (reg:DI TR1_REG))
1757 (clobber (reg:DI TR2_REG))
1758 (use (match_operand 1 "target_operand" "b"))]
1759 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1761 [(set_attr "type" "sfunc")
1762 (set_attr "needs_delay_slot" "yes")])
1764 (define_expand "udivsi3_i4_media"
1766 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1768 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1769 (set (match_dup 5) (float:DF (match_dup 3)))
1770 (set (match_dup 6) (float:DF (match_dup 4)))
1771 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1772 (set (match_dup 8) (fix:DI (match_dup 7)))
1773 (set (match_operand:SI 0 "register_operand" "")
1774 (truncate:SI (match_dup 8)))]
1775 "TARGET_SHMEDIA_FPU"
1778 operands[3] = gen_reg_rtx (DImode);
1779 operands[4] = gen_reg_rtx (DImode);
1780 operands[5] = gen_reg_rtx (DFmode);
1781 operands[6] = gen_reg_rtx (DFmode);
1782 operands[7] = gen_reg_rtx (DFmode);
1783 operands[8] = gen_reg_rtx (DImode);
1786 (define_insn "udivsi3_i4"
1787 [(set (match_operand:SI 0 "register_operand" "=y")
1788 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1789 (clobber (reg:SI T_REG))
1790 (clobber (reg:SI PR_REG))
1791 (clobber (reg:DF DR0_REG))
1792 (clobber (reg:DF DR2_REG))
1793 (clobber (reg:DF DR4_REG))
1794 (clobber (reg:SI R0_REG))
1795 (clobber (reg:SI R1_REG))
1796 (clobber (reg:SI R4_REG))
1797 (clobber (reg:SI R5_REG))
1798 (use (reg:PSI FPSCR_REG))
1799 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1800 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1802 [(set_attr "type" "sfunc")
1803 (set_attr "fp_mode" "double")
1804 (set_attr "needs_delay_slot" "yes")])
1806 (define_insn "udivsi3_i4_single"
1807 [(set (match_operand:SI 0 "register_operand" "=y")
1808 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1809 (clobber (reg:SI T_REG))
1810 (clobber (reg:SI PR_REG))
1811 (clobber (reg:DF DR0_REG))
1812 (clobber (reg:DF DR2_REG))
1813 (clobber (reg:DF DR4_REG))
1814 (clobber (reg:SI R0_REG))
1815 (clobber (reg:SI R1_REG))
1816 (clobber (reg:SI R4_REG))
1817 (clobber (reg:SI R5_REG))
1818 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1819 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1821 [(set_attr "type" "sfunc")
1822 (set_attr "needs_delay_slot" "yes")])
1824 (define_insn "udivsi3_i4_int"
1825 [(set (match_operand:SI 0 "register_operand" "=z")
1826 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1827 (clobber (reg:SI T_REG))
1828 (clobber (reg:SI R1_REG))
1829 (clobber (reg:SI PR_REG))
1830 (clobber (reg:SI MACH_REG))
1831 (clobber (reg:SI MACL_REG))
1832 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1835 [(set_attr "type" "sfunc")
1836 (set_attr "needs_delay_slot" "yes")])
1839 (define_expand "udivsi3"
1840 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1841 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1842 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1843 (parallel [(set (match_operand:SI 0 "register_operand" "")
1844 (udiv:SI (reg:SI R4_REG)
1846 (clobber (reg:SI T_REG))
1847 (clobber (reg:SI PR_REG))
1848 (clobber (reg:SI R4_REG))
1849 (use (match_dup 3))])]
1855 operands[3] = gen_reg_rtx (Pmode);
1856 /* Emit the move of the address to a pseudo outside of the libcall. */
1857 if (TARGET_DIVIDE_CALL_TABLE)
1859 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1860 that causes problems when the divide code is supposed to come from a
1861 separate library. Division by zero is undefined, so dividing 1 can be
1862 implemented by comparing with the divisor. */
1863 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1865 emit_insn (gen_cmpsi (operands[1], operands[2]));
1866 emit_insn (gen_sgeu (operands[0]));
1869 else if (operands[2] == const0_rtx)
1871 emit_move_insn (operands[0], operands[2]);
1874 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1875 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1877 else if (TARGET_DIVIDE_CALL_FP)
1879 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1880 if (TARGET_FPU_SINGLE)
1881 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1883 last = gen_udivsi3_i4 (operands[0], operands[3]);
1885 else if (TARGET_SHMEDIA_FPU)
1887 operands[1] = force_reg (SImode, operands[1]);
1888 operands[2] = force_reg (SImode, operands[2]);
1889 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1892 else if (TARGET_SH2A)
1894 operands[1] = force_reg (SImode, operands[1]);
1895 operands[2] = force_reg (SImode, operands[2]);
1896 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1899 else if (TARGET_SH5)
1901 function_symbol (operands[3],
1902 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1906 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1907 else if (TARGET_FPU_ANY)
1908 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1910 last = gen_udivsi3_i1 (operands[0], operands[3]);
1914 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1915 last = gen_udivsi3_i1 (operands[0], operands[3]);
1917 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1918 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1919 last = emit_insn (last);
1920 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1921 invariant code motion can move it. */
1922 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1923 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1927 (define_insn "divsi3_sh2a"
1928 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1929 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1930 (match_operand:SI 2 "arith_reg_operand" "z")))]
1933 [(set_attr "type" "arith")
1934 (set_attr "in_delay_slot" "no")])
1936 (define_insn "divsi3_i1"
1937 [(set (match_operand:SI 0 "register_operand" "=z")
1938 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1939 (clobber (reg:SI T_REG))
1940 (clobber (reg:SI PR_REG))
1941 (clobber (reg:SI R1_REG))
1942 (clobber (reg:SI R2_REG))
1943 (clobber (reg:SI R3_REG))
1944 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1945 "TARGET_SH1 && ! TARGET_SH4"
1947 [(set_attr "type" "sfunc")
1948 (set_attr "needs_delay_slot" "yes")])
1950 (define_insn "divsi3_i1_media"
1951 [(set (match_operand:SI 0 "register_operand" "=z")
1952 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1953 (clobber (reg:SI T_MEDIA_REG))
1954 (clobber (reg:SI PR_MEDIA_REG))
1955 (clobber (reg:SI R1_REG))
1956 (clobber (reg:SI R20_REG))
1957 (clobber (reg:SI R21_REG))
1958 (clobber (reg:SI TR0_REG))
1959 (use (match_operand 1 "target_operand" "b"))]
1960 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1962 [(set_attr "type" "sfunc")])
1964 (define_insn "divsi3_media_2"
1965 [(set (match_operand:SI 0 "register_operand" "=z")
1966 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1967 (clobber (reg:SI T_MEDIA_REG))
1968 (clobber (reg:SI PR_MEDIA_REG))
1969 (clobber (reg:SI R1_REG))
1970 (clobber (reg:SI R21_REG))
1971 (clobber (reg:SI TR0_REG))
1972 (use (reg:SI R20_REG))
1973 (use (match_operand 1 "target_operand" "b"))]
1974 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1976 [(set_attr "type" "sfunc")])
1978 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1979 ;; hard reg clobbers and data dependencies that we need when we want
1980 ;; to rematerialize the division into a call.
1981 (define_insn_and_split "divsi_inv_call"
1982 [(set (match_operand:SI 0 "register_operand" "=r")
1983 (div:SI (match_operand:SI 1 "register_operand" "r")
1984 (match_operand:SI 2 "register_operand" "r")))
1985 (clobber (reg:SI R4_REG))
1986 (clobber (reg:SI R5_REG))
1987 (clobber (reg:SI T_MEDIA_REG))
1988 (clobber (reg:SI PR_MEDIA_REG))
1989 (clobber (reg:SI R1_REG))
1990 (clobber (reg:SI R21_REG))
1991 (clobber (reg:SI TR0_REG))
1992 (clobber (reg:SI R20_REG))
1993 (use (match_operand:SI 3 "register_operand" "r"))]
1996 "&& (high_life_started || reload_completed)"
1997 [(set (match_dup 0) (match_dup 3))]
1999 [(set_attr "highpart" "must_split")])
2001 ;; This is the combiner pattern for -mdiv=inv:call .
2002 (define_insn_and_split "*divsi_inv_call_combine"
2003 [(set (match_operand:SI 0 "register_operand" "=z")
2004 (div:SI (match_operand:SI 1 "register_operand" "r")
2005 (match_operand:SI 2 "register_operand" "r")))
2006 (clobber (reg:SI R4_REG))
2007 (clobber (reg:SI R5_REG))
2008 (clobber (reg:SI T_MEDIA_REG))
2009 (clobber (reg:SI PR_MEDIA_REG))
2010 (clobber (reg:SI R1_REG))
2011 (clobber (reg:SI R21_REG))
2012 (clobber (reg:SI TR0_REG))
2013 (clobber (reg:SI R20_REG))
2014 (use (unspec:SI [(match_dup 1)
2015 (match_operand:SI 3 "" "")
2016 (unspec:SI [(match_operand:SI 4 "" "")
2018 (match_operand:DI 5 "" "")]
2020 (match_operand:DI 6 "" "")
2023 UNSPEC_DIV_INV_M3))]
2026 "&& (high_life_started || reload_completed)"
2030 const char *name = sh_divsi3_libfunc;
2031 enum sh_function_kind kind = SFUNC_GOT;
2034 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2035 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2036 while (TARGET_DIVIDE_INV_CALL2)
2038 rtx x = operands[3];
2040 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2042 x = XVECEXP (x, 0, 0);
2043 name = \"__sdivsi3_2\";
2044 kind = SFUNC_STATIC;
2045 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2048 sym = function_symbol (NULL, name, kind);
2049 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2052 [(set_attr "highpart" "must_split")])
2054 (define_expand "divsi3_i4_media"
2055 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2056 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2057 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2058 (set (match_operand:SI 0 "register_operand" "=r")
2059 (fix:SI (match_dup 5)))]
2060 "TARGET_SHMEDIA_FPU"
2063 operands[3] = gen_reg_rtx (DFmode);
2064 operands[4] = gen_reg_rtx (DFmode);
2065 operands[5] = gen_reg_rtx (DFmode);
2068 (define_insn "divsi3_i4"
2069 [(set (match_operand:SI 0 "register_operand" "=y")
2070 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2071 (clobber (reg:SI PR_REG))
2072 (clobber (reg:DF DR0_REG))
2073 (clobber (reg:DF DR2_REG))
2074 (use (reg:PSI FPSCR_REG))
2075 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2076 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2078 [(set_attr "type" "sfunc")
2079 (set_attr "fp_mode" "double")
2080 (set_attr "needs_delay_slot" "yes")])
2082 (define_insn "divsi3_i4_single"
2083 [(set (match_operand:SI 0 "register_operand" "=y")
2084 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2085 (clobber (reg:SI PR_REG))
2086 (clobber (reg:DF DR0_REG))
2087 (clobber (reg:DF DR2_REG))
2088 (clobber (reg:SI R2_REG))
2089 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2090 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2092 [(set_attr "type" "sfunc")
2093 (set_attr "needs_delay_slot" "yes")])
2095 (define_insn "divsi3_i4_int"
2096 [(set (match_operand:SI 0 "register_operand" "=z")
2097 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2098 (clobber (reg:SI T_REG))
2099 (clobber (reg:SI PR_REG))
2100 (clobber (reg:SI R1_REG))
2101 (clobber (reg:SI MACH_REG))
2102 (clobber (reg:SI MACL_REG))
2103 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2106 [(set_attr "type" "sfunc")
2107 (set_attr "needs_delay_slot" "yes")])
2109 (define_expand "divsi3"
2110 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2111 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2112 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2113 (parallel [(set (match_operand:SI 0 "register_operand" "")
2114 (div:SI (reg:SI R4_REG)
2116 (clobber (reg:SI T_REG))
2117 (clobber (reg:SI PR_REG))
2118 (clobber (reg:SI R1_REG))
2119 (clobber (reg:SI R2_REG))
2120 (clobber (reg:SI R3_REG))
2121 (use (match_dup 3))])]
2127 operands[3] = gen_reg_rtx (Pmode);
2128 /* Emit the move of the address to a pseudo outside of the libcall. */
2129 if (TARGET_DIVIDE_CALL_TABLE)
2131 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2132 last = gen_divsi3_i4_int (operands[0], operands[3]);
2134 else if (TARGET_DIVIDE_CALL_FP)
2136 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2137 if (TARGET_FPU_SINGLE)
2138 last = gen_divsi3_i4_single (operands[0], operands[3]);
2140 last = gen_divsi3_i4 (operands[0], operands[3]);
2142 else if (TARGET_SH2A)
2144 operands[1] = force_reg (SImode, operands[1]);
2145 operands[2] = force_reg (SImode, operands[2]);
2146 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2149 else if (TARGET_DIVIDE_INV)
2151 rtx dividend = operands[1];
2152 rtx divisor = operands[2];
2154 rtx nsb_res = gen_reg_rtx (DImode);
2155 rtx norm64 = gen_reg_rtx (DImode);
2156 rtx tab_ix = gen_reg_rtx (DImode);
2157 rtx norm32 = gen_reg_rtx (SImode);
2158 rtx i92 = force_reg (DImode, GEN_INT (92));
2159 rtx scratch0a = gen_reg_rtx (DImode);
2160 rtx scratch0b = gen_reg_rtx (DImode);
2161 rtx inv0 = gen_reg_rtx (SImode);
2162 rtx scratch1a = gen_reg_rtx (DImode);
2163 rtx scratch1b = gen_reg_rtx (DImode);
2164 rtx shift = gen_reg_rtx (DImode);
2166 rtx inv1 = gen_reg_rtx (SImode);
2167 rtx scratch2a = gen_reg_rtx (DImode);
2168 rtx scratch2b = gen_reg_rtx (SImode);
2169 rtx inv2 = gen_reg_rtx (SImode);
2170 rtx scratch3a = gen_reg_rtx (DImode);
2171 rtx scratch3b = gen_reg_rtx (DImode);
2172 rtx scratch3c = gen_reg_rtx (DImode);
2173 rtx scratch3d = gen_reg_rtx (SImode);
2174 rtx scratch3e = gen_reg_rtx (DImode);
2175 rtx result = gen_reg_rtx (SImode);
2177 if (! arith_reg_or_0_operand (dividend, SImode))
2178 dividend = force_reg (SImode, dividend);
2179 if (! arith_reg_operand (divisor, SImode))
2180 divisor = force_reg (SImode, divisor);
2181 if (flag_pic && Pmode != DImode)
2183 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2184 tab_base = gen_datalabel_ref (tab_base);
2185 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2189 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2190 tab_base = gen_datalabel_ref (tab_base);
2191 tab_base = force_reg (DImode, tab_base);
2193 if (TARGET_DIVIDE_INV20U)
2194 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2196 i2p27 = GEN_INT (0);
2197 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2198 i43 = force_reg (DImode, GEN_INT (43));
2201 emit_insn (gen_nsbdi (nsb_res,
2202 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2203 emit_insn (gen_ashldi3_media (norm64,
2204 gen_rtx_SUBREG (DImode, divisor, 0),
2206 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2207 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2208 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2209 inv0, scratch0a, scratch0b,
2210 scratch1a, scratch1b));
2211 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2212 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2214 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2216 scratch3a, scratch3b, scratch3c,
2217 scratch2a, scratch2b, scratch3d, scratch3e));
2218 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2219 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2220 else if (TARGET_DIVIDE_INV_FP)
2221 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2222 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2223 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2224 gen_reg_rtx (DFmode)));
2226 emit_move_insn (operands[0], result);
2229 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2231 operands[1] = force_reg (SImode, operands[1]);
2232 operands[2] = force_reg (SImode, operands[2]);
2233 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2236 else if (TARGET_SH5)
2238 if (TARGET_DIVIDE_CALL2)
2240 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2241 tab_base = gen_datalabel_ref (tab_base);
2242 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2244 if (TARGET_FPU_ANY && TARGET_SH1)
2245 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2246 else if (TARGET_DIVIDE_CALL2)
2247 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2249 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2252 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2253 (operands[0], operands[3]));
2254 else if (TARGET_FPU_ANY)
2255 last = gen_divsi3_i4_single (operands[0], operands[3]);
2257 last = gen_divsi3_i1 (operands[0], operands[3]);
2261 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2262 last = gen_divsi3_i1 (operands[0], operands[3]);
2264 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2265 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2266 last = emit_insn (last);
2267 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2268 invariant code motion can move it. */
2269 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2270 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2274 ;; operands: scratch, tab_base, tab_ix
2275 ;; These are unspecs because we could generate an indexed addressing mode
2276 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2277 ;; confuse reload. See PR27117.
2279 (define_insn "divsi_inv_qitable"
2280 [(set (match_operand:DI 0 "register_operand" "=r")
2281 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2282 (match_operand:DI 2 "register_operand" "r")]
2283 UNSPEC_DIV_INV_TABLE)))]
2287 [(set_attr "type" "load_media")
2288 (set_attr "highpart" "user")])
2290 ;; operands: scratch, tab_base, tab_ix
2291 (define_insn "divsi_inv_hitable"
2292 [(set (match_operand:DI 0 "register_operand" "=r")
2293 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2294 (match_operand:DI 2 "register_operand" "r")]
2295 UNSPEC_DIV_INV_TABLE)))]
2299 [(set_attr "type" "load_media")
2300 (set_attr "highpart" "user")])
2302 ;; operands: inv0, tab_base, tab_ix, norm32
2303 ;; scratch equiv in sdivsi3_2: r19, r21
2304 (define_expand "divsi_inv_m0"
2305 [(set (match_operand:SI 0 "register_operand" "=r")
2306 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2307 (match_operand:DI 2 "register_operand" "r")
2308 (match_operand:SI 3 "register_operand" "r")]
2310 (clobber (match_operand:DI 4 "register_operand" "=r"))
2311 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2319 ldx.ub r20, r21, r19 // u0.8
2321 muls.l r25, r19, r19 // s2.38
2322 ldx.w r20, r21, r21 // s2.14
2323 shari r19, 24, r19 // truncate to s2.14
2324 sub r21, r19, r19 // some 11 bit inverse in s1.14
2327 rtx inv0 = operands[0];
2328 rtx tab_base = operands[1];
2329 rtx tab_ix = operands[2];
2330 rtx norm32 = operands[3];
2331 rtx scratch0 = operands[4];
2332 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2333 rtx scratch1 = operands[5];
2335 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2336 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2337 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2338 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2339 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2340 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2344 ;; operands: inv1, tab_base, tab_ix, norm32
2345 (define_insn_and_split "divsi_inv_m1"
2346 [(set (match_operand:SI 0 "register_operand" "=r")
2347 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2348 (match_operand:DI 2 "register_operand" "r")
2349 (match_operand:SI 3 "register_operand" "r")]
2351 (clobber (match_operand:SI 4 "register_operand" "=r"))
2352 (clobber (match_operand:DI 5 "register_operand" "=r"))
2353 (clobber (match_operand:DI 6 "register_operand" "=r"))
2354 (clobber (match_operand:DI 7 "register_operand" "=r"))
2355 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2363 muls.l r19, r19, r18 // u0.28
2364 muls.l r25, r18, r18 // s2.58
2365 shlli r19, 45, r0 // multiply by two and convert to s2.58
2367 shari r18, 28, r18 // some 18 bit inverse in s1.30
2370 rtx inv1 = operands[0];
2371 rtx tab_base = operands[1];
2372 rtx tab_ix = operands[2];
2373 rtx norm32 = operands[3];
2374 rtx inv0 = operands[4];
2375 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2376 rtx scratch0a = operands[5];
2377 rtx scratch0b = operands[6];
2378 rtx scratch0 = operands[7];
2379 rtx scratch1 = operands[8];
2380 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2382 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2383 scratch0a, scratch0b));
2384 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2385 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2386 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2387 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2388 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2392 ;; operands: inv2, norm32, inv1, i92
2393 (define_insn_and_split "divsi_inv_m2"
2394 [(set (match_operand:SI 0 "register_operand" "=r")
2395 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2396 (match_operand:SI 2 "register_operand" "r")
2397 (match_operand:DI 3 "register_operand" "r")]
2399 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2407 muls.l r18, r25, r0 // s2.60
2408 shari r0, 16, r0 // s-16.44
2410 muls.l r0, r18, r19 // s-16.74
2411 shari r19, 30, r19 // s-16.44
2413 rtx inv2 = operands[0];
2414 rtx norm32 = operands[1];
2415 rtx inv1 = operands[2];
2416 rtx i92 = operands[3];
2417 rtx scratch0 = operands[4];
2418 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2420 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2421 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2422 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2423 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2424 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2428 (define_insn_and_split "divsi_inv_m3"
2429 [(set (match_operand:SI 0 "register_operand" "=r")
2430 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2431 (match_operand:SI 2 "register_operand" "r")
2432 (match_operand:SI 3 "register_operand" "r")
2433 (match_operand:DI 4 "register_operand" "r")
2434 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2435 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2437 (clobber (match_operand:DI 7 "register_operand" "=r"))
2438 (clobber (match_operand:DI 8 "register_operand" "=r"))
2439 (clobber (match_operand:DI 9 "register_operand" "=r"))
2440 (clobber (match_operand:DI 10 "register_operand" "=r"))
2441 (clobber (match_operand:SI 11 "register_operand" "=r"))
2442 (clobber (match_operand:SI 12 "register_operand" "=r"))
2443 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2451 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2452 r0: scratch0 r19: scratch1 r21: scratch2
2454 muls.l r18, r4, r25 // s32.30
2455 muls.l r19, r4, r19 // s15.30
2457 shari r19, 14, r19 // s18.-14
2463 rtx result = operands[0];
2464 rtx dividend = operands[1];
2465 rtx inv1 = operands[2];
2466 rtx inv2 = operands[3];
2467 rtx shift = operands[4];
2468 rtx scratch0 = operands[7];
2469 rtx scratch1 = operands[8];
2470 rtx scratch2 = operands[9];
2472 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2473 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2474 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2475 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2476 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2477 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2478 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2482 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2483 ;; inv1: tab_base, tab_ix, norm32
2484 ;; inv2: norm32, inv1, i92
2485 (define_insn_and_split "divsi_inv_m1_3"
2486 [(set (match_operand:SI 0 "register_operand" "=r")
2487 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2488 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2489 (match_operand:DI 3 "register_operand" "r")
2490 (match_operand:SI 4 "register_operand" "r")]
2492 (unspec:SI [(match_dup 4)
2493 (unspec:SI [(match_dup 2)
2495 (match_dup 4)] UNSPEC_DIV_INV_M1)
2496 (match_operand:SI 5 "" "")]
2498 (match_operand:DI 6 "register_operand" "r")
2499 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2500 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2502 (clobber (match_operand:DI 9 "register_operand" "=r"))
2503 (clobber (match_operand:DI 10 "register_operand" "=r"))
2504 (clobber (match_operand:DI 11 "register_operand" "=r"))
2505 (clobber (match_operand:DI 12 "register_operand" "=r"))
2506 (clobber (match_operand:SI 13 "register_operand" "=r"))
2507 (clobber (match_operand:SI 14 "register_operand" "=r"))
2508 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2510 && (TARGET_DIVIDE_INV_MINLAT
2511 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2517 rtx result = operands[0];
2518 rtx dividend = operands[1];
2519 rtx tab_base = operands[2];
2520 rtx tab_ix = operands[3];
2521 rtx norm32 = operands[4];
2522 /* rtx i92 = operands[5]; */
2523 rtx shift = operands[6];
2524 rtx i2p27 = operands[7];
2525 rtx i43 = operands[8];
2526 rtx scratch0 = operands[9];
2527 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2528 rtx scratch1 = operands[10];
2529 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2530 rtx scratch2 = operands[11];
2531 rtx scratch3 = operands[12];
2532 rtx scratch4 = operands[13];
2533 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2534 rtx scratch5 = operands[14];
2535 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2536 rtx scratch6 = operands[15];
2538 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2539 scratch0, scratch1));
2540 /* inv0 == scratch4 */
2541 if (! TARGET_DIVIDE_INV20U)
2543 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2545 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2549 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2550 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2552 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2553 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2554 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2555 /* inv1 == scratch4 */
2557 if (TARGET_DIVIDE_INV_MINLAT)
2559 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2560 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2561 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2562 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2563 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2564 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2565 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2566 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2567 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2568 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2569 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2573 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2574 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2575 emit_insn (gen_nsbdi (scratch6,
2576 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2577 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2578 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2579 emit_insn (gen_divsi_inv20 (scratch2,
2580 norm32, scratch4, dividend,
2581 scratch6, scratch3, i43,
2582 /* scratch0 may be shared with i2p27. */
2583 scratch0, scratch1, scratch5,
2584 label, label, i2p27));
2586 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2587 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2591 (define_insn "divsi_inv20"
2592 [(set (match_operand:DI 0 "register_operand" "=&r")
2593 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2594 (match_operand:SI 2 "register_operand" "r")
2595 (match_operand:SI 3 "register_operand" "r")
2596 (match_operand:DI 4 "register_operand" "r")
2597 (match_operand:DI 5 "register_operand" "r")
2598 (match_operand:DI 6 "register_operand" "r")
2599 (match_operand:DI 12 "register_operand" "r")
2600 (match_operand 10 "target_operand" "b")
2601 (match_operand 11 "immediate_operand" "i")]
2603 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2604 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2605 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2607 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2610 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2611 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2612 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2613 %10 label (tr), %11 label (imm)
2615 muls.l inv1, norm32, scratch0 // s2.60
2616 muls.l inv1, dividend, result // s32.30
2617 xor i2p27, result_sign, round_scratch
2618 bge/u dividend_nsb, i43, tr.. (label)
2619 shari scratch0, 16, scratch0 // s-16.44
2620 muls.l sratch0_si, inv1, scratch0 // s-16.74
2621 sub result, round_scratch, result
2622 shari dividend, 14, scratch1 // s19.-14
2623 shari scratch0, 30, scratch0 // s-16.44
2624 muls.l scratch0, scratch1, round_scratch // s15.30
2626 sub result, round_scratch, result */
2628 int likely = TARGET_DIVIDE_INV20L;
2630 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2631 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2632 output_asm_insn (likely
2633 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2634 : \"bge/u\t%4, %6, %10\", operands);
2635 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2636 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2637 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2639 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2640 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2643 (define_insn_and_split "divsi_inv_fp"
2644 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2645 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2646 (match_operand:SI 2 "register_operand" "rf")))
2647 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2648 (clobber (match_operand:SI 4 "register_operand" "=r"))
2649 (clobber (match_operand:SI 5 "register_operand" "=r"))
2650 (clobber (match_operand:DF 6 "register_operand" "=r"))
2651 (clobber (match_operand:DF 7 "register_operand" "=r"))
2652 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2653 "TARGET_SHMEDIA_FPU"
2655 "&& (high_life_started || reload_completed)"
2656 [(set (match_dup 0) (match_dup 3))]
2658 [(set_attr "highpart" "must_split")])
2660 ;; If a matching group of divide-by-inverse instructions is in the same
2661 ;; basic block after gcse & loop optimizations, we want to transform them
2662 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2663 (define_insn_and_split "*divsi_inv_fp_combine"
2664 [(set (match_operand:SI 0 "register_operand" "=f")
2665 (div:SI (match_operand:SI 1 "register_operand" "f")
2666 (match_operand:SI 2 "register_operand" "f")))
2667 (use (unspec:SI [(match_dup 1)
2668 (match_operand:SI 3 "" "")
2669 (unspec:SI [(match_operand:SI 4 "" "")
2671 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2672 (match_operand:DI 6 "" "")
2674 (const_int 0)] UNSPEC_DIV_INV_M3))
2675 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2676 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2677 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2678 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2679 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2680 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2683 [(set (match_dup 9) (float:DF (match_dup 1)))
2684 (set (match_dup 10) (float:DF (match_dup 2)))
2685 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2687 (fix:SI (match_dup 11)))
2688 (set (match_dup 0) (match_dup 8))]
2691 if (! fp_arith_reg_operand (operands[1], SImode))
2693 emit_move_insn (operands[7], operands[1]);
2694 operands[1] = operands[7];
2696 if (! fp_arith_reg_operand (operands[2], SImode))
2698 emit_move_insn (operands[8], operands[2]);
2699 operands[2] = operands[8];
2702 [(set_attr "highpart" "must_split")])
2704 ;; -------------------------------------------------------------------------
2705 ;; Multiplication instructions
2706 ;; -------------------------------------------------------------------------
2708 (define_insn "umulhisi3_i"
2709 [(set (reg:SI MACL_REG)
2710 (mult:SI (zero_extend:SI
2711 (match_operand:HI 0 "arith_reg_operand" "r"))
2713 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2716 [(set_attr "type" "smpy")])
2718 (define_insn "mulhisi3_i"
2719 [(set (reg:SI MACL_REG)
2720 (mult:SI (sign_extend:SI
2721 (match_operand:HI 0 "arith_reg_operand" "r"))
2723 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2726 [(set_attr "type" "smpy")])
2728 (define_expand "mulhisi3"
2729 [(set (reg:SI MACL_REG)
2730 (mult:SI (sign_extend:SI
2731 (match_operand:HI 1 "arith_reg_operand" ""))
2733 (match_operand:HI 2 "arith_reg_operand" ""))))
2734 (set (match_operand:SI 0 "arith_reg_operand" "")
2741 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2742 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2743 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2744 invariant code motion can move it. */
2745 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2746 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2747 /* expand_binop can't find a suitable code in umul_widen_optab to
2748 make a REG_EQUAL note from, so make one here.
2749 See also smulsi3_highpart.
2750 ??? Alternatively, we could put this at the calling site of expand_binop,
2751 i.e. expand_expr. */
2753 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2758 (define_expand "umulhisi3"
2759 [(set (reg:SI MACL_REG)
2760 (mult:SI (zero_extend:SI
2761 (match_operand:HI 1 "arith_reg_operand" ""))
2763 (match_operand:HI 2 "arith_reg_operand" ""))))
2764 (set (match_operand:SI 0 "arith_reg_operand" "")
2771 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2772 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2773 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2774 invariant code motion can move it. */
2775 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2776 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2777 /* expand_binop can't find a suitable code in umul_widen_optab to
2778 make a REG_EQUAL note from, so make one here.
2779 See also smulsi3_highpart.
2780 ??? Alternatively, we could put this at the calling site of expand_binop,
2781 i.e. expand_expr. */
2783 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2788 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2789 ;; a call to a routine which clobbers known registers.
2792 [(set (match_operand:SI 1 "register_operand" "=z")
2793 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2794 (clobber (reg:SI MACL_REG))
2795 (clobber (reg:SI T_REG))
2796 (clobber (reg:SI PR_REG))
2797 (clobber (reg:SI R3_REG))
2798 (clobber (reg:SI R2_REG))
2799 (clobber (reg:SI R1_REG))
2800 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2803 [(set_attr "type" "sfunc")
2804 (set_attr "needs_delay_slot" "yes")])
2806 (define_expand "mulsi3_call"
2807 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2808 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2809 (parallel[(set (match_operand:SI 0 "register_operand" "")
2810 (mult:SI (reg:SI R4_REG)
2812 (clobber (reg:SI MACL_REG))
2813 (clobber (reg:SI T_REG))
2814 (clobber (reg:SI PR_REG))
2815 (clobber (reg:SI R3_REG))
2816 (clobber (reg:SI R2_REG))
2817 (clobber (reg:SI R1_REG))
2818 (use (match_operand:SI 3 "register_operand" ""))])]
2822 (define_insn "mul_r"
2823 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2824 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2825 (match_operand:SI 2 "arith_reg_operand" "z")))]
2828 [(set_attr "type" "dmpy")])
2830 (define_insn "mul_l"
2831 [(set (reg:SI MACL_REG)
2832 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2833 (match_operand:SI 1 "arith_reg_operand" "r")))]
2836 [(set_attr "type" "dmpy")])
2838 (define_expand "mulsi3"
2839 [(set (reg:SI MACL_REG)
2840 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2841 (match_operand:SI 2 "arith_reg_operand" "")))
2842 (set (match_operand:SI 0 "arith_reg_operand" "")
2851 /* The address must be set outside the libcall,
2852 since it goes into a pseudo. */
2853 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854 rtx addr = force_reg (SImode, sym);
2855 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2858 last = emit_insn (insns);
2862 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2864 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2865 /* consec_sets_giv can only recognize the first insn that sets a
2866 giv as the giv insn. So we must tag this also with a REG_EQUAL
2868 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2870 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2871 invariant code motion can move it. */
2872 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2873 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2877 (define_insn "mulsidi3_i"
2878 [(set (reg:SI MACH_REG)
2882 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2883 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2885 (set (reg:SI MACL_REG)
2886 (mult:SI (match_dup 0)
2890 [(set_attr "type" "dmpy")])
2892 (define_expand "mulsidi3"
2893 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2894 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2895 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2896 "TARGET_SH2 || TARGET_SHMEDIA"
2901 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2907 (define_insn "mulsidi3_media"
2908 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2909 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2910 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2913 [(set_attr "type" "dmpy_media")
2914 (set_attr "highpart" "ignore")])
2916 (define_insn "mulsidi3_compact"
2917 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2919 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2920 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2921 (clobber (reg:SI MACH_REG))
2922 (clobber (reg:SI MACL_REG))]
2927 [(set (match_operand:DI 0 "arith_reg_dest" "")
2929 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2930 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2931 (clobber (reg:SI MACH_REG))
2932 (clobber (reg:SI MACL_REG))]
2937 rtx low_dst = gen_lowpart (SImode, operands[0]);
2938 rtx high_dst = gen_highpart (SImode, operands[0]);
2940 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2942 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2943 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2944 /* We need something to tag the possible REG_EQUAL notes on to. */
2945 emit_move_insn (operands[0], operands[0]);
2949 (define_insn "umulsidi3_i"
2950 [(set (reg:SI MACH_REG)
2954 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2955 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2957 (set (reg:SI MACL_REG)
2958 (mult:SI (match_dup 0)
2962 [(set_attr "type" "dmpy")])
2964 (define_expand "umulsidi3"
2965 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2966 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2967 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2968 "TARGET_SH2 || TARGET_SHMEDIA"
2973 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2979 (define_insn "umulsidi3_media"
2980 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2981 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2982 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2985 [(set_attr "type" "dmpy_media")
2986 (set_attr "highpart" "ignore")])
2988 (define_insn "umulsidi3_compact"
2989 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2991 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2992 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2993 (clobber (reg:SI MACH_REG))
2994 (clobber (reg:SI MACL_REG))]
2999 [(set (match_operand:DI 0 "arith_reg_dest" "")
3000 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3001 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3002 (clobber (reg:SI MACH_REG))
3003 (clobber (reg:SI MACL_REG))]
3008 rtx low_dst = gen_lowpart (SImode, operands[0]);
3009 rtx high_dst = gen_highpart (SImode, operands[0]);
3011 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3013 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3014 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3015 /* We need something to tag the possible REG_EQUAL notes on to. */
3016 emit_move_insn (operands[0], operands[0]);
3020 (define_insn "smulsi3_highpart_i"
3021 [(set (reg:SI MACH_REG)
3025 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3026 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3028 (clobber (reg:SI MACL_REG))]
3031 [(set_attr "type" "dmpy")])
3033 (define_expand "smulsi3_highpart"
3035 [(set (reg:SI MACH_REG)
3039 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3040 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3042 (clobber (reg:SI MACL_REG))])
3043 (set (match_operand:SI 0 "arith_reg_operand" "")
3050 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3051 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3052 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3053 invariant code motion can move it. */
3054 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3055 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3056 /* expand_binop can't find a suitable code in mul_highpart_optab to
3057 make a REG_EQUAL note from, so make one here.
3058 See also {,u}mulhisi.
3059 ??? Alternatively, we could put this at the calling site of expand_binop,
3060 i.e. expand_mult_highpart. */
3062 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
3067 (define_insn "umulsi3_highpart_i"
3068 [(set (reg:SI MACH_REG)
3072 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3073 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3075 (clobber (reg:SI MACL_REG))]
3078 [(set_attr "type" "dmpy")])
3080 (define_expand "umulsi3_highpart"
3082 [(set (reg:SI MACH_REG)
3086 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3087 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3089 (clobber (reg:SI MACL_REG))])
3090 (set (match_operand:SI 0 "arith_reg_operand" "")
3097 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3098 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3099 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3100 invariant code motion can move it. */
3101 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3102 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3106 (define_insn_and_split "muldi3"
3107 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3108 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3109 (match_operand:DI 2 "arith_reg_operand" "r")))
3110 (clobber (match_scratch:DI 3 "=&r"))
3111 (clobber (match_scratch:DI 4 "=r"))]
3118 rtx op3_v2si, op2_v2si;
3120 op3_v2si = operands[3];
3121 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3123 op3_v2si = XEXP (op3_v2si, 0);
3124 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3126 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3127 op2_v2si = operands[2];
3128 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3130 op2_v2si = XEXP (op2_v2si, 0);
3131 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3133 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3134 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3135 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3136 emit_insn (gen_umulsidi3_media (operands[4],
3137 sh_gen_truncate (SImode, operands[1], 0),
3138 sh_gen_truncate (SImode, operands[2], 0)));
3139 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3140 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3141 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3142 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3147 ;; -------------------------------------------------------------------------
3148 ;; Logical operations
3149 ;; -------------------------------------------------------------------------
3151 (define_insn "*andsi3_compact"
3152 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3153 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3154 (match_operand:SI 2 "logical_operand" "r,K08")))]
3157 [(set_attr "type" "arith")])
3159 (define_insn "*andsi3_media"
3160 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3161 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3162 (match_operand:SI 2 "logical_operand" "r,I10")))]
3167 [(set_attr "type" "arith_media")])
3169 ;; If the constant is 255, then emit an extu.b instruction instead of an
3170 ;; and, since that will give better code.
3172 (define_expand "andsi3"
3173 [(set (match_operand:SI 0 "arith_reg_operand" "")
3174 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3175 (match_operand:SI 2 "logical_operand" "")))]
3180 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3182 emit_insn (gen_zero_extendqisi2 (operands[0],
3183 gen_lowpart (QImode, operands[1])));
3188 (define_insn_and_split "anddi3"
3189 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3190 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3191 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3198 && ! logical_operand (operands[2], DImode)"
3202 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3203 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3205 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3208 [(set_attr "type" "arith_media")])
3210 (define_insn "andcsi3"
3211 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3212 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3213 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3216 [(set_attr "type" "arith_media")])
3218 (define_insn "andcdi3"
3219 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3220 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3221 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3224 [(set_attr "type" "arith_media")])
3226 (define_expand "iorsi3"
3227 [(set (match_operand:SI 0 "arith_reg_operand" "")
3228 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3229 (match_operand:SI 2 "logical_operand" "")))]
3233 (define_insn "*iorsi3_compact"
3234 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3235 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3236 (match_operand:SI 2 "logical_operand" "r,K08")))]
3239 [(set_attr "type" "arith")])
3241 (define_insn "*iorsi3_media"
3242 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3243 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3244 (match_operand:SI 2 "logical_operand" "r,I10")))]
3249 [(set_attr "type" "arith_media")])
3251 (define_insn "iordi3"
3252 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3253 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3254 (match_operand:DI 2 "logical_operand" "r,I10")))]
3259 [(set_attr "type" "arith_media")])
3261 (define_insn_and_split "*logical_sidi3"
3262 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3263 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3264 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3265 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3268 "&& reload_completed"
3269 [(set (match_dup 0) (match_dup 3))]
3273 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3274 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3275 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3278 (define_insn_and_split "*logical_sidisi3"
3279 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3280 (truncate:SI (sign_extend:DI
3281 (match_operator:SI 3 "logical_operator"
3282 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3283 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3287 [(set (match_dup 0) (match_dup 3))])
3289 (define_insn_and_split "*logical_sidi3_2"
3290 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3291 (sign_extend:DI (truncate:SI (sign_extend:DI
3292 (match_operator:SI 3 "logical_operator"
3293 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3294 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3298 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3300 (define_expand "xorsi3"
3301 [(set (match_operand:SI 0 "arith_reg_operand" "")
3302 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3303 (match_operand:SI 2 "xor_operand" "")))]
3307 (define_insn "*xorsi3_compact"
3308 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3309 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3310 (match_operand:SI 2 "logical_operand" "K08,r")))]
3313 [(set_attr "type" "arith")])
3315 (define_insn "*xorsi3_media"
3316 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3317 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3318 (match_operand:SI 2 "xor_operand" "r,I06")))]
3323 [(set_attr "type" "arith_media")])
3325 (define_insn "xordi3"
3326 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3327 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3328 (match_operand:DI 2 "xor_operand" "r,I06")))]
3333 [(set_attr "type" "arith_media")])
3335 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3336 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3338 [(set (match_operand:DI 0 "arith_reg_dest" "")
3339 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3340 [(match_operand 1 "any_register_operand" "")
3341 (match_operand 2 "any_register_operand" "")])))]
3343 [(set (match_dup 5) (match_dup 4))
3344 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3347 enum machine_mode inmode = GET_MODE (operands[1]);
3350 if (GET_CODE (operands[0]) == SUBREG)
3352 offset = SUBREG_BYTE (operands[0]);
3353 operands[0] = SUBREG_REG (operands[0]);
3355 gcc_assert (GET_CODE (operands[0]) == REG);
3356 if (! TARGET_LITTLE_ENDIAN)
3357 offset += 8 - GET_MODE_SIZE (inmode);
3358 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3361 ;; -------------------------------------------------------------------------
3362 ;; Shifts and rotates
3363 ;; -------------------------------------------------------------------------
3365 (define_expand "rotldi3"
3366 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3367 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3368 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3370 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3372 (define_insn "rotldi3_mextr"
3373 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3374 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3375 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3379 static char templ[16];
3381 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3382 8 - (int) (INTVAL (operands[2]) >> 3));
3385 [(set_attr "type" "arith_media")])
3387 (define_expand "rotrdi3"
3388 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3389 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3390 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3392 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3394 (define_insn "rotrdi3_mextr"
3395 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3396 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3397 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3401 static char templ[16];
3403 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3406 [(set_attr "type" "arith_media")])
3409 [(set (match_operand:DI 0 "arith_reg_dest" "")
3410 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3411 "ua_address_operand" "")))
3412 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3414 (clobber (match_operand:DI 3 "register_operand" ""))]
3416 [(match_dup 4) (match_dup 5)]
3419 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3420 (operands[3], operands[1]));
3421 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3422 GEN_INT (56), GEN_INT (8));
3425 (define_insn "rotlsi3_1"
3426 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3427 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3430 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3433 [(set_attr "type" "arith")])
3435 (define_insn "rotlsi3_31"
3436 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3437 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3439 (clobber (reg:SI T_REG))]
3442 [(set_attr "type" "arith")])
3444 (define_insn "rotlsi3_16"
3445 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3446 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3450 [(set_attr "type" "arith")])
3452 (define_expand "rotlsi3"
3453 [(set (match_operand:SI 0 "arith_reg_dest" "")
3454 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3455 (match_operand:SI 2 "immediate_operand" "")))]
3459 static const char rot_tab[] = {
3460 000, 000, 000, 000, 000, 000, 010, 001,
3461 001, 001, 011, 013, 003, 003, 003, 003,
3462 003, 003, 003, 003, 003, 013, 012, 002,
3463 002, 002, 010, 000, 000, 000, 000, 000,
3468 if (GET_CODE (operands[2]) != CONST_INT)
3470 count = INTVAL (operands[2]);
3471 choice = rot_tab[count];
3472 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3478 emit_move_insn (operands[0], operands[1]);
3479 count -= (count & 16) * 2;
3482 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3489 parts[0] = gen_reg_rtx (SImode);
3490 parts[1] = gen_reg_rtx (SImode);
3491 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3492 emit_move_insn (parts[choice-1], operands[1]);
3493 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3494 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3495 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3496 count = (count & ~16) - 8;
3500 for (; count > 0; count--)
3501 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3502 for (; count < 0; count++)
3503 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3508 (define_insn "*rotlhi3_8"
3509 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3510 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3514 [(set_attr "type" "arith")])
3516 (define_expand "rotlhi3"
3517 [(set (match_operand:HI 0 "arith_reg_operand" "")
3518 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3519 (match_operand:HI 2 "immediate_operand" "")))]
3523 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3530 (define_insn "ashlsi3_sh2a"
3531 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3532 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3533 (match_operand:SI 2 "arith_reg_operand" "r")))]
3536 [(set_attr "type" "arith")
3537 (set_attr "length" "4")])
3539 ;; This pattern is used by init_expmed for computing the costs of shift
3542 (define_insn_and_split "ashlsi3_std"
3543 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3544 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3545 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3546 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3548 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3549 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3557 && GET_CODE (operands[2]) == CONST_INT
3558 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3559 [(set (match_dup 3) (match_dup 2))
3561 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3562 (clobber (match_dup 4))])]
3563 "operands[4] = gen_rtx_SCRATCH (SImode);"
3564 [(set_attr "length" "*,*,*,4")
3565 (set_attr "type" "dyn_shift,arith,arith,arith")])
3567 (define_insn "ashlhi3_k"
3568 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3569 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3570 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3571 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3575 [(set_attr "type" "arith")])
3577 (define_insn "ashlsi3_n"
3578 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3579 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3580 (match_operand:SI 2 "const_int_operand" "n")))
3581 (clobber (reg:SI T_REG))]
3582 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3584 [(set (attr "length")
3585 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3587 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3589 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3591 (const_string "8")))
3592 (set_attr "type" "arith")])
3595 [(set (match_operand:SI 0 "arith_reg_dest" "")
3596 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3597 (match_operand:SI 2 "const_int_operand" "")))
3598 (clobber (reg:SI T_REG))]
3599 "TARGET_SH1 && reload_completed"
3600 [(use (reg:SI R0_REG))]
3603 gen_shifty_op (ASHIFT, operands);
3607 (define_insn "ashlsi3_media"
3608 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3609 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3610 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3615 [(set_attr "type" "arith_media")
3616 (set_attr "highpart" "ignore")])
3618 (define_expand "ashlsi3"
3619 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3620 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3621 (match_operand:SI 2 "nonmemory_operand" "")))
3622 (clobber (reg:SI T_REG))])]
3628 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3631 if (GET_CODE (operands[2]) == CONST_INT
3632 && sh_dynamicalize_shift_p (operands[2]))
3633 operands[2] = force_reg (SImode, operands[2]);
3636 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3639 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3643 (define_insn "*ashlhi3_n"
3644 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3645 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3646 (match_operand:HI 2 "const_int_operand" "n")))
3647 (clobber (reg:SI T_REG))]
3650 [(set (attr "length")
3651 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3653 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3655 (const_string "6")))
3656 (set_attr "type" "arith")])
3658 (define_expand "ashlhi3"
3659 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3660 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3661 (match_operand:SI 2 "nonmemory_operand" "")))
3662 (clobber (reg:SI T_REG))])]
3666 if (GET_CODE (operands[2]) != CONST_INT)
3668 /* It may be possible to call gen_ashlhi3 directly with more generic
3669 operands. Make sure operands[1] is a HImode register here. */
3670 if (!arith_reg_operand (operands[1], HImode))
3671 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3675 [(set (match_operand:HI 0 "arith_reg_dest" "")
3676 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3677 (match_operand:HI 2 "const_int_operand" "")))
3678 (clobber (reg:SI T_REG))]
3679 "TARGET_SH1 && reload_completed"
3680 [(use (reg:SI R0_REG))]
3683 gen_shifty_hi_op (ASHIFT, operands);
3688 ; arithmetic shift right
3691 (define_insn "ashrsi3_sh2a"
3692 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3693 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3694 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3697 [(set_attr "type" "dyn_shift")
3698 (set_attr "length" "4")])
3700 (define_insn "ashrsi3_k"
3701 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3702 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3703 (match_operand:SI 2 "const_int_operand" "M")))
3704 (clobber (reg:SI T_REG))]
3705 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3707 [(set_attr "type" "arith")])
3709 ;; We can't do HImode right shifts correctly unless we start out with an
3710 ;; explicit zero / sign extension; doing that would result in worse overall
3711 ;; code, so just let the machine independent code widen the mode.
3712 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3715 ;; ??? This should be a define expand.
3717 (define_insn "ashrsi2_16"
3718 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3719 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3723 [(set_attr "length" "4")])
3726 [(set (match_operand:SI 0 "arith_reg_dest" "")
3727 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3730 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3731 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3732 "operands[2] = gen_lowpart (HImode, operands[0]);")
3734 ;; ??? This should be a define expand.
3736 (define_insn "ashrsi2_31"
3737 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3738 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3740 (clobber (reg:SI T_REG))]
3743 [(set_attr "length" "4")])
3746 [(set (match_operand:SI 0 "arith_reg_dest" "")
3747 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3749 (clobber (reg:SI T_REG))]
3754 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3755 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3760 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3762 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3764 && peep2_reg_dead_p (2, operands[0])
3765 && peep2_reg_dead_p (2, operands[1])"
3769 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3773 (define_insn "ashlsi_c"
3774 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3777 (lt:SI (match_dup 1) (const_int 0)))]
3780 [(set_attr "type" "arith")])
3782 (define_insn "*ashlsi_c_void"
3783 [(set (reg:SI T_REG)
3784 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3785 (clobber (match_scratch:SI 1 "=0"))]
3786 "TARGET_SH1 && cse_not_expected"
3788 [(set_attr "type" "arith")])
3790 (define_insn "ashrsi3_d"
3791 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3792 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3793 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3796 [(set_attr "type" "dyn_shift")])
3798 (define_insn "ashrsi3_n"
3799 [(set (reg:SI R4_REG)
3800 (ashiftrt:SI (reg:SI R4_REG)
3801 (match_operand:SI 0 "const_int_operand" "i")))
3802 (clobber (reg:SI T_REG))
3803 (clobber (reg:SI PR_REG))
3804 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3807 [(set_attr "type" "sfunc")
3808 (set_attr "needs_delay_slot" "yes")])
3810 (define_insn "ashrsi3_media"
3811 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3812 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3813 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3818 [(set_attr "type" "arith_media")
3819 (set_attr "highpart" "ignore")])
3821 (define_expand "ashrsi3"
3822 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3823 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3824 (match_operand:SI 2 "nonmemory_operand" "")))
3825 (clobber (reg:SI T_REG))])]
3831 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3834 if (expand_ashiftrt (operands))
3840 ;; logical shift right
3842 (define_insn "lshrsi3_sh2a"
3843 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3844 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3845 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3848 [(set_attr "type" "dyn_shift")
3849 (set_attr "length" "4")])
3851 (define_insn "lshrsi3_d"
3852 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3853 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3854 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3857 [(set_attr "type" "dyn_shift")])
3859 ;; Only the single bit shift clobbers the T bit.
3861 (define_insn "lshrsi3_m"
3862 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3863 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3864 (match_operand:SI 2 "const_int_operand" "M")))
3865 (clobber (reg:SI T_REG))]
3866 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3868 [(set_attr "type" "arith")])
3870 (define_insn "lshrsi3_k"
3871 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3872 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3873 (match_operand:SI 2 "const_int_operand" "P27")))]
3874 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3875 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3877 [(set_attr "type" "arith")])
3879 (define_insn "lshrsi3_n"
3880 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3881 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3882 (match_operand:SI 2 "const_int_operand" "n")))
3883 (clobber (reg:SI T_REG))]
3884 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3886 [(set (attr "length")
3887 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3889 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3891 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3893 (const_string "8")))
3894 (set_attr "type" "arith")])
3897 [(set (match_operand:SI 0 "arith_reg_dest" "")
3898 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3899 (match_operand:SI 2 "const_int_operand" "")))
3900 (clobber (reg:SI T_REG))]
3901 "TARGET_SH1 && reload_completed"
3902 [(use (reg:SI R0_REG))]
3905 gen_shifty_op (LSHIFTRT, operands);
3909 (define_insn "lshrsi3_media"
3910 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3911 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3912 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3917 [(set_attr "type" "arith_media")
3918 (set_attr "highpart" "ignore")])
3920 (define_expand "lshrsi3"
3921 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3922 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3923 (match_operand:SI 2 "nonmemory_operand" "")))
3924 (clobber (reg:SI T_REG))])]
3930 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3933 if (GET_CODE (operands[2]) == CONST_INT
3934 && sh_dynamicalize_shift_p (operands[2]))
3935 operands[2] = force_reg (SImode, operands[2]);
3936 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3938 rtx count = copy_to_mode_reg (SImode, operands[2]);
3939 emit_insn (gen_negsi2 (count, count));
3940 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3943 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3947 ;; ??? This should be a define expand.
3949 (define_insn "ashldi3_k"
3950 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3951 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3953 (clobber (reg:SI T_REG))]
3955 "shll %R0\;rotcl %S0"
3956 [(set_attr "length" "4")
3957 (set_attr "type" "arith")])
3959 (define_insn "ashldi3_media"
3960 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3961 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3962 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3967 [(set_attr "type" "arith_media")])
3969 (define_insn "*ashldisi3_media"
3970 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3971 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3972 (match_operand:DI 2 "const_int_operand" "n")))]
3973 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3974 "shlli.l %1, %2, %0"
3975 [(set_attr "type" "arith_media")
3976 (set_attr "highpart" "ignore")])
3978 (define_expand "ashldi3"
3979 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3980 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3981 (match_operand:DI 2 "immediate_operand" "")))
3982 (clobber (reg:SI T_REG))])]
3988 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3991 if (GET_CODE (operands[2]) != CONST_INT
3992 || INTVAL (operands[2]) != 1)
3996 ;; ??? This should be a define expand.
3998 (define_insn "lshrdi3_k"
3999 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4000 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4002 (clobber (reg:SI T_REG))]
4004 "shlr %S0\;rotcr %R0"
4005 [(set_attr "length" "4")
4006 (set_attr "type" "arith")])
4008 (define_insn "lshrdi3_media"
4009 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4010 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4011 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4013 && (arith_reg_dest (operands[0], DImode)
4014 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4018 [(set_attr "type" "arith_media")])
4020 (define_insn "*lshrdisi3_media"
4021 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4022 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4023 (match_operand:DI 2 "const_int_operand" "n")))]
4024 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4025 "shlri.l %1, %2, %0"
4026 [(set_attr "type" "arith_media")
4027 (set_attr "highpart" "ignore")])
4029 (define_expand "lshrdi3"
4030 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4031 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4032 (match_operand:DI 2 "immediate_operand" "")))
4033 (clobber (reg:SI T_REG))])]
4039 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4042 if (GET_CODE (operands[2]) != CONST_INT
4043 || INTVAL (operands[2]) != 1)
4047 ;; ??? This should be a define expand.
4049 (define_insn "ashrdi3_k"
4050 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4051 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4053 (clobber (reg:SI T_REG))]
4055 "shar %S0\;rotcr %R0"
4056 [(set_attr "length" "4")
4057 (set_attr "type" "arith")])
4059 (define_insn "ashrdi3_media"
4060 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4061 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4062 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4064 && (arith_reg_dest (operands[0], DImode)
4065 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4069 [(set_attr "type" "arith_media")])
4071 (define_insn "*ashrdisi3_media"
4072 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4073 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4074 (match_operand:DI 2 "const_int_operand" "n")))]
4075 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4076 "shari.l %1, %2, %0"
4077 [(set_attr "type" "arith_media")
4078 (set_attr "highpart" "ignore")])
4080 (define_insn "ashrdisi3_media_high"
4081 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4083 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4084 (match_operand:DI 2 "const_int_operand" "n"))))]
4085 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4087 [(set_attr "type" "arith_media")])
4089 (define_insn "ashrdisi3_media_opaque"
4090 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4091 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4092 (match_operand:DI 2 "const_int_operand" "n")]
4096 [(set_attr "type" "arith_media")])
4098 (define_expand "ashrdi3"
4099 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4100 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4101 (match_operand:DI 2 "immediate_operand" "")))
4102 (clobber (reg:SI T_REG))])]
4108 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4111 if (GET_CODE (operands[2]) != CONST_INT
4112 || INTVAL (operands[2]) != 1)
4116 ;; combined left/right shift
4119 [(set (match_operand:SI 0 "register_operand" "")
4120 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4121 (match_operand:SI 2 "const_int_operand" ""))
4122 (match_operand:SI 3 "const_int_operand" "")))]
4123 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4124 [(use (reg:SI R0_REG))]
4125 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4129 [(set (match_operand:SI 0 "register_operand" "")
4130 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4131 (match_operand:SI 2 "const_int_operand" ""))
4132 (match_operand:SI 3 "const_int_operand" "")))
4133 (clobber (reg:SI T_REG))]
4134 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4135 [(use (reg:SI R0_REG))]
4136 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4140 [(set (match_operand:SI 0 "register_operand" "=r")
4141 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4142 (match_operand:SI 2 "const_int_operand" "n"))
4143 (match_operand:SI 3 "const_int_operand" "n")))
4144 (clobber (reg:SI T_REG))]
4145 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4147 [(set (attr "length")
4148 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4150 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4152 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4154 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4156 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4158 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4160 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4161 (const_string "16")]
4162 (const_string "18")))
4163 (set_attr "type" "arith")])
4166 [(set (match_operand:SI 0 "register_operand" "=z")
4167 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4168 (match_operand:SI 2 "const_int_operand" "n"))
4169 (match_operand:SI 3 "const_int_operand" "n")))
4170 (clobber (reg:SI T_REG))]
4171 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4173 [(set (attr "length")
4174 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4176 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4178 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4180 (const_string "10")))
4181 (set_attr "type" "arith")])
4183 ;; shift left / and combination with a scratch register: The combine pass
4184 ;; does not accept the individual instructions, even though they are
4185 ;; cheap. But it needs a precise description so that it is usable after
4187 (define_insn "and_shl_scratch"
4188 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4192 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4193 (match_operand:SI 2 "const_int_operand" "N,n"))
4194 (match_operand:SI 3 "" "0,r"))
4195 (match_operand:SI 4 "const_int_operand" "n,n"))
4196 (match_operand:SI 5 "const_int_operand" "n,n")))
4197 (clobber (reg:SI T_REG))]
4200 [(set (attr "length")
4201 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4203 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4205 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4207 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4208 (const_string "10")]
4209 (const_string "12")))
4210 (set_attr "type" "arith")])
4213 [(set (match_operand:SI 0 "register_operand" "")
4217 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4218 (match_operand:SI 2 "const_int_operand" ""))
4219 (match_operand:SI 3 "register_operand" ""))
4220 (match_operand:SI 4 "const_int_operand" ""))
4221 (match_operand:SI 5 "const_int_operand" "")))
4222 (clobber (reg:SI T_REG))]
4224 [(use (reg:SI R0_REG))]
4227 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4229 if (INTVAL (operands[2]))
4231 gen_shifty_op (LSHIFTRT, operands);
4233 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4234 operands[2] = operands[4];
4235 gen_shifty_op (ASHIFT, operands);
4236 if (INTVAL (operands[5]))
4238 operands[2] = operands[5];
4239 gen_shifty_op (LSHIFTRT, operands);
4244 ;; signed left/right shift combination.
4246 [(set (match_operand:SI 0 "register_operand" "")
4248 (ashift:SI (match_operand:SI 1 "register_operand" "")
4249 (match_operand:SI 2 "const_int_operand" ""))
4250 (match_operand:SI 3 "const_int_operand" "")
4252 (clobber (reg:SI T_REG))]
4254 [(use (reg:SI R0_REG))]
4255 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4258 (define_insn "shl_sext_ext"
4259 [(set (match_operand:SI 0 "register_operand" "=r")
4261 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4262 (match_operand:SI 2 "const_int_operand" "n"))
4263 (match_operand:SI 3 "const_int_operand" "n")
4265 (clobber (reg:SI T_REG))]
4266 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4268 [(set (attr "length")
4269 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4271 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4273 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4275 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4277 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4279 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4281 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4283 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4284 (const_string "16")]
4285 (const_string "18")))
4286 (set_attr "type" "arith")])
4288 (define_insn "shl_sext_sub"
4289 [(set (match_operand:SI 0 "register_operand" "=z")
4291 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4292 (match_operand:SI 2 "const_int_operand" "n"))
4293 (match_operand:SI 3 "const_int_operand" "n")
4295 (clobber (reg:SI T_REG))]
4296 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4298 [(set (attr "length")
4299 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4301 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4303 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4305 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4306 (const_string "12")]
4307 (const_string "14")))
4308 (set_attr "type" "arith")])
4310 ;; These patterns are found in expansions of DImode shifts by 16, and
4311 ;; allow the xtrct instruction to be generated from C source.
4313 (define_insn "xtrct_left"
4314 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4315 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4317 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4321 [(set_attr "type" "arith")])
4323 (define_insn "xtrct_right"
4324 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4325 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4327 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4331 [(set_attr "type" "arith")])
4333 ;; -------------------------------------------------------------------------
4335 ;; -------------------------------------------------------------------------
4338 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4339 (neg:SI (plus:SI (reg:SI T_REG)
4340 (match_operand:SI 1 "arith_reg_operand" "r"))))
4342 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4346 [(set_attr "type" "arith")])
4348 (define_insn "*negdi_media"
4349 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4350 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4353 [(set_attr "type" "arith_media")])
4355 (define_expand "negdi2"
4356 [(set (match_operand:DI 0 "arith_reg_operand" "")
4357 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4363 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4364 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4366 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4367 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4369 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4370 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4372 emit_insn (gen_clrt ());
4373 emit_insn (gen_negc (low_dst, low_src));
4374 emit_insn (gen_negc (high_dst, high_src));
4379 (define_insn "negsi2"
4380 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4381 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4384 [(set_attr "type" "arith")])
4386 (define_insn "one_cmplsi2"
4387 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4388 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4391 [(set_attr "type" "arith")])
4393 (define_expand "one_cmpldi2"
4394 [(set (match_operand:DI 0 "arith_reg_dest" "")
4395 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4397 "TARGET_SHMEDIA" "")
4399 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4400 This can be used as some kind of conditional execution, which is useful
4403 [(set (match_operand:SI 0 "arith_reg_dest" "")
4404 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4405 (match_operand:SI 1 "arith_reg_operand" ""))
4409 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4410 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4414 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4415 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4416 (match_operand:SI 1 "arith_reg_operand" "0")
4417 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4419 "bf 0f\;neg %2,%0\\n0:"
4420 [(set_attr "type" "arith") ;; poor approximation
4421 (set_attr "length" "4")])
4424 ;; -------------------------------------------------------------------------
4425 ;; Zero extension instructions
4426 ;; -------------------------------------------------------------------------
4428 (define_insn "zero_extendsidi2"
4429 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4430 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4432 "addz.l %1, r63, %0"
4433 [(set_attr "type" "arith_media")
4434 (set_attr "highpart" "extend")])
4436 (define_insn "zero_extendhidi2"
4437 [(set (match_operand:DI 0 "register_operand" "=r,r")
4438 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4443 [(set_attr "type" "*,load_media")
4444 (set (attr "highpart")
4445 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4446 (const_string "user")]
4447 (const_string "ignore")))])
4450 [(set (match_operand:DI 0 "register_operand" "")
4451 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4452 "TARGET_SHMEDIA && reload_completed"
4453 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4454 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4457 if (GET_CODE (operands[1]) == TRUNCATE)
4458 operands[1] = XEXP (operands[1], 0);
4461 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4462 ;; reload the entire truncate expression.
4463 (define_insn_and_split "*loaddi_trunc"
4464 [(set (match_operand 0 "any_register_operand" "=r")
4465 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4466 "TARGET_SHMEDIA && reload_completed"
4468 "TARGET_SHMEDIA && reload_completed"
4469 [(set (match_dup 0) (match_dup 1))]
4470 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4472 (define_insn "zero_extendqidi2"
4473 [(set (match_operand:DI 0 "register_operand" "=r,r")
4474 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4479 [(set_attr "type" "arith_media,load_media")
4480 (set (attr "highpart")
4481 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4482 (const_string "user")]
4483 (const_string "ignore")))])
4485 (define_expand "zero_extendhisi2"
4486 [(set (match_operand:SI 0 "arith_reg_operand" "")
4487 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4491 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4492 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4495 (define_insn "*zero_extendhisi2_compact"
4496 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4497 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4500 [(set_attr "type" "arith")])
4502 (define_insn "*zero_extendhisi2_media"
4503 [(set (match_operand:SI 0 "register_operand" "=r,r")
4504 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4509 [(set_attr "type" "arith_media,load_media")
4510 (set (attr "highpart")
4511 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4512 (const_string "user")]
4513 (const_string "ignore")))])
4516 [(set (match_operand:SI 0 "register_operand" "")
4517 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4518 "TARGET_SHMEDIA && reload_completed"
4519 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4520 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4523 rtx op1 = operands[1];
4525 if (GET_CODE (op1) == TRUNCATE)
4526 op1 = XEXP (op1, 0);
4528 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4529 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4532 (define_expand "zero_extendqisi2"
4533 [(set (match_operand:SI 0 "arith_reg_operand" "")
4534 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4538 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4539 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4542 (define_insn "*zero_extendqisi2_compact"
4543 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4544 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4547 [(set_attr "type" "arith")])
4549 (define_insn "*zero_extendqisi2_media"
4550 [(set (match_operand:SI 0 "register_operand" "=r,r")
4551 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4556 [(set_attr "type" "arith_media,load_media")
4557 (set (attr "highpart")
4558 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4559 (const_string "user")]
4560 (const_string "ignore")))])
4562 (define_insn "zero_extendqihi2"
4563 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4564 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4567 [(set_attr "type" "arith")])
4569 ;; -------------------------------------------------------------------------
4570 ;; Sign extension instructions
4571 ;; -------------------------------------------------------------------------
4573 ;; ??? This should be a define expand.
4574 ;; ??? Or perhaps it should be dropped?
4576 ;; convert_move generates good code for SH[1-4].
4577 (define_insn "extendsidi2"
4578 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4579 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4585 [(set_attr "type" "arith_media,load_media,fpconv_media")
4586 (set (attr "highpart")
4587 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4588 (const_string "user")]
4589 (const_string "extend")))])
4591 (define_insn "extendhidi2"
4592 [(set (match_operand:DI 0 "register_operand" "=r,r")
4593 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4598 [(set_attr "type" "*,load_media")
4599 (set (attr "highpart")
4600 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4601 (const_string "user")]
4602 (const_string "ignore")))])
4605 [(set (match_operand:DI 0 "register_operand" "")
4606 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4607 "TARGET_SHMEDIA && reload_completed"
4608 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4609 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4612 if (GET_CODE (operands[1]) == TRUNCATE)
4613 operands[1] = XEXP (operands[1], 0);
4616 (define_insn "extendqidi2"
4617 [(set (match_operand:DI 0 "register_operand" "=r,r")
4618 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4623 [(set_attr "type" "*,load_media")
4624 (set (attr "highpart")
4625 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4626 (const_string "user")]
4627 (const_string "ignore")))])
4630 [(set (match_operand:DI 0 "register_operand" "")
4631 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4632 "TARGET_SHMEDIA && reload_completed"
4633 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4634 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4637 if (GET_CODE (operands[1]) == TRUNCATE)
4638 operands[1] = XEXP (operands[1], 0);
4641 (define_expand "extendhisi2"
4642 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4643 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4647 (define_insn "*extendhisi2_compact"
4648 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4649 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4654 [(set_attr "type" "arith,load")])
4656 (define_insn "*extendhisi2_media"
4657 [(set (match_operand:SI 0 "register_operand" "=r,r")
4658 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4663 [(set_attr "type" "arith_media,load_media")
4664 (set (attr "highpart")
4665 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4666 (const_string "user")]
4667 (const_string "ignore")))])
4670 [(set (match_operand:SI 0 "register_operand" "")
4671 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4672 "TARGET_SHMEDIA && reload_completed"
4673 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4674 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4677 rtx op1 = operands[1];
4678 if (GET_CODE (op1) == TRUNCATE)
4679 op1 = XEXP (op1, 0);
4681 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4682 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4685 (define_expand "extendqisi2"
4686 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4687 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4691 (define_insn "*extendqisi2_compact"
4692 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4693 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4698 [(set_attr "type" "arith,load")])
4700 (define_insn "*extendqisi2_media"
4701 [(set (match_operand:SI 0 "register_operand" "=r,r")
4702 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4707 [(set_attr "type" "arith_media,load_media")
4708 (set (attr "highpart")
4709 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4710 (const_string "user")]
4711 (const_string "ignore")))])
4714 [(set (match_operand:SI 0 "register_operand" "")
4715 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4716 "TARGET_SHMEDIA && reload_completed"
4717 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4718 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4721 rtx op1 = operands[1];
4722 if (GET_CODE (op1) == TRUNCATE)
4723 op1 = XEXP (op1, 0);
4725 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4726 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4729 (define_insn "extendqihi2"
4730 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4731 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4736 [(set_attr "type" "arith,load")])
4738 /* It would seem useful to combine the truncXi patterns into the movXi
4739 patterns, but unary operators are ignored when matching constraints,
4740 so we need separate patterns. */
4741 (define_insn "truncdisi2"
4742 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4743 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4752 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4753 (set (attr "highpart")
4754 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4755 (const_string "user")]
4756 (const_string "extend")))])
4758 (define_insn "truncdihi2"
4759 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4760 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4763 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4765 [(set_attr "type" "arith_media,store_media")
4766 (set_attr "length" "8,4")
4767 (set (attr "highpart")
4768 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4769 (const_string "user")]
4770 (const_string "extend")))])
4772 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4773 ; Because we use zero extension, we can't provide signed QImode compares
4774 ; using a simple compare or conditional banch insn.
4775 (define_insn "truncdiqi2"
4776 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4777 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4782 [(set_attr "type" "arith_media,store")
4783 (set (attr "highpart")
4784 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4785 (const_string "user")]
4786 (const_string "extend")))])
4787 ;; -------------------------------------------------------------------------
4788 ;; Move instructions
4789 ;; -------------------------------------------------------------------------
4791 ;; define push and pop so it is easy for sh.c
4792 ;; We can't use push and pop on SHcompact because the stack must always
4793 ;; be 8-byte aligned.
4795 (define_expand "push"
4796 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4797 (match_operand:SI 0 "register_operand" "r,l,x"))]
4798 "TARGET_SH1 && ! TARGET_SH5"
4801 (define_expand "pop"
4802 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4803 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4804 "TARGET_SH1 && ! TARGET_SH5"
4807 (define_expand "push_e"
4808 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4809 (match_operand:SF 0 "" ""))
4810 (use (reg:PSI FPSCR_REG))
4811 (clobber (scratch:SI))])]
4812 "TARGET_SH1 && ! TARGET_SH5"
4815 (define_insn "push_fpul"
4816 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4817 "TARGET_SH2E && ! TARGET_SH5"
4819 [(set_attr "type" "fstore")
4820 (set_attr "late_fp_use" "yes")
4821 (set_attr "hit_stack" "yes")])
4823 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4825 (define_expand "push_4"
4826 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4827 (match_operand:DF 0 "" ""))
4828 (use (reg:PSI FPSCR_REG))
4829 (clobber (scratch:SI))])]
4830 "TARGET_SH1 && ! TARGET_SH5"
4833 (define_expand "pop_e"
4834 [(parallel [(set (match_operand:SF 0 "" "")
4835 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4836 (use (reg:PSI FPSCR_REG))
4837 (clobber (scratch:SI))])]
4838 "TARGET_SH1 && ! TARGET_SH5"
4841 (define_insn "pop_fpul"
4842 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4843 "TARGET_SH2E && ! TARGET_SH5"
4845 [(set_attr "type" "load")
4846 (set_attr "hit_stack" "yes")])
4848 (define_expand "pop_4"
4849 [(parallel [(set (match_operand:DF 0 "" "")
4850 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4851 (use (reg:PSI FPSCR_REG))
4852 (clobber (scratch:SI))])]
4853 "TARGET_SH1 && ! TARGET_SH5"
4856 (define_expand "push_fpscr"
4861 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4862 gen_rtx_PRE_DEC (Pmode,
4863 stack_pointer_rtx)),
4865 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4869 (define_expand "pop_fpscr"
4874 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4875 gen_frame_mem (PSImode,
4876 gen_rtx_POST_INC (Pmode,
4877 stack_pointer_rtx))));
4878 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4882 ;; These two patterns can happen as the result of optimization, when
4883 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4884 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4887 [(set (reg:SI T_REG) (const_int 0))]
4892 [(set (reg:SI T_REG) (const_int 1))]
4896 ;; t/r must come after r/r, lest reload will try to reload stuff like
4897 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4898 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4899 (define_insn "movsi_i"
4900 [(set (match_operand:SI 0 "general_movdst_operand"
4901 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4902 (match_operand:SI 1 "general_movsrc_operand"
4903 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4907 && (register_operand (operands[0], SImode)
4908 || register_operand (operands[1], SImode))"
4926 [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,mac_mem,store,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4927 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4929 ;; t/r must come after r/r, lest reload will try to reload stuff like
4930 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4931 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4932 ;; will require a reload.
4933 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4934 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4935 (define_insn "movsi_ie"
4936 [(set (match_operand:SI 0 "general_movdst_operand"
4937 "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4938 (match_operand:SI 1 "general_movsrc_operand"
4939 "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4940 "(TARGET_SH2E || TARGET_SH2A)
4941 && (register_operand (operands[0], SImode)
4942 || register_operand (operands[1], SImode))"
4968 ! move optimized away"
4969 [(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")
4970 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4971 (set_attr "length" "*,*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4973 (define_insn "movsi_i_lowpart"
4974 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4975 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4977 && (register_operand (operands[0], SImode)
4978 || register_operand (operands[1], SImode))"
4989 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4991 (define_insn_and_split "load_ra"
4992 [(set (match_operand:SI 0 "general_movdst_operand" "")
4993 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4996 "&& ! currently_expanding_to_rtl"
4997 [(set (match_dup 0) (match_dup 1))]
5000 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
5001 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5004 ;; The '?'s in the following constraints may not reflect the time taken
5005 ;; to perform the move. They are there to discourage the use of floating-
5006 ;; point registers for storing integer values.
5007 (define_insn "*movsi_media"
5008 [(set (match_operand:SI 0 "general_movdst_operand"
5009 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5010 (match_operand:SI 1 "general_movsrc_operand"
5011 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5013 && (register_operand (operands[0], SImode)
5014 || sh_register_operand (operands[1], SImode)
5015 || GET_CODE (operands[1]) == TRUNCATE)"
5030 [(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")
5031 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5032 (set (attr "highpart")
5033 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5034 (const_string "user")]
5035 (const_string "ignore")))])
5037 (define_insn "*movsi_media_nofpu"
5038 [(set (match_operand:SI 0 "general_movdst_operand"
5039 "=r,r,r,r,m,*b,r,*b")
5040 (match_operand:SI 1 "general_movsrc_operand"
5041 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5043 && (register_operand (operands[0], SImode)
5044 || sh_register_operand (operands[1], SImode)
5045 || GET_CODE (operands[1]) == TRUNCATE)"
5055 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5056 (set_attr "length" "4,4,8,4,4,4,4,12")
5057 (set (attr "highpart")
5058 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5059 (const_string "user")]
5060 (const_string "ignore")))])
5062 (define_expand "movsi_const"
5063 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5064 (const:SI (sign_extend:SI
5067 (match_operand:DI 1 "immediate_operand" "s")
5070 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5073 (truncate:HI (match_dup 1))))))]
5074 "TARGET_SHMEDIA && reload_completed
5075 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5078 if (GET_CODE (operands[1]) == LABEL_REF
5079 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5080 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5081 else if (GOTOFF_P (operands[1]))
5083 rtx unspec = XEXP (operands[1], 0);
5085 if (! UNSPEC_GOTOFF_P (unspec))
5087 unspec = XEXP (unspec, 0);
5088 if (! UNSPEC_GOTOFF_P (unspec))
5091 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5092 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5093 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5097 (define_expand "movsi_const_16bit"
5098 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5099 (const:SI (sign_extend:SI
5101 (match_operand:DI 1 "immediate_operand" "s")))))]
5102 "TARGET_SHMEDIA && flag_pic && reload_completed
5103 && GET_CODE (operands[1]) == SYMBOL_REF"
5107 [(set (match_operand:SI 0 "arith_reg_dest" "")
5108 (match_operand:SI 1 "immediate_operand" ""))]
5109 "TARGET_SHMEDIA && reload_completed
5110 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5114 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5116 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (operands[1]),
5123 [(set (match_operand:SI 0 "register_operand" "")
5124 (match_operand:SI 1 "immediate_operand" ""))]
5125 "TARGET_SHMEDIA && reload_completed
5126 && ((GET_CODE (operands[1]) == CONST_INT
5127 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5128 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5129 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5131 (define_expand "movsi"
5132 [(set (match_operand:SI 0 "general_movdst_operand" "")
5133 (match_operand:SI 1 "general_movsrc_operand" ""))]
5135 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5137 (define_expand "ic_invalidate_line"
5138 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5139 (match_dup 1)] UNSPEC_ICACHE)
5140 (clobber (scratch:SI))])]
5141 "TARGET_HARD_SH4 || TARGET_SH5"
5146 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5149 else if (TARGET_SHCOMPACT)
5151 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5152 operands[1] = force_reg (Pmode, operands[1]);
5153 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5156 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5158 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5161 operands[0] = force_reg (Pmode, operands[0]);
5162 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5166 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5167 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5168 ;; the requirement *1*00 for associative address writes. The alignment of
5169 ;; %0 implies that its least significant bit is cleared,
5170 ;; thus we clear the V bit of a matching entry if there is one.
5171 (define_insn "ic_invalidate_line_i"
5172 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5173 (match_operand:SI 1 "register_operand" "r")]
5175 (clobber (match_scratch:SI 2 "=&r"))]
5177 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5178 [(set_attr "length" "8")
5179 (set_attr "type" "cwb")])
5181 (define_insn "ic_invalidate_line_sh4a"
5182 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5184 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5185 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5186 [(set_attr "length" "16")
5187 (set_attr "type" "cwb")])
5189 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5190 ;; an add in the code that calculates the address.
5191 (define_insn "ic_invalidate_line_media"
5192 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5195 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5196 [(set_attr "length" "16")
5197 (set_attr "type" "invalidate_line_media")])
5199 (define_insn "ic_invalidate_line_compact"
5200 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5201 (match_operand:SI 1 "register_operand" "r")]
5203 (clobber (reg:SI PR_REG))]
5206 [(set_attr "type" "sfunc")
5207 (set_attr "needs_delay_slot" "yes")])
5209 (define_expand "initialize_trampoline"
5210 [(match_operand:SI 0 "" "")
5211 (match_operand:SI 1 "" "")
5212 (match_operand:SI 2 "" "")]
5218 tramp = force_reg (Pmode, operands[0]);
5219 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5221 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5222 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5224 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5228 (define_insn "initialize_trampoline_compact"
5229 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5230 (match_operand:SI 1 "register_operand" "r")
5231 (reg:SI R2_REG) (reg:SI R3_REG)]
5234 (clobber (reg:SI PR_REG))]
5237 [(set_attr "type" "sfunc")
5238 (set_attr "needs_delay_slot" "yes")])
5240 (define_insn "movqi_i"
5241 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5242 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5244 && (arith_reg_operand (operands[0], QImode)
5245 || arith_reg_operand (operands[1], QImode))"
5254 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5256 (define_insn "*movqi_media"
5257 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5258 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5260 && (arith_reg_operand (operands[0], QImode)
5261 || extend_reg_or_0_operand (operands[1], QImode))"
5267 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5268 (set (attr "highpart")
5269 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5270 (const_string "user")]
5271 (const_string "ignore")))])
5273 (define_expand "movqi"
5274 [(set (match_operand:QI 0 "general_operand" "")
5275 (match_operand:QI 1 "general_operand" ""))]
5277 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5279 (define_expand "reload_inqi"
5280 [(set (match_operand:SI 2 "" "=&r")
5281 (match_operand:QI 1 "inqhi_operand" ""))
5282 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5283 (truncate:QI (match_dup 3)))]
5287 rtx inner = XEXP (operands[1], 0);
5288 int regno = REGNO (inner);
5290 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5291 operands[1] = gen_rtx_REG (SImode, regno);
5292 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5295 /* When storing r0, we have to avoid reg+reg addressing. */
5296 (define_insn "movhi_i"
5297 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5298 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5300 && (arith_reg_operand (operands[0], HImode)
5301 || arith_reg_operand (operands[1], HImode))
5302 && (GET_CODE (operands[0]) != MEM
5303 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5304 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5305 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5315 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5317 (define_insn "*movhi_media"
5318 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5319 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5321 && (arith_reg_operand (operands[0], HImode)
5322 || arith_reg_or_0_operand (operands[1], HImode))"
5329 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5330 (set (attr "highpart")
5331 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5332 (const_string "user")]
5333 (const_string "ignore")))])
5336 [(set (match_operand:HI 0 "register_operand" "")
5337 (match_operand:HI 1 "immediate_operand" ""))]
5338 "TARGET_SHMEDIA && reload_completed
5339 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5340 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5342 (define_expand "movhi"
5343 [(set (match_operand:HI 0 "general_movdst_operand" "")
5344 (match_operand:HI 1 "general_movsrc_operand" ""))]
5346 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5348 (define_expand "reload_inhi"
5349 [(set (match_operand:SI 2 "" "=&r")
5350 (match_operand:HI 1 "inqhi_operand" ""))
5351 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5352 (truncate:HI (match_dup 3)))]
5356 rtx inner = XEXP (operands[1], 0);
5357 int regno = REGNO (inner);
5359 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5360 operands[1] = gen_rtx_REG (SImode, regno);
5361 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5364 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5365 ;; compiled with -m2 -ml -O3 -funroll-loops
5366 (define_insn "*movdi_i"
5367 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5368 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5370 && (arith_reg_operand (operands[0], DImode)
5371 || arith_reg_operand (operands[1], DImode))"
5372 "* return output_movedouble (insn, operands, DImode);"
5373 [(set_attr "length" "4")
5374 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5376 ;; If the output is a register and the input is memory or a register, we have
5377 ;; to be careful and see which word needs to be loaded first.
5380 [(set (match_operand:DI 0 "general_movdst_operand" "")
5381 (match_operand:DI 1 "general_movsrc_operand" ""))]
5382 "TARGET_SH1 && reload_completed"
5383 [(set (match_dup 2) (match_dup 3))
5384 (set (match_dup 4) (match_dup 5))]
5389 if ((GET_CODE (operands[0]) == MEM
5390 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5391 || (GET_CODE (operands[1]) == MEM
5392 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5395 switch (GET_CODE (operands[0]))
5398 regno = REGNO (operands[0]);
5401 regno = subreg_regno (operands[0]);
5411 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5413 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5414 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5415 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5416 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5420 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5421 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5422 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5423 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5426 if (operands[2] == 0 || operands[3] == 0
5427 || operands[4] == 0 || operands[5] == 0)
5431 ;; The '?'s in the following constraints may not reflect the time taken
5432 ;; to perform the move. They are there to discourage the use of floating-
5433 ;; point registers for storing integer values.
5434 (define_insn "*movdi_media"
5435 [(set (match_operand:DI 0 "general_movdst_operand"
5436 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5437 (match_operand:DI 1 "general_movsrc_operand"
5438 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5440 && (register_operand (operands[0], DImode)
5441 || sh_register_operand (operands[1], DImode))"
5456 [(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")
5457 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5459 (define_insn "*movdi_media_nofpu"
5460 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5461 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5463 && (register_operand (operands[0], DImode)
5464 || sh_register_operand (operands[1], DImode))"
5474 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5475 (set_attr "length" "4,4,16,4,4,4,4,*")])
5477 (define_insn "*movdi_media_I16"
5478 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5479 (match_operand:DI 1 "const_int_operand" "I16"))]
5480 "TARGET_SHMEDIA && reload_completed"
5482 [(set_attr "type" "arith_media")
5483 (set_attr "length" "4")])
5486 [(set (match_operand:DI 0 "arith_reg_dest" "")
5487 (match_operand:DI 1 "immediate_operand" ""))]
5488 "TARGET_SHMEDIA && reload_completed
5489 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5490 [(set (match_dup 0) (match_dup 1))]
5495 if (TARGET_SHMEDIA64)
5496 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5498 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5500 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (operands[1]),
5506 (define_expand "movdi_const"
5507 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5508 (const:DI (sign_extend:DI
5511 (match_operand:DI 1 "immediate_operand" "s")
5514 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5520 (const_int 32)))))))
5522 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5528 (const_int 16)))))))
5530 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5535 "TARGET_SHMEDIA64 && reload_completed
5536 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5539 sh_mark_label (operands[1], 4);
5542 (define_expand "movdi_const_32bit"
5543 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5544 (const:DI (sign_extend:DI
5547 (match_operand:DI 1 "immediate_operand" "s")
5550 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5555 "TARGET_SHMEDIA32 && reload_completed
5556 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5559 sh_mark_label (operands[1], 2);
5562 (define_expand "movdi_const_16bit"
5563 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5564 (const:DI (sign_extend:DI
5566 (match_operand:DI 1 "immediate_operand" "s")))))]
5567 "TARGET_SHMEDIA && flag_pic && reload_completed
5568 && GET_CODE (operands[1]) == SYMBOL_REF"
5572 [(set (match_operand:DI 0 "ext_dest_operand" "")
5573 (match_operand:DI 1 "immediate_operand" ""))]
5574 "TARGET_SHMEDIA && reload_completed
5575 && GET_CODE (operands[1]) == CONST_INT
5576 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5577 [(set (match_dup 0) (match_dup 2))
5581 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5582 unsigned HOST_WIDE_INT low = val;
5583 unsigned HOST_WIDE_INT high = val;
5584 unsigned HOST_WIDE_INT sign;
5585 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5587 /* Zero-extend the 16 least-significant bits. */
5590 /* Arithmetic shift right the word by 16 bits. */
5592 if (GET_CODE (operands[0]) == SUBREG
5593 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5602 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5608 /* If we can't generate the constant with a two-insn movi / shori
5609 sequence, try some other strategies. */
5610 if (! CONST_OK_FOR_I16 (high))
5612 /* Try constant load / left shift. We know VAL != 0. */
5613 val2 = val ^ (val-1);
5616 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5618 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5619 || (! CONST_OK_FOR_I16 (high >> 16)
5620 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5622 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5623 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5624 GEN_INT (trailing_zeroes));
5628 /* Try constant load / right shift. */
5629 val2 = (val >> 15) + 1;
5630 if (val2 == (val2 & -val2))
5632 int shift = 49 - exact_log2 (val2);
5634 val2 = trunc_int_for_mode (val << shift, DImode);
5635 if (CONST_OK_FOR_I16 (val2))
5637 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5643 val2 = val & 0xffff;
5644 if ((val >> 16 & 0xffff) == val2
5645 && (val >> 32 & 0xffff) == val2
5646 && (val >> 48 & 0xffff) == val2)
5648 val2 = (HOST_WIDE_INT) val >> 48;
5649 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5650 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5653 /* Try movi / mshflo.l */
5654 val2 = (HOST_WIDE_INT) val >> 32;
5655 if (val2 == ((unsigned HOST_WIDE_INT)
5656 trunc_int_for_mode (val, SImode)))
5658 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5662 /* Try movi / mshflo.l w/ r63. */
5663 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5664 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5666 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5672 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5675 operands[2] = GEN_INT (val2);
5679 [(set (match_operand:DI 0 "ext_dest_operand" "")
5680 (match_operand:DI 1 "immediate_operand" ""))]
5681 "TARGET_SHMEDIA && reload_completed
5682 && GET_CODE (operands[1]) == CONST_DOUBLE"
5683 [(set (match_dup 0) (match_dup 2))
5685 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5688 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5689 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5690 unsigned HOST_WIDE_INT val = low;
5691 unsigned HOST_WIDE_INT sign;
5693 /* Zero-extend the 16 least-significant bits. */
5695 operands[1] = GEN_INT (val);
5697 /* Arithmetic shift right the double-word by 16 bits. */
5699 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5702 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5706 /* This will only be true if high is a sign-extension of low, i.e.,
5707 it must be either 0 or (unsigned)-1, and be zero iff the
5708 most-significant bit of low is set. */
5709 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5710 operands[2] = GEN_INT (low);
5712 operands[2] = immed_double_const (low, high, DImode);
5715 (define_insn "shori_media"
5716 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5717 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5719 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5720 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5724 [(set_attr "type" "arith_media,*")])
5726 (define_insn "*shori_media_si"
5727 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5728 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5730 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5734 (define_expand "movdi"
5735 [(set (match_operand:DI 0 "general_movdst_operand" "")
5736 (match_operand:DI 1 "general_movsrc_operand" ""))]
5738 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5740 (define_insn "movdf_media"
5741 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5742 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5744 && (register_operand (operands[0], DFmode)
5745 || sh_register_operand (operands[1], DFmode))"
5756 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5758 (define_insn "movdf_media_nofpu"
5759 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5760 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5762 && (register_operand (operands[0], DFmode)
5763 || sh_register_operand (operands[1], DFmode))"
5769 [(set_attr "type" "arith_media,*,load_media,store_media")])
5772 [(set (match_operand:DF 0 "arith_reg_dest" "")
5773 (match_operand:DF 1 "immediate_operand" ""))]
5774 "TARGET_SHMEDIA && reload_completed"
5775 [(set (match_dup 3) (match_dup 2))]
5778 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5780 REAL_VALUE_TYPE value;
5782 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5783 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5785 if (HOST_BITS_PER_WIDE_INT >= 64)
5786 operands[2] = immed_double_const ((unsigned long) values[endian]
5787 | ((HOST_WIDE_INT) values[1 - endian]
5791 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5792 operands[2] = immed_double_const (values[endian], values[1 - endian],
5796 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5799 ;; ??? This should be a define expand.
5801 (define_insn "movdf_k"
5802 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5803 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5805 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5806 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5807 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5808 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5809 && (arith_reg_operand (operands[0], DFmode)
5810 || arith_reg_operand (operands[1], DFmode))"
5811 "* return output_movedouble (insn, operands, DFmode);"
5812 [(set_attr "length" "4")
5813 (set_attr "type" "move,pcload,load,store")])
5815 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5816 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5817 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5818 ;; the d/m/c/X alternative, which is split later into single-precision
5819 ;; instructions. And when not optimizing, no splits are done before fixing
5820 ;; up pcloads, so we need usable length information for that.
5821 (define_insn "movdf_i4"
5822 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5823 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5824 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5825 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5826 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5827 && (arith_reg_operand (operands[0], DFmode)
5828 || arith_reg_operand (operands[1], DFmode))"
5840 [(set_attr_alternative "length"
5841 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5843 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5844 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5845 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5847 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5848 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5849 ;; increment or decrement r15 explicitly.
5851 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5852 (const_int 10) (const_int 8))
5854 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5855 (const_int 10) (const_int 8))])
5856 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5857 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5858 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5859 (const_string "double")
5860 (const_string "none")))])
5862 ;; Moving DFmode between fp/general registers through memory
5863 ;; (the top of the stack) is faster than moving through fpul even for
5864 ;; little endian. Because the type of an instruction is important for its
5865 ;; scheduling, it is beneficial to split these operations, rather than
5866 ;; emitting them in one single chunk, even if this will expose a stack
5867 ;; use that will prevent scheduling of other stack accesses beyond this
5870 [(set (match_operand:DF 0 "register_operand" "")
5871 (match_operand:DF 1 "register_operand" ""))
5872 (use (match_operand:PSI 2 "fpscr_operand" ""))
5873 (clobber (match_scratch:SI 3 "=X"))]
5874 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5875 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5881 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5883 emit_move_insn (stack_pointer_rtx,
5884 plus_constant (stack_pointer_rtx, -8));
5885 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5888 tos = gen_tmp_stack_mem (DFmode,
5889 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5890 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5891 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5892 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5893 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5894 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5896 tos = gen_tmp_stack_mem (DFmode,
5897 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5898 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5899 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5900 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5902 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5906 ;; local-alloc sometimes allocates scratch registers even when not required,
5907 ;; so we must be prepared to handle these.
5909 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5911 [(set (match_operand:DF 0 "general_movdst_operand" "")
5912 (match_operand:DF 1 "general_movsrc_operand" ""))
5913 (use (match_operand:PSI 2 "fpscr_operand" ""))
5914 (clobber (match_scratch:SI 3 ""))]
5915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5917 && true_regnum (operands[0]) < 16
5918 && true_regnum (operands[1]) < 16"
5919 [(set (match_dup 0) (match_dup 1))]
5922 /* If this was a reg <-> mem operation with base + index reg addressing,
5923 we have to handle this in a special way. */
5924 rtx mem = operands[0];
5926 if (! memory_operand (mem, DFmode))
5931 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5932 mem = SUBREG_REG (mem);
5933 if (GET_CODE (mem) == MEM)
5935 rtx addr = XEXP (mem, 0);
5936 if (GET_CODE (addr) == PLUS
5937 && GET_CODE (XEXP (addr, 0)) == REG
5938 && GET_CODE (XEXP (addr, 1)) == REG)
5941 rtx reg0 = gen_rtx_REG (Pmode, 0);
5942 rtx regop = operands[store_p], word0 ,word1;
5944 if (GET_CODE (regop) == SUBREG)
5945 alter_subreg (®op);
5946 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5950 mem = copy_rtx (mem);
5951 PUT_MODE (mem, SImode);
5952 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5953 alter_subreg (&word0);
5954 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5955 alter_subreg (&word1);
5956 if (store_p || ! refers_to_regno_p (REGNO (word0),
5957 REGNO (word0) + 1, addr, 0))
5960 ? gen_movsi_ie (mem, word0)
5961 : gen_movsi_ie (word0, mem));
5962 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5963 mem = copy_rtx (mem);
5965 ? gen_movsi_ie (mem, word1)
5966 : gen_movsi_ie (word1, mem));
5967 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5971 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5972 emit_insn (gen_movsi_ie (word1, mem));
5973 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5974 mem = copy_rtx (mem);
5975 emit_insn (gen_movsi_ie (word0, mem));
5982 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5984 [(set (match_operand:DF 0 "register_operand" "")
5985 (match_operand:DF 1 "memory_operand" ""))
5986 (use (match_operand:PSI 2 "fpscr_operand" ""))
5987 (clobber (reg:SI R0_REG))]
5988 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5989 [(parallel [(set (match_dup 0) (match_dup 1))
5991 (clobber (scratch:SI))])]
5994 (define_expand "reload_indf__frn"
5995 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5996 (match_operand:DF 1 "immediate_operand" "FQ"))
5997 (use (reg:PSI FPSCR_REG))
5998 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6002 (define_expand "reload_outdf__RnFRm"
6003 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6004 (match_operand:DF 1 "register_operand" "af,r"))
6005 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6009 ;; Simplify no-op moves.
6011 [(set (match_operand:SF 0 "register_operand" "")
6012 (match_operand:SF 1 "register_operand" ""))
6013 (use (match_operand:PSI 2 "fpscr_operand" ""))
6014 (clobber (match_scratch:SI 3 ""))]
6015 "TARGET_SH2E && reload_completed
6016 && true_regnum (operands[0]) == true_regnum (operands[1])"
6017 [(set (match_dup 0) (match_dup 0))]
6020 ;; fmovd substitute post-reload splits
6022 [(set (match_operand:DF 0 "register_operand" "")
6023 (match_operand:DF 1 "register_operand" ""))
6024 (use (match_operand:PSI 2 "fpscr_operand" ""))
6025 (clobber (match_scratch:SI 3 ""))]
6026 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6027 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6028 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6032 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6033 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6034 gen_rtx_REG (SFmode, src), operands[2]));
6035 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6036 gen_rtx_REG (SFmode, src + 1), operands[2]));
6041 [(set (match_operand:DF 0 "register_operand" "")
6042 (mem:DF (match_operand:SI 1 "register_operand" "")))
6043 (use (match_operand:PSI 2 "fpscr_operand" ""))
6044 (clobber (match_scratch:SI 3 ""))]
6045 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6046 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6047 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6051 int regno = true_regnum (operands[0]);
6053 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6055 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6056 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6057 regno + !! TARGET_LITTLE_ENDIAN),
6058 mem2, operands[2]));
6059 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6060 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6061 regno + ! TARGET_LITTLE_ENDIAN),
6062 change_address (mem, SFmode, NULL_RTX),
6068 [(set (match_operand:DF 0 "register_operand" "")
6069 (match_operand:DF 1 "memory_operand" ""))
6070 (use (match_operand:PSI 2 "fpscr_operand" ""))
6071 (clobber (match_scratch:SI 3 ""))]
6072 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6073 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6077 int regno = true_regnum (operands[0]);
6078 rtx addr, insn, adjust = NULL_RTX;
6079 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6080 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6081 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6083 operands[1] = copy_rtx (mem2);
6084 addr = XEXP (mem2, 0);
6085 if (GET_CODE (addr) != POST_INC)
6087 /* If we have to modify the stack pointer, the value that we have
6088 read with post-increment might be modified by an interrupt,
6089 so write it back. */
6090 if (REGNO (addr) == STACK_POINTER_REGNUM)
6091 adjust = gen_push_e (reg0);
6093 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6094 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6096 addr = XEXP (addr, 0);
6097 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6098 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6099 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6103 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6108 [(set (match_operand:DF 0 "memory_operand" "")
6109 (match_operand:DF 1 "register_operand" ""))
6110 (use (match_operand:PSI 2 "fpscr_operand" ""))
6111 (clobber (match_scratch:SI 3 ""))]
6112 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6113 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6117 int regno = true_regnum (operands[1]);
6118 rtx insn, addr, adjust = NULL_RTX;
6120 operands[0] = copy_rtx (operands[0]);
6121 PUT_MODE (operands[0], SFmode);
6122 insn = emit_insn (gen_movsf_ie (operands[0],
6123 gen_rtx_REG (SFmode,
6124 regno + ! TARGET_LITTLE_ENDIAN),
6126 operands[0] = copy_rtx (operands[0]);
6127 addr = XEXP (operands[0], 0);
6128 if (GET_CODE (addr) != PRE_DEC)
6130 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6131 emit_insn_before (adjust, insn);
6132 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6134 addr = XEXP (addr, 0);
6136 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6137 insn = emit_insn (gen_movsf_ie (operands[0],
6138 gen_rtx_REG (SFmode,
6139 regno + !! TARGET_LITTLE_ENDIAN),
6141 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6145 ;; If the output is a register and the input is memory or a register, we have
6146 ;; to be careful and see which word needs to be loaded first.
6149 [(set (match_operand:DF 0 "general_movdst_operand" "")
6150 (match_operand:DF 1 "general_movsrc_operand" ""))]
6151 "TARGET_SH1 && reload_completed"
6152 [(set (match_dup 2) (match_dup 3))
6153 (set (match_dup 4) (match_dup 5))]
6158 if ((GET_CODE (operands[0]) == MEM
6159 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6160 || (GET_CODE (operands[1]) == MEM
6161 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6164 switch (GET_CODE (operands[0]))
6167 regno = REGNO (operands[0]);
6170 regno = subreg_regno (operands[0]);
6180 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6182 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6183 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6184 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6185 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6189 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6190 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6191 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6192 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6195 if (operands[2] == 0 || operands[3] == 0
6196 || operands[4] == 0 || operands[5] == 0)
6200 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6201 ;; used only once, let combine add in the index again.
6204 [(set (match_operand:SI 0 "register_operand" "")
6205 (match_operand:SI 1 "" ""))
6206 (clobber (match_operand 2 "register_operand" ""))]
6207 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6208 && ALLOW_INDEXED_ADDRESS"
6209 [(use (reg:SI R0_REG))]
6212 rtx addr, reg, const_int;
6214 if (GET_CODE (operands[1]) != MEM)
6216 addr = XEXP (operands[1], 0);
6217 if (GET_CODE (addr) != PLUS)
6219 reg = XEXP (addr, 0);
6220 const_int = XEXP (addr, 1);
6221 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6222 && GET_CODE (const_int) == CONST_INT))
6224 emit_move_insn (operands[2], const_int);
6225 emit_move_insn (operands[0],
6226 change_address (operands[1], VOIDmode,
6227 gen_rtx_PLUS (SImode, reg, operands[2])));
6232 [(set (match_operand:SI 1 "" "")
6233 (match_operand:SI 0 "register_operand" ""))
6234 (clobber (match_operand 2 "register_operand" ""))]
6235 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6236 && ALLOW_INDEXED_ADDRESS"
6237 [(use (reg:SI R0_REG))]
6240 rtx addr, reg, const_int;
6242 if (GET_CODE (operands[1]) != MEM)
6244 addr = XEXP (operands[1], 0);
6245 if (GET_CODE (addr) != PLUS)
6247 reg = XEXP (addr, 0);
6248 const_int = XEXP (addr, 1);
6249 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6250 && GET_CODE (const_int) == CONST_INT))
6252 emit_move_insn (operands[2], const_int);
6253 emit_move_insn (change_address (operands[1], VOIDmode,
6254 gen_rtx_PLUS (SImode, reg, operands[2])),
6259 (define_expand "movdf"
6260 [(set (match_operand:DF 0 "general_movdst_operand" "")
6261 (match_operand:DF 1 "general_movsrc_operand" ""))]
6265 if (prepare_move_operands (operands, DFmode)) DONE;
6268 if (TARGET_SHMEDIA_FPU)
6269 emit_insn (gen_movdf_media (operands[0], operands[1]));
6271 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6274 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6276 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6281 ;;This is incompatible with the way gcc uses subregs.
6282 ;;(define_insn "movv2sf_i"
6283 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6284 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6285 ;; "TARGET_SHMEDIA_FPU
6286 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6287 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6291 ;; fst%M0.p %m0, %1"
6292 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6294 (define_insn_and_split "movv2sf_i"
6295 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6296 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6297 "TARGET_SHMEDIA_FPU"
6299 "TARGET_SHMEDIA_FPU && reload_completed"
6300 [(set (match_dup 0) (match_dup 1))]
6303 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6304 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6307 (define_expand "movv2sf"
6308 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6309 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6310 "TARGET_SHMEDIA_FPU"
6313 if (prepare_move_operands (operands, V2SFmode))
6317 (define_expand "addv2sf3"
6318 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6319 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6320 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6321 "TARGET_SHMEDIA_FPU"
6324 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6328 (define_expand "subv2sf3"
6329 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6330 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6331 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6332 "TARGET_SHMEDIA_FPU"
6335 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6339 (define_expand "mulv2sf3"
6340 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6341 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6342 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6343 "TARGET_SHMEDIA_FPU"
6346 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6350 (define_expand "divv2sf3"
6351 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6352 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6353 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6354 "TARGET_SHMEDIA_FPU"
6357 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6361 (define_insn_and_split "*movv4sf_i"
6362 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6363 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6364 "TARGET_SHMEDIA_FPU"
6366 "&& reload_completed"
6372 for (i = 0; i < 4/2; i++)
6376 if (GET_CODE (operands[0]) == MEM)
6377 x = adjust_address (operands[0], V2SFmode,
6378 i * GET_MODE_SIZE (V2SFmode));
6380 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6382 if (GET_CODE (operands[1]) == MEM)
6383 y = adjust_address (operands[1], V2SFmode,
6384 i * GET_MODE_SIZE (V2SFmode));
6386 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6388 emit_insn (gen_movv2sf_i (x, y));
6393 [(set_attr "length" "8")])
6395 (define_expand "movv4sf"
6396 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6397 (match_operand:V4SF 1 "general_operand" ""))]
6398 "TARGET_SHMEDIA_FPU"
6401 if (prepare_move_operands (operands, V4SFmode))
6405 (define_insn_and_split "*movv16sf_i"
6406 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6407 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6408 "TARGET_SHMEDIA_FPU"
6410 "&& reload_completed"
6416 for (i = 0; i < 16/2; i++)
6420 if (GET_CODE (operands[0]) == MEM)
6421 x = adjust_address (operands[0], V2SFmode,
6422 i * GET_MODE_SIZE (V2SFmode));
6425 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6429 if (GET_CODE (operands[1]) == MEM)
6430 y = adjust_address (operands[1], V2SFmode,
6431 i * GET_MODE_SIZE (V2SFmode));
6434 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6438 emit_insn (gen_movv2sf_i (x, y));
6443 [(set_attr "length" "32")])
6445 (define_expand "movv16sf"
6446 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6447 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6448 "TARGET_SHMEDIA_FPU"
6451 if (prepare_move_operands (operands, V16SFmode))
6455 (define_insn "movsf_media"
6456 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6457 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6459 && (register_operand (operands[0], SFmode)
6460 || sh_register_operand (operands[1], SFmode))"
6471 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6472 (set (attr "highpart")
6473 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6474 (const_string "user")]
6475 (const_string "ignore")))])
6477 (define_insn "movsf_media_nofpu"
6478 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6479 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6481 && (register_operand (operands[0], SFmode)
6482 || sh_register_operand (operands[1], SFmode))"
6488 [(set_attr "type" "arith_media,*,load_media,store_media")
6489 (set (attr "highpart")
6490 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6491 (const_string "user")]
6492 (const_string "ignore")))])
6495 [(set (match_operand:SF 0 "arith_reg_dest" "")
6496 (match_operand:SF 1 "immediate_operand" ""))]
6497 "TARGET_SHMEDIA && reload_completed
6498 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6499 [(set (match_dup 3) (match_dup 2))]
6503 REAL_VALUE_TYPE value;
6505 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6506 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6507 operands[2] = GEN_INT (values);
6509 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6512 (define_insn "movsf_i"
6513 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6514 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6517 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6518 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6519 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6520 && (arith_reg_operand (operands[0], SFmode)
6521 || arith_reg_operand (operands[1], SFmode))"
6530 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6532 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6533 ;; update_flow_info would not know where to put REG_EQUAL notes
6534 ;; when the destination changes mode.
6535 (define_insn "movsf_ie"
6536 [(set (match_operand:SF 0 "general_movdst_operand"
6537 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6538 (match_operand:SF 1 "general_movsrc_operand"
6539 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6540 (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"))
6541 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6544 && (arith_reg_operand (operands[0], SFmode)
6545 || arith_reg_operand (operands[1], SFmode)
6546 || arith_reg_operand (operands[3], SImode)
6547 || (fpul_operand (operands[0], SFmode)
6548 && memory_operand (operands[1], SFmode)
6549 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6550 || (fpul_operand (operands[1], SFmode)
6551 && memory_operand (operands[0], SFmode)
6552 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6572 ! move optimized away"
6573 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6574 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6575 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6576 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6577 (const_string "single")
6578 (const_string "none")))])
6581 [(set (match_operand:SF 0 "register_operand" "")
6582 (match_operand:SF 1 "register_operand" ""))
6583 (use (match_operand:PSI 2 "fpscr_operand" ""))
6584 (clobber (reg:SI FPUL_REG))]
6586 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6588 (clobber (scratch:SI))])
6589 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6591 (clobber (scratch:SI))])]
6594 (define_expand "movsf"
6595 [(set (match_operand:SF 0 "general_movdst_operand" "")
6596 (match_operand:SF 1 "general_movsrc_operand" ""))]
6600 if (prepare_move_operands (operands, SFmode))
6604 if (TARGET_SHMEDIA_FPU)
6605 emit_insn (gen_movsf_media (operands[0], operands[1]));
6607 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6612 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6617 (define_insn "mov_nop"
6618 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6621 [(set_attr "length" "0")
6622 (set_attr "type" "nil")])
6624 (define_expand "reload_insf__frn"
6625 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6626 (match_operand:SF 1 "immediate_operand" "FQ"))
6627 (use (reg:PSI FPSCR_REG))
6628 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6632 (define_expand "reload_insi__i_fpul"
6633 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6634 (match_operand:SI 1 "immediate_operand" "i"))
6635 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6639 (define_expand "ptabs"
6640 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6644 if (!TARGET_PT_FIXED)
6646 rtx eq = operands[1];
6648 /* ??? For canonical RTL we really should remove any CONST from EQ
6649 before wrapping it in the AND, and finally wrap the EQ into a
6650 const if is constant. However, for reload we must expose the
6651 input register or symbolic constant, and we can't have
6652 different insn structures outside of the operands for different
6653 alternatives of the same pattern. */
6654 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6657 = (gen_rtx_IF_THEN_ELSE
6660 gen_rtx_MEM (PDImode, operands[1]),
6661 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6662 PDImode, operands[1])));
6666 ;; expanded by ptabs expander.
6667 (define_insn "*extendsipdi_media"
6668 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6669 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6673 (mem:PDI (match_dup 1))
6674 (sign_extend:PDI (match_dup 1))))]
6675 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6679 [(set_attr "type" "ptabs_media,pt_media")
6680 (set_attr "length" "4,*")])
6682 (define_insn "*truncdipdi_media"
6683 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6684 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6688 (mem:PDI (match_dup 1))
6689 (truncate:PDI (match_dup 1))))]
6690 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6694 [(set_attr "type" "ptabs_media,pt_media")
6695 (set_attr "length" "4,*")])
6697 (define_insn "*movsi_y"
6698 [(set (match_operand:SI 0 "register_operand" "=y,y")
6699 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6700 (clobber (match_scratch:SI 2 "=&z,r"))]
6702 && (reload_in_progress || reload_completed)"
6704 [(set_attr "length" "4")
6705 (set_attr "type" "pcload,move")])
6708 [(set (match_operand:SI 0 "register_operand" "")
6709 (match_operand:SI 1 "immediate_operand" ""))
6710 (clobber (match_operand:SI 2 "register_operand" ""))]
6712 [(set (match_dup 2) (match_dup 1))
6713 (set (match_dup 0) (match_dup 2))]
6717 [(set (match_operand:SI 0 "register_operand" "")
6718 (match_operand:SI 1 "memory_operand" ""))
6719 (clobber (reg:SI R0_REG))]
6721 [(set (match_dup 0) (match_dup 1))]
6724 ;; ------------------------------------------------------------------------
6725 ;; Define the real conditional branch instructions.
6726 ;; ------------------------------------------------------------------------
6728 (define_insn "branch_true"
6729 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6730 (label_ref (match_operand 0 "" ""))
6733 "* return output_branch (1, insn, operands);"
6734 [(set_attr "type" "cbranch")])
6736 (define_insn "branch_false"
6737 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6738 (label_ref (match_operand 0 "" ""))
6741 "* return output_branch (0, insn, operands);"
6742 [(set_attr "type" "cbranch")])
6744 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6745 ;; which destination is too far away.
6746 ;; The const_int_operand is distinct for each branch target; it avoids
6747 ;; unwanted matches with redundant_insn.
6748 (define_insn "block_branch_redirect"
6749 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6752 [(set_attr "length" "0")])
6754 ;; This one has the additional purpose to record a possible scratch register
6755 ;; for the following branch.
6756 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6757 ;; because the insn then might be deemed dead and deleted. And we can't
6758 ;; make the use in the jump insn explicit because that would disable
6759 ;; delay slot scheduling from the target.
6760 (define_insn "indirect_jump_scratch"
6761 [(set (match_operand:SI 0 "register_operand" "=r")
6762 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6763 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6766 [(set_attr "length" "0")])
6768 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6769 ;; being pulled into the delay slot of a condbranch that has been made to
6770 ;; jump around the unconditional jump because it was out of range.
6771 (define_insn "stuff_delay_slot"
6773 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6774 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6777 [(set_attr "length" "0")
6778 (set_attr "cond_delay_slot" "yes")])
6780 ;; Conditional branch insns
6782 (define_expand "beq_media"
6784 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6785 (match_operand:DI 2 "arith_operand" "r,I06"))
6786 (match_operand 0 "" "")
6789 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6791 (define_insn "*beq_media_i"
6793 (if_then_else (match_operator 3 "equality_comparison_operator"
6794 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6795 (match_operand:DI 2 "arith_operand" "r,I06")])
6796 (match_operand 0 "target_operand" "b,b")
6801 b%o3i%' %1, %2, %0%>"
6802 [(set_attr "type" "cbranch_media")])
6804 (define_insn "*beq_media_i32"
6806 (if_then_else (match_operator 3 "equality_comparison_operator"
6807 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6808 (match_operand:SI 2 "arith_operand" "r,I06")])
6809 (match_operand 0 "target_operand" "b,b")
6814 b%o3i%' %1, %2, %0%>"
6815 [(set_attr "type" "cbranch_media")])
6817 (define_expand "bne_media"
6819 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6820 (match_operand:DI 2 "arith_operand" "r,I06"))
6821 (match_operand 0 "" "")
6824 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6826 (define_expand "bgt_media"
6828 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6829 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6830 (match_operand 0 "" "")
6833 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6835 (define_expand "bge_media"
6837 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6838 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6839 (match_operand 0 "" "")
6842 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6844 (define_expand "bgtu_media"
6846 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6847 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6848 (match_operand 0 "" "")
6851 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6853 (define_expand "bgeu_media"
6855 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6856 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6857 (match_operand 0 "" "")
6860 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6862 (define_insn "*bgt_media_i"
6864 (if_then_else (match_operator 3 "greater_comparison_operator"
6865 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6866 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6867 (match_operand 0 "target_operand" "b")
6870 "b%o3%' %N1, %N2, %0%>"
6871 [(set_attr "type" "cbranch_media")])
6873 (define_insn "*bgt_media_i32"
6875 (if_then_else (match_operator 3 "greater_comparison_operator"
6876 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6877 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6878 (match_operand 0 "target_operand" "b")
6881 "b%o3%' %N1, %N2, %0%>"
6882 [(set_attr "type" "cbranch_media")])
6884 ;; These are only needed to make invert_jump() happy - otherwise, jump
6885 ;; optimization will be silently disabled.
6886 (define_insn "*blt_media_i"
6888 (if_then_else (match_operator 3 "less_comparison_operator"
6889 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6890 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6891 (match_operand 0 "target_operand" "b")
6894 "b%o3%' %N2, %N1, %0%>"
6895 [(set_attr "type" "cbranch_media")])
6897 (define_insn "*blt_media_i32"
6899 (if_then_else (match_operator 3 "less_comparison_operator"
6900 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6901 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6902 (match_operand 0 "target_operand" "b")
6905 "b%o3%' %N2, %N1, %0%>"
6906 [(set_attr "type" "cbranch_media")])
6908 (define_expand "beq"
6910 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6911 (label_ref (match_operand 0 "" ""))
6918 enum machine_mode mode = GET_MODE (sh_compare_op0);
6920 if (mode != DImode && mode != SImode)
6922 rtx tmp = gen_reg_rtx (DImode);
6924 emit_insn (gen_seq (tmp));
6925 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6929 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6930 if (CONSTANT_P (sh_compare_op1)
6931 && (GET_CODE (sh_compare_op1) != CONST_INT
6932 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6933 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6934 emit_jump_insn (gen_beq_media (operands[0],
6935 sh_compare_op0, sh_compare_op1));
6939 from_compare (operands, EQ);
6942 (define_expand "bne"
6944 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6945 (label_ref (match_operand 0 "" ""))
6952 enum machine_mode mode = GET_MODE (sh_compare_op0);
6954 if (mode != DImode && mode != SImode)
6956 rtx tmp = gen_reg_rtx (DImode);
6958 emit_insn (gen_seq (tmp));
6959 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6963 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6964 if (CONSTANT_P (sh_compare_op1)
6965 && (GET_CODE (sh_compare_op1) != CONST_INT
6966 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6967 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6968 emit_jump_insn (gen_bne_media (operands[0],
6969 sh_compare_op0, sh_compare_op1));
6973 from_compare (operands, EQ);
6976 (define_expand "bgt"
6978 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6979 (label_ref (match_operand 0 "" ""))
6986 enum machine_mode mode = GET_MODE (sh_compare_op0);
6988 if (mode != DImode && mode != SImode)
6990 rtx tmp = gen_reg_rtx (DImode);
6992 emit_insn (gen_sgt (tmp));
6993 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6997 if (sh_compare_op0 != const0_rtx)
6998 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6999 if (sh_compare_op1 != const0_rtx)
7000 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7001 emit_jump_insn (gen_bgt_media (operands[0],
7002 sh_compare_op0, sh_compare_op1));
7006 from_compare (operands, GT);
7009 (define_expand "blt"
7011 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7012 (label_ref (match_operand 0 "" ""))
7019 enum machine_mode mode = GET_MODE (sh_compare_op0);
7021 if (mode != DImode && mode != SImode)
7023 rtx tmp = gen_reg_rtx (DImode);
7025 emit_insn (gen_slt (tmp));
7026 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7030 if (sh_compare_op0 != const0_rtx)
7031 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7032 if (sh_compare_op1 != const0_rtx)
7033 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7034 emit_jump_insn (gen_bgt_media (operands[0],
7035 sh_compare_op1, sh_compare_op0));
7039 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7041 rtx tmp = sh_compare_op0;
7042 sh_compare_op0 = sh_compare_op1;
7043 sh_compare_op1 = tmp;
7044 emit_insn (gen_bgt (operands[0]));
7047 from_compare (operands, GE);
7050 (define_expand "ble"
7052 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7053 (label_ref (match_operand 0 "" ""))
7060 enum machine_mode mode = GET_MODE (sh_compare_op0);
7062 if (mode != DImode && mode != SImode)
7064 rtx tmp = gen_reg_rtx (DImode);
7066 emit_insn (gen_sle (tmp));
7067 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7071 if (sh_compare_op0 != const0_rtx)
7072 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7073 if (sh_compare_op1 != const0_rtx)
7074 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7075 emit_jump_insn (gen_bge_media (operands[0],
7076 sh_compare_op1, sh_compare_op0));
7082 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7084 rtx tmp = sh_compare_op0;
7085 sh_compare_op0 = sh_compare_op1;
7086 sh_compare_op1 = tmp;
7087 emit_insn (gen_bge (operands[0]));
7090 from_compare (operands, GT);
7093 (define_expand "bge"
7095 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7096 (label_ref (match_operand 0 "" ""))
7103 enum machine_mode mode = GET_MODE (sh_compare_op0);
7105 if (mode != DImode && mode != SImode)
7107 rtx tmp = gen_reg_rtx (DImode);
7109 emit_insn (gen_sge (tmp));
7110 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7114 if (sh_compare_op0 != const0_rtx)
7115 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7116 if (sh_compare_op1 != const0_rtx)
7117 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7118 emit_jump_insn (gen_bge_media (operands[0],
7119 sh_compare_op0, sh_compare_op1));
7125 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7127 rtx tmp = sh_compare_op0;
7128 sh_compare_op0 = sh_compare_op1;
7129 sh_compare_op1 = tmp;
7130 emit_insn (gen_ble (operands[0]));
7133 from_compare (operands, GE);
7136 (define_expand "bgtu"
7138 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7139 (label_ref (match_operand 0 "" ""))
7146 enum machine_mode mode = GET_MODE (sh_compare_op0);
7148 if (sh_compare_op0 != const0_rtx)
7149 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7150 if (sh_compare_op1 != const0_rtx)
7151 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7152 emit_jump_insn (gen_bgtu_media (operands[0],
7153 sh_compare_op0, sh_compare_op1));
7157 from_compare (operands, GTU);
7160 (define_expand "bltu"
7162 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7163 (label_ref (match_operand 0 "" ""))
7170 enum machine_mode mode = GET_MODE (sh_compare_op0);
7172 if (sh_compare_op0 != const0_rtx)
7173 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7174 if (sh_compare_op1 != const0_rtx)
7175 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7176 emit_jump_insn (gen_bgtu_media (operands[0],
7177 sh_compare_op1, sh_compare_op0));
7181 from_compare (operands, GEU);
7184 (define_expand "bgeu"
7186 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7187 (label_ref (match_operand 0 "" ""))
7194 enum machine_mode mode = GET_MODE (sh_compare_op0);
7196 if (sh_compare_op0 != const0_rtx)
7197 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7198 if (sh_compare_op1 != const0_rtx)
7199 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7200 emit_jump_insn (gen_bgeu_media (operands[0],
7201 sh_compare_op0, sh_compare_op1));
7205 from_compare (operands, GEU);
7208 (define_expand "bleu"
7210 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7211 (label_ref (match_operand 0 "" ""))
7218 enum machine_mode mode = GET_MODE (sh_compare_op0);
7220 if (sh_compare_op0 != const0_rtx)
7221 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7222 if (sh_compare_op1 != const0_rtx)
7223 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7224 emit_jump_insn (gen_bgeu_media (operands[0],
7225 sh_compare_op1, sh_compare_op0));
7229 from_compare (operands, GTU);
7232 (define_expand "bunordered"
7233 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7235 (if_then_else (ne (match_dup 1) (const_int 0))
7236 (match_operand 0 "" "")
7241 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7242 operands[1] = gen_reg_rtx (SImode);
7243 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7244 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7247 ;; combiner splitter for test-and-branch on single bit in register. This
7248 ;; is endian dependent because the non-paradoxical subreg looks different
7253 (match_operator 3 "equality_comparison_operator"
7254 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7255 "extend_reg_operand" "")
7259 "const_int_operand" "")) 0)
7261 (match_operand 0 "target_operand" "")
7263 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7264 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7265 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7266 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7270 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7271 operands[6] = (GET_CODE (operands[3]) == EQ
7272 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7273 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7276 ;; ------------------------------------------------------------------------
7277 ;; Jump and linkage insns
7278 ;; ------------------------------------------------------------------------
7280 (define_insn "jump_compact"
7282 (label_ref (match_operand 0 "" "")))]
7286 /* The length is 16 if the delay slot is unfilled. */
7287 if (get_attr_length(insn) > 4)
7288 return output_far_jump(insn, operands[0]);
7290 return \"bra %l0%#\";
7292 [(set_attr "type" "jump")
7293 (set_attr "needs_delay_slot" "yes")])
7295 ;; ??? It would be much saner to explicitly use the scratch register
7296 ;; in the jump insn, and have indirect_jump_scratch only set it,
7297 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7298 ;; from the target then, as it uses simplejump_p.
7299 ;;(define_insn "jump_compact_far"
7301 ;; (label_ref (match_operand 0 "" "")))
7302 ;; (use (match_operand 1 "register_operand" "r")]
7304 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7305 ;; [(set_attr "type" "jump")
7306 ;; (set_attr "needs_delay_slot" "yes")])
7308 (define_insn "jump_media"
7310 (match_operand 0 "target_operand" "b"))]
7313 [(set_attr "type" "jump_media")])
7315 (define_expand "jump"
7317 (label_ref (match_operand 0 "" "")))]
7322 emit_jump_insn (gen_jump_compact (operands[0]));
7323 else if (TARGET_SHMEDIA)
7325 if (reload_in_progress || reload_completed)
7327 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7333 (define_insn "force_mode_for_call"
7334 [(use (reg:PSI FPSCR_REG))]
7337 [(set_attr "length" "0")
7338 (set (attr "fp_mode")
7339 (if_then_else (eq_attr "fpu_single" "yes")
7340 (const_string "single") (const_string "double")))])
7342 (define_insn "calli"
7343 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7344 (match_operand 1 "" ""))
7345 (use (reg:PSI FPSCR_REG))
7346 (clobber (reg:SI PR_REG))]
7349 [(set_attr "type" "call")
7350 (set (attr "fp_mode")
7351 (if_then_else (eq_attr "fpu_single" "yes")
7352 (const_string "single") (const_string "double")))
7353 (set_attr "needs_delay_slot" "yes")
7354 (set_attr "fp_set" "unknown")])
7356 ;; This is a pc-rel call, using bsrf, for use with PIC.
7358 (define_insn "calli_pcrel"
7359 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7360 (match_operand 1 "" ""))
7361 (use (reg:PSI FPSCR_REG))
7362 (use (reg:SI PIC_REG))
7363 (use (match_operand 2 "" ""))
7364 (clobber (reg:SI PR_REG))]
7367 [(set_attr "type" "call")
7368 (set (attr "fp_mode")
7369 (if_then_else (eq_attr "fpu_single" "yes")
7370 (const_string "single") (const_string "double")))
7371 (set_attr "needs_delay_slot" "yes")
7372 (set_attr "fp_set" "unknown")])
7374 (define_insn_and_split "call_pcrel"
7375 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7376 (match_operand 1 "" ""))
7377 (use (reg:PSI FPSCR_REG))
7378 (use (reg:SI PIC_REG))
7379 (clobber (reg:SI PR_REG))
7380 (clobber (match_scratch:SI 2 "=r"))]
7387 rtx lab = PATTERN (gen_call_site ());
7389 if (SYMBOL_REF_LOCAL_P (operands[0]))
7390 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7392 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7393 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7396 [(set_attr "type" "call")
7397 (set (attr "fp_mode")
7398 (if_then_else (eq_attr "fpu_single" "yes")
7399 (const_string "single") (const_string "double")))
7400 (set_attr "needs_delay_slot" "yes")
7401 (set_attr "fp_set" "unknown")])
7403 (define_insn "call_compact"
7404 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7405 (match_operand 1 "" ""))
7406 (match_operand 2 "immediate_operand" "n")
7407 (use (reg:SI R0_REG))
7408 (use (reg:SI R1_REG))
7409 (use (reg:PSI FPSCR_REG))
7410 (clobber (reg:SI PR_REG))]
7411 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7413 [(set_attr "type" "call")
7414 (set (attr "fp_mode")
7415 (if_then_else (eq_attr "fpu_single" "yes")
7416 (const_string "single") (const_string "double")))
7417 (set_attr "needs_delay_slot" "yes")])
7419 (define_insn "call_compact_rettramp"
7420 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7421 (match_operand 1 "" ""))
7422 (match_operand 2 "immediate_operand" "n")
7423 (use (reg:SI R0_REG))
7424 (use (reg:SI R1_REG))
7425 (use (reg:PSI FPSCR_REG))
7426 (clobber (reg:SI R10_REG))
7427 (clobber (reg:SI PR_REG))]
7428 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7430 [(set_attr "type" "call")
7431 (set (attr "fp_mode")
7432 (if_then_else (eq_attr "fpu_single" "yes")
7433 (const_string "single") (const_string "double")))
7434 (set_attr "needs_delay_slot" "yes")])
7436 (define_insn "call_media"
7437 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7438 (match_operand 1 "" ""))
7439 (clobber (reg:DI PR_MEDIA_REG))]
7442 [(set_attr "type" "jump_media")])
7444 (define_insn "call_valuei"
7445 [(set (match_operand 0 "" "=rf")
7446 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7447 (match_operand 2 "" "")))
7448 (use (reg:PSI FPSCR_REG))
7449 (clobber (reg:SI PR_REG))]
7452 [(set_attr "type" "call")
7453 (set (attr "fp_mode")
7454 (if_then_else (eq_attr "fpu_single" "yes")
7455 (const_string "single") (const_string "double")))
7456 (set_attr "needs_delay_slot" "yes")
7457 (set_attr "fp_set" "unknown")])
7459 (define_insn "call_valuei_pcrel"
7460 [(set (match_operand 0 "" "=rf")
7461 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7462 (match_operand 2 "" "")))
7463 (use (reg:PSI FPSCR_REG))
7464 (use (reg:SI PIC_REG))
7465 (use (match_operand 3 "" ""))
7466 (clobber (reg:SI PR_REG))]
7469 [(set_attr "type" "call")
7470 (set (attr "fp_mode")
7471 (if_then_else (eq_attr "fpu_single" "yes")
7472 (const_string "single") (const_string "double")))
7473 (set_attr "needs_delay_slot" "yes")
7474 (set_attr "fp_set" "unknown")])
7476 (define_insn_and_split "call_value_pcrel"
7477 [(set (match_operand 0 "" "=rf")
7478 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7479 (match_operand 2 "" "")))
7480 (use (reg:PSI FPSCR_REG))
7481 (use (reg:SI PIC_REG))
7482 (clobber (reg:SI PR_REG))
7483 (clobber (match_scratch:SI 3 "=r"))]
7490 rtx lab = PATTERN (gen_call_site ());
7492 if (SYMBOL_REF_LOCAL_P (operands[1]))
7493 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7495 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7496 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7497 operands[2], copy_rtx (lab)));
7500 [(set_attr "type" "call")
7501 (set (attr "fp_mode")
7502 (if_then_else (eq_attr "fpu_single" "yes")
7503 (const_string "single") (const_string "double")))
7504 (set_attr "needs_delay_slot" "yes")
7505 (set_attr "fp_set" "unknown")])
7507 (define_insn "call_value_compact"
7508 [(set (match_operand 0 "" "=rf")
7509 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7510 (match_operand 2 "" "")))
7511 (match_operand 3 "immediate_operand" "n")
7512 (use (reg:SI R0_REG))
7513 (use (reg:SI R1_REG))
7514 (use (reg:PSI FPSCR_REG))
7515 (clobber (reg:SI PR_REG))]
7516 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7518 [(set_attr "type" "call")
7519 (set (attr "fp_mode")
7520 (if_then_else (eq_attr "fpu_single" "yes")
7521 (const_string "single") (const_string "double")))
7522 (set_attr "needs_delay_slot" "yes")])
7524 (define_insn "call_value_compact_rettramp"
7525 [(set (match_operand 0 "" "=rf")
7526 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7527 (match_operand 2 "" "")))
7528 (match_operand 3 "immediate_operand" "n")
7529 (use (reg:SI R0_REG))
7530 (use (reg:SI R1_REG))
7531 (use (reg:PSI FPSCR_REG))
7532 (clobber (reg:SI R10_REG))
7533 (clobber (reg:SI PR_REG))]
7534 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7536 [(set_attr "type" "call")
7537 (set (attr "fp_mode")
7538 (if_then_else (eq_attr "fpu_single" "yes")
7539 (const_string "single") (const_string "double")))
7540 (set_attr "needs_delay_slot" "yes")])
7542 (define_insn "call_value_media"
7543 [(set (match_operand 0 "" "=rf")
7544 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7545 (match_operand 2 "" "")))
7546 (clobber (reg:DI PR_MEDIA_REG))]
7549 [(set_attr "type" "jump_media")])
7551 (define_expand "call"
7552 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7553 (match_operand 1 "" ""))
7554 (match_operand 2 "" "")
7555 (use (reg:PSI FPSCR_REG))
7556 (clobber (reg:SI PR_REG))])]
7562 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7563 emit_call_insn (gen_call_media (operands[0], operands[1]));
7566 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7568 rtx cookie_rtx = operands[2];
7569 long cookie = INTVAL (cookie_rtx);
7570 rtx func = XEXP (operands[0], 0);
7575 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7577 rtx reg = gen_reg_rtx (Pmode);
7579 emit_insn (gen_symGOTPLT2reg (reg, func));
7583 func = legitimize_pic_address (func, Pmode, 0);
7586 r0 = gen_rtx_REG (SImode, R0_REG);
7587 r1 = gen_rtx_REG (SImode, R1_REG);
7589 /* Since such a call function may use all call-clobbered
7590 registers, we force a mode switch earlier, so that we don't
7591 run out of registers when adjusting fpscr for the call. */
7592 emit_insn (gen_force_mode_for_call ());
7595 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7597 operands[0] = force_reg (SImode, operands[0]);
7599 emit_move_insn (r0, func);
7600 emit_move_insn (r1, cookie_rtx);
7602 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7603 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7606 emit_call_insn (gen_call_compact (operands[0], operands[1],
7611 else if (TARGET_SHCOMPACT && flag_pic
7612 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7613 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7615 rtx reg = gen_reg_rtx (Pmode);
7617 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7618 XEXP (operands[0], 0) = reg;
7620 if (flag_pic && TARGET_SH2
7621 && GET_CODE (operands[0]) == MEM
7622 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7624 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7629 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7630 operands[1] = operands[2];
7633 emit_call_insn (gen_calli (operands[0], operands[1]));
7637 (define_insn "call_pop_compact"
7638 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7639 (match_operand 1 "" ""))
7640 (match_operand 2 "immediate_operand" "n")
7641 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7642 (match_operand 3 "immediate_operand" "n")))
7643 (use (reg:SI R0_REG))
7644 (use (reg:SI R1_REG))
7645 (use (reg:PSI FPSCR_REG))
7646 (clobber (reg:SI PR_REG))]
7647 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7649 [(set_attr "type" "call")
7650 (set (attr "fp_mode")
7651 (if_then_else (eq_attr "fpu_single" "yes")
7652 (const_string "single") (const_string "double")))
7653 (set_attr "needs_delay_slot" "yes")])
7655 (define_insn "call_pop_compact_rettramp"
7656 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7657 (match_operand 1 "" ""))
7658 (match_operand 2 "immediate_operand" "n")
7659 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7660 (match_operand 3 "immediate_operand" "n")))
7661 (use (reg:SI R0_REG))
7662 (use (reg:SI R1_REG))
7663 (use (reg:PSI FPSCR_REG))
7664 (clobber (reg:SI R10_REG))
7665 (clobber (reg:SI PR_REG))]
7666 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7668 [(set_attr "type" "call")
7669 (set (attr "fp_mode")
7670 (if_then_else (eq_attr "fpu_single" "yes")
7671 (const_string "single") (const_string "double")))
7672 (set_attr "needs_delay_slot" "yes")])
7674 (define_expand "call_pop"
7675 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7676 (match_operand 1 "" ""))
7677 (match_operand 2 "" "")
7678 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7679 (match_operand 3 "" "")))])]
7688 gcc_assert (operands[2] && INTVAL (operands[2]));
7689 cookie_rtx = operands[2];
7690 cookie = INTVAL (cookie_rtx);
7691 func = XEXP (operands[0], 0);
7695 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7697 rtx reg = gen_reg_rtx (Pmode);
7698 emit_insn (gen_symGOTPLT2reg (reg, func));
7702 func = legitimize_pic_address (func, Pmode, 0);
7705 r0 = gen_rtx_REG (SImode, R0_REG);
7706 r1 = gen_rtx_REG (SImode, R1_REG);
7708 /* Since such a call function may use all call-clobbered
7709 registers, we force a mode switch earlier, so that we don't
7710 run out of registers when adjusting fpscr for the call. */
7711 emit_insn (gen_force_mode_for_call ());
7713 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7715 operands[0] = force_reg (SImode, operands[0]);
7717 emit_move_insn (r0, func);
7718 emit_move_insn (r1, cookie_rtx);
7720 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7721 emit_call_insn (gen_call_pop_compact_rettramp
7722 (operands[0], operands[1], operands[2], operands[3]));
7724 emit_call_insn (gen_call_pop_compact
7725 (operands[0], operands[1], operands[2], operands[3]));
7730 (define_expand "call_value"
7731 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7732 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7733 (match_operand 2 "" "")))
7734 (match_operand 3 "" "")
7735 (use (reg:PSI FPSCR_REG))
7736 (clobber (reg:SI PR_REG))])]
7742 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7743 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7747 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7749 rtx cookie_rtx = operands[3];
7750 long cookie = INTVAL (cookie_rtx);
7751 rtx func = XEXP (operands[1], 0);
7756 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7758 rtx reg = gen_reg_rtx (Pmode);
7760 emit_insn (gen_symGOTPLT2reg (reg, func));
7764 func = legitimize_pic_address (func, Pmode, 0);
7767 r0 = gen_rtx_REG (SImode, R0_REG);
7768 r1 = gen_rtx_REG (SImode, R1_REG);
7770 /* Since such a call function may use all call-clobbered
7771 registers, we force a mode switch earlier, so that we don't
7772 run out of registers when adjusting fpscr for the call. */
7773 emit_insn (gen_force_mode_for_call ());
7776 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7778 operands[1] = force_reg (SImode, operands[1]);
7780 emit_move_insn (r0, func);
7781 emit_move_insn (r1, cookie_rtx);
7783 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7784 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7789 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7790 operands[2], operands[3]));
7794 else if (TARGET_SHCOMPACT && flag_pic
7795 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7796 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7798 rtx reg = gen_reg_rtx (Pmode);
7800 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7801 XEXP (operands[1], 0) = reg;
7803 if (flag_pic && TARGET_SH2
7804 && GET_CODE (operands[1]) == MEM
7805 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7807 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7812 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7814 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7818 (define_insn "sibcalli"
7819 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7820 (match_operand 1 "" ""))
7821 (use (reg:PSI FPSCR_REG))
7825 [(set_attr "needs_delay_slot" "yes")
7826 (set (attr "fp_mode")
7827 (if_then_else (eq_attr "fpu_single" "yes")
7828 (const_string "single") (const_string "double")))
7829 (set_attr "type" "jump_ind")])
7831 (define_insn "sibcalli_pcrel"
7832 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7833 (match_operand 1 "" ""))
7834 (use (match_operand 2 "" ""))
7835 (use (reg:PSI FPSCR_REG))
7839 [(set_attr "needs_delay_slot" "yes")
7840 (set (attr "fp_mode")
7841 (if_then_else (eq_attr "fpu_single" "yes")
7842 (const_string "single") (const_string "double")))
7843 (set_attr "type" "jump_ind")])
7845 ;; This uses an unspec to describe that the symbol_ref is very close.
7846 (define_insn "sibcalli_thunk"
7847 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7849 (match_operand 1 "" ""))
7850 (use (reg:PSI FPSCR_REG))
7854 [(set_attr "needs_delay_slot" "yes")
7855 (set (attr "fp_mode")
7856 (if_then_else (eq_attr "fpu_single" "yes")
7857 (const_string "single") (const_string "double")))
7858 (set_attr "type" "jump")
7859 (set_attr "length" "2")])
7861 (define_insn_and_split "sibcall_pcrel"
7862 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7863 (match_operand 1 "" ""))
7864 (use (reg:PSI FPSCR_REG))
7865 (clobber (match_scratch:SI 2 "=k"))
7873 rtx lab = PATTERN (gen_call_site ());
7876 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7877 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7879 SIBLING_CALL_P (call_insn) = 1;
7882 [(set_attr "needs_delay_slot" "yes")
7883 (set (attr "fp_mode")
7884 (if_then_else (eq_attr "fpu_single" "yes")
7885 (const_string "single") (const_string "double")))
7886 (set_attr "type" "jump_ind")])
7888 (define_insn "sibcall_compact"
7889 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7890 (match_operand 1 "" ""))
7892 (use (match_operand:SI 2 "register_operand" "z,x"))
7893 (use (reg:SI R1_REG))
7894 (use (reg:PSI FPSCR_REG))
7895 ;; We want to make sure the `x' above will only match MACH_REG
7896 ;; because sibcall_epilogue may clobber MACL_REG.
7897 (clobber (reg:SI MACL_REG))]
7901 jmp @%0\\n sts %2, r0"
7902 [(set_attr "needs_delay_slot" "yes,no")
7903 (set_attr "length" "2,4")
7904 (set (attr "fp_mode") (const_string "single"))
7905 (set_attr "type" "jump_ind")])
7907 (define_insn "sibcall_media"
7908 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7909 (match_operand 1 "" ""))
7910 (use (reg:SI PR_MEDIA_REG))
7914 [(set_attr "type" "jump_media")])
7916 (define_expand "sibcall"
7918 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7919 (match_operand 1 "" ""))
7920 (match_operand 2 "" "")
7921 (use (reg:PSI FPSCR_REG))
7928 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7929 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7932 else if (TARGET_SHCOMPACT && operands[2]
7933 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7935 rtx cookie_rtx = operands[2];
7936 long cookie = INTVAL (cookie_rtx);
7937 rtx func = XEXP (operands[0], 0);
7942 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7944 rtx reg = gen_reg_rtx (Pmode);
7946 emit_insn (gen_symGOT2reg (reg, func));
7950 func = legitimize_pic_address (func, Pmode, 0);
7953 /* FIXME: if we could tell whether all argument registers are
7954 already taken, we could decide whether to force the use of
7955 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7956 simple way to tell. We could use the CALL_COOKIE, but we
7957 can't currently tell a register used for regular argument
7958 passing from one that is unused. If we leave it up to reload
7959 to decide which register to use, it seems to always choose
7960 R0_REG, which leaves no available registers in SIBCALL_REGS
7961 to hold the address of the trampoline. */
7962 mach = gen_rtx_REG (SImode, MACH_REG);
7963 r1 = gen_rtx_REG (SImode, R1_REG);
7965 /* Since such a call function may use all call-clobbered
7966 registers, we force a mode switch earlier, so that we don't
7967 run out of registers when adjusting fpscr for the call. */
7968 emit_insn (gen_force_mode_for_call ());
7971 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7973 operands[0] = force_reg (SImode, operands[0]);
7975 /* We don't need a return trampoline, since the callee will
7976 return directly to the upper caller. */
7977 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7979 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7980 cookie_rtx = GEN_INT (cookie);
7983 emit_move_insn (mach, func);
7984 emit_move_insn (r1, cookie_rtx);
7986 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7989 else if (TARGET_SHCOMPACT && flag_pic
7990 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7991 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7993 rtx reg = gen_reg_rtx (Pmode);
7995 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7996 XEXP (operands[0], 0) = reg;
7998 if (flag_pic && TARGET_SH2
7999 && GET_CODE (operands[0]) == MEM
8000 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8001 /* The PLT needs the PIC register, but the epilogue would have
8002 to restore it, so we can only use PC-relative PIC calls for
8003 static functions. */
8004 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8006 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8010 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8012 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8016 (define_expand "sibcall_value"
8017 [(set (match_operand 0 "" "")
8018 (call (match_operand 1 "" "")
8019 (match_operand 2 "" "")))
8020 (match_operand 3 "" "")]
8024 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
8028 (define_insn "call_value_pop_compact"
8029 [(set (match_operand 0 "" "=rf")
8030 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8031 (match_operand 2 "" "")))
8032 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8033 (match_operand 4 "immediate_operand" "n")))
8034 (match_operand 3 "immediate_operand" "n")
8035 (use (reg:SI R0_REG))
8036 (use (reg:SI R1_REG))
8037 (use (reg:PSI FPSCR_REG))
8038 (clobber (reg:SI PR_REG))]
8039 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8041 [(set_attr "type" "call")
8042 (set (attr "fp_mode")
8043 (if_then_else (eq_attr "fpu_single" "yes")
8044 (const_string "single") (const_string "double")))
8045 (set_attr "needs_delay_slot" "yes")])
8047 (define_insn "call_value_pop_compact_rettramp"
8048 [(set (match_operand 0 "" "=rf")
8049 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8050 (match_operand 2 "" "")))
8051 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8052 (match_operand 4 "immediate_operand" "n")))
8053 (match_operand 3 "immediate_operand" "n")
8054 (use (reg:SI R0_REG))
8055 (use (reg:SI R1_REG))
8056 (use (reg:PSI FPSCR_REG))
8057 (clobber (reg:SI R10_REG))
8058 (clobber (reg:SI PR_REG))]
8059 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8061 [(set_attr "type" "call")
8062 (set (attr "fp_mode")
8063 (if_then_else (eq_attr "fpu_single" "yes")
8064 (const_string "single") (const_string "double")))
8065 (set_attr "needs_delay_slot" "yes")])
8067 (define_expand "call_value_pop"
8068 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8069 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8070 (match_operand 2 "" "")))
8071 (match_operand 3 "" "")
8072 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8073 (match_operand 4 "" "")))])]
8082 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8083 cookie_rtx = operands[3];
8084 cookie = INTVAL (cookie_rtx);
8085 func = XEXP (operands[1], 0);
8089 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8091 rtx reg = gen_reg_rtx (Pmode);
8093 emit_insn (gen_symGOTPLT2reg (reg, func));
8097 func = legitimize_pic_address (func, Pmode, 0);
8100 r0 = gen_rtx_REG (SImode, R0_REG);
8101 r1 = gen_rtx_REG (SImode, R1_REG);
8103 /* Since such a call function may use all call-clobbered
8104 registers, we force a mode switch earlier, so that we don't
8105 run out of registers when adjusting fpscr for the call. */
8106 emit_insn (gen_force_mode_for_call ());
8108 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8110 operands[1] = force_reg (SImode, operands[1]);
8112 emit_move_insn (r0, func);
8113 emit_move_insn (r1, cookie_rtx);
8115 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8116 emit_call_insn (gen_call_value_pop_compact_rettramp
8117 (operands[0], operands[1], operands[2],
8118 operands[3], operands[4]));
8120 emit_call_insn (gen_call_value_pop_compact
8121 (operands[0], operands[1], operands[2],
8122 operands[3], operands[4]));
8127 (define_expand "sibcall_epilogue"
8132 sh_expand_epilogue (1);
8133 if (TARGET_SHCOMPACT)
8137 /* If epilogue clobbers r0, preserve it in macl. */
8138 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8139 if ((set = single_set (insn))
8140 && GET_CODE (SET_DEST (set)) == REG
8141 && REGNO (SET_DEST (set)) == R0_REG)
8143 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8144 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8147 /* We can't tell at this point whether the sibcall is a
8148 sibcall_compact and, if it is, whether it uses r0 or
8149 mach as operand 2, so let the instructions that
8150 preserve r0 be optimized away if r0 turns out to be
8152 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8153 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8155 i = emit_move_insn (r0, tmp);
8156 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8164 (define_insn "indirect_jump_compact"
8166 (match_operand:SI 0 "arith_reg_operand" "r"))]
8169 [(set_attr "needs_delay_slot" "yes")
8170 (set_attr "type" "jump_ind")])
8172 (define_expand "indirect_jump"
8174 (match_operand 0 "register_operand" ""))]
8178 if (GET_MODE (operands[0]) != Pmode)
8179 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8182 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8183 ;; which can be present in structured code from indirect jumps which can not
8184 ;; be present in structured code. This allows -fprofile-arcs to work.
8186 ;; For SH1 processors.
8187 (define_insn "casesi_jump_1"
8189 (match_operand:SI 0 "register_operand" "r"))
8190 (use (label_ref (match_operand 1 "" "")))]
8193 [(set_attr "needs_delay_slot" "yes")
8194 (set_attr "type" "jump_ind")])
8196 ;; For all later processors.
8197 (define_insn "casesi_jump_2"
8198 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8199 (label_ref (match_operand 1 "" ""))))
8200 (use (label_ref (match_operand 2 "" "")))]
8202 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8204 [(set_attr "needs_delay_slot" "yes")
8205 (set_attr "type" "jump_ind")])
8207 (define_insn "casesi_jump_media"
8208 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8209 (use (label_ref (match_operand 1 "" "")))]
8212 [(set_attr "type" "jump_media")])
8214 ;; Call subroutine returning any type.
8215 ;; ??? This probably doesn't work.
8217 (define_expand "untyped_call"
8218 [(parallel [(call (match_operand 0 "" "")
8220 (match_operand 1 "" "")
8221 (match_operand 2 "" "")])]
8222 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8227 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8229 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8231 rtx set = XVECEXP (operands[2], 0, i);
8232 emit_move_insn (SET_DEST (set), SET_SRC (set));
8235 /* The optimizer does not know that the call sets the function value
8236 registers we stored in the result block. We avoid problems by
8237 claiming that all hard registers are used and clobbered at this
8239 emit_insn (gen_blockage ());
8244 ;; ------------------------------------------------------------------------
8246 ;; ------------------------------------------------------------------------
8249 [(set (reg:SI T_REG)
8250 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8251 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8254 [(set_attr "type" "arith")])
8261 ;; Load address of a label. This is only generated by the casesi expand,
8262 ;; and by machine_dependent_reorg (fixing up fp moves).
8263 ;; This must use unspec, because this only works for labels that are
8267 [(set (reg:SI R0_REG)
8268 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8271 [(set_attr "in_delay_slot" "no")
8272 (set_attr "type" "arith")])
8274 ;; machine_dependent_reorg will make this a `mova'.
8275 (define_insn "mova_const"
8276 [(set (reg:SI R0_REG)
8277 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8280 [(set_attr "in_delay_slot" "no")
8281 (set_attr "type" "arith")])
8283 (define_expand "GOTaddr2picreg"
8284 [(set (reg:SI R0_REG)
8285 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8287 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8288 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8291 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8292 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8296 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8297 rtx pic = operands[0];
8298 rtx lab = PATTERN (gen_call_site ());
8301 equiv = operands[1];
8302 operands[1] = gen_rtx_MINUS (Pmode,
8306 gen_rtx_MINUS (Pmode,
8307 gen_rtx_CONST (Pmode,
8310 operands[1] = gen_sym2PIC (operands[1]);
8311 PUT_MODE (operands[1], Pmode);
8313 if (Pmode == SImode)
8315 emit_insn (gen_movsi_const (pic, operands[1]));
8316 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8320 emit_insn (gen_movdi_const (pic, operands[1]));
8321 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8324 insn = emit_move_insn (operands[0], tr);
8326 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8335 [(set (match_operand 0 "target_reg_operand" "=b")
8336 (const (unspec [(match_operand 1 "" "Csy")]
8337 UNSPEC_DATALABEL)))]
8338 "TARGET_SHMEDIA && flag_pic
8339 && EXTRA_CONSTRAINT_Csy (operands[1])"
8340 "ptb/u datalabel %1, %0"
8341 [(set_attr "type" "ptabs_media")
8342 (set_attr "length" "*")])
8344 (define_insn "ptrel_si"
8345 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8346 (plus:SI (match_operand:SI 1 "register_operand" "r")
8348 (match_operand:SI 2 "" "")]
8350 "%O2: ptrel/u %1, %0"
8351 [(set_attr "type" "ptabs_media")])
8353 (define_insn "ptrel_di"
8354 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8355 (plus:DI (match_operand:DI 1 "register_operand" "r")
8357 (match_operand:DI 2 "" "")]
8359 "%O2: ptrel/u %1, %0"
8360 [(set_attr "type" "ptabs_media")])
8362 (define_expand "builtin_setjmp_receiver"
8363 [(match_operand 0 "" "")]
8367 emit_insn (gen_GOTaddr2picreg ());
8371 (define_expand "call_site"
8372 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8376 static HOST_WIDE_INT i = 0;
8377 operands[0] = GEN_INT (i);
8381 (define_expand "sym_label2reg"
8382 [(set (match_operand:SI 0 "" "")
8385 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8388 (match_operand:SI 2 "" "")
8392 (define_expand "symGOT_load"
8393 [(set (match_dup 2) (match_operand 1 "" ""))
8394 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8395 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8401 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8402 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8406 rtx reg = operands[2];
8408 if (Pmode == DImode)
8411 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8413 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8418 emit_insn (gen_movsi_const (reg, operands[1]));
8420 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8424 emit_move_insn (operands[2], operands[1]);
8426 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8428 gen_rtx_REG (Pmode, PIC_REG)));
8430 /* N.B. This is not constant for a GOTPLT relocation. */
8431 mem = gen_rtx_MEM (Pmode, operands[3]);
8432 MEM_NOTRAP_P (mem) = 1;
8433 /* ??? Should we have a special alias set for the GOT? */
8434 insn = emit_move_insn (operands[0], mem);
8436 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8443 (define_expand "sym2GOT"
8444 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8448 (define_expand "symGOT2reg"
8449 [(match_operand 0 "" "") (match_operand 1 "" "")]
8455 gotsym = gen_sym2GOT (operands[1]);
8456 PUT_MODE (gotsym, Pmode);
8457 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8459 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8464 (define_expand "symGOTPLT2reg"
8465 [(match_operand 0 "" "") (match_operand 1 "" "")]
8469 rtx pltsym = gen_rtx_CONST (Pmode,
8470 gen_rtx_UNSPEC (Pmode,
8471 gen_rtvec (1, operands[1]),
8473 emit_insn (gen_symGOT_load (operands[0], pltsym));
8477 (define_expand "sym2GOTOFF"
8478 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8482 (define_expand "symGOTOFF2reg"
8483 [(match_operand 0 "" "") (match_operand 1 "" "")]
8487 rtx gotoffsym, insn;
8488 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8490 gotoffsym = gen_sym2GOTOFF (operands[1]);
8491 PUT_MODE (gotoffsym, Pmode);
8492 emit_move_insn (t, gotoffsym);
8493 insn = emit_move_insn (operands[0],
8494 gen_rtx_PLUS (Pmode, t,
8495 gen_rtx_REG (Pmode, PIC_REG)));
8497 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8503 (define_expand "symPLT_label2reg"
8504 [(set (match_operand:SI 0 "" "")
8507 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8511 (match_operand:SI 2 "" "")
8513 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8514 ;; Even though the PIC register is not really used by the call
8515 ;; sequence in which this is expanded, the PLT code assumes the PIC
8516 ;; register is set, so we must not skip its initialization. Since
8517 ;; we only use this expand as part of calling sequences, and never
8518 ;; to take the address of a function, this is the best point to
8519 ;; insert the (use). Using the PLT to take the address of a
8520 ;; function would be wrong, not only because the PLT entry could
8521 ;; then be called from a function that doesn't initialize the PIC
8522 ;; register to the proper GOT, but also because pointers to the
8523 ;; same function might not compare equal, should they be set by
8524 ;; different shared libraries.
8525 (use (reg:SI PIC_REG))]
8529 (define_expand "sym2PIC"
8530 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8534 ;; TLS code generation.
8535 ;; ??? this should be a define_insn_and_split
8536 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8537 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8540 (define_insn "tls_global_dynamic"
8541 [(set (match_operand:SI 0 "register_operand" "=&z")
8542 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8545 (use (reg:PSI FPSCR_REG))
8546 (use (reg:SI PIC_REG))
8547 (clobber (reg:SI PR_REG))
8548 (clobber (scratch:SI))]
8554 \\tmova\\t2f,r0\\n\\
8555 \\tmov.l\\t2f,r1\\n\\
8558 \\tadd\\tr12,r4\\n\\
8562 1:\\t.long\\t%a1@TLSGD\\n\\
8563 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8566 [(set_attr "type" "tls_load")
8567 (set_attr "length" "26")])
8569 (define_insn "tls_local_dynamic"
8570 [(set (match_operand:SI 0 "register_operand" "=&z")
8571 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8574 (use (reg:PSI FPSCR_REG))
8575 (use (reg:SI PIC_REG))
8576 (clobber (reg:SI PR_REG))
8577 (clobber (scratch:SI))]
8583 \\tmova\\t2f,r0\\n\\
8584 \\tmov.l\\t2f,r1\\n\\
8587 \\tadd\\tr12,r4\\n\\
8591 1:\\t.long\\t%a1@TLSLDM\\n\\
8592 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8595 [(set_attr "type" "tls_load")
8596 (set_attr "length" "26")])
8598 (define_expand "sym2DTPOFF"
8599 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8603 (define_expand "symDTPOFF2reg"
8604 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8608 rtx dtpoffsym, insn;
8609 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8611 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8612 PUT_MODE (dtpoffsym, Pmode);
8613 emit_move_insn (t, dtpoffsym);
8614 insn = emit_move_insn (operands[0],
8615 gen_rtx_PLUS (Pmode, t, operands[2]));
8619 (define_expand "sym2GOTTPOFF"
8620 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8624 (define_insn "tls_initial_exec"
8625 [(set (match_operand:SI 0 "register_operand" "=&r")
8626 (unspec:SI [(match_operand:SI 1 "" "")]
8628 (use (reg:SI GBR_REG))
8629 (use (reg:SI PIC_REG))
8630 (clobber (reg:SI R0_REG))]
8636 \\tstc\\tgbr,%0\\n\\
8637 \\tmov.l\\t@(r0,r12),r0\\n\\
8641 1:\\t.long\\t%a1\\n\\
8644 [(set_attr "type" "tls_load")
8645 (set_attr "length" "16")])
8647 (define_expand "sym2TPOFF"
8648 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8652 (define_expand "symTPOFF2reg"
8653 [(match_operand 0 "" "") (match_operand 1 "" "")]
8659 tpoffsym = gen_sym2TPOFF (operands[1]);
8660 PUT_MODE (tpoffsym, Pmode);
8661 insn = emit_move_insn (operands[0], tpoffsym);
8665 (define_insn "load_gbr"
8666 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8667 (use (reg:SI GBR_REG))]
8670 [(set_attr "type" "tls_load")])
8672 ;; case instruction for switch statements.
8674 ;; Operand 0 is index
8675 ;; operand 1 is the minimum bound
8676 ;; operand 2 is the maximum bound - minimum bound + 1
8677 ;; operand 3 is CODE_LABEL for the table;
8678 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8680 (define_expand "casesi"
8681 [(match_operand:SI 0 "arith_reg_operand" "")
8682 (match_operand:SI 1 "arith_reg_operand" "")
8683 (match_operand:SI 2 "arith_reg_operand" "")
8684 (match_operand 3 "" "") (match_operand 4 "" "")]
8688 rtx reg = gen_reg_rtx (SImode);
8689 rtx reg2 = gen_reg_rtx (SImode);
8692 rtx reg = gen_reg_rtx (DImode);
8693 rtx reg2 = gen_reg_rtx (DImode);
8694 rtx reg3 = gen_reg_rtx (Pmode);
8695 rtx reg4 = gen_reg_rtx (Pmode);
8696 rtx reg5 = gen_reg_rtx (Pmode);
8699 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8700 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8701 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8703 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8704 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8705 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8706 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8707 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8708 (Pmode, operands[3])));
8709 /* Messy: can we subreg to clean this up? */
8710 if (Pmode == DImode)
8711 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8713 load = gen_casesi_load_media (reg4,
8714 gen_rtx_SUBREG (DImode, reg3, 0),
8716 PUT_MODE (SET_SRC (load), Pmode);
8718 /* ??? The following add could be eliminated if we used ptrel. */
8719 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8720 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8724 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8725 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8726 /* If optimizing, casesi_worker depends on the mode of the instruction
8727 before label it 'uses' - operands[3]. */
8728 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8730 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8732 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8734 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8735 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8736 operands[3], but to lab. We will fix this up in
8737 machine_dependent_reorg. */
8742 (define_expand "casesi_0"
8743 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8744 (set (match_dup 4) (minus:SI (match_dup 4)
8745 (match_operand:SI 1 "arith_operand" "")))
8747 (gtu:SI (match_dup 4)
8748 (match_operand:SI 2 "arith_reg_operand" "")))
8750 (if_then_else (ne (reg:SI T_REG)
8752 (label_ref (match_operand 3 "" ""))
8757 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8758 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8759 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8761 (define_insn "casesi_worker_0"
8762 [(set (match_operand:SI 0 "register_operand" "=r,r")
8763 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8764 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8765 (clobber (match_scratch:SI 3 "=X,1"))
8766 (clobber (match_scratch:SI 4 "=&z,z"))]
8771 [(set (match_operand:SI 0 "register_operand" "")
8772 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8773 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8774 (clobber (match_scratch:SI 3 ""))
8775 (clobber (match_scratch:SI 4 ""))]
8776 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8777 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8778 (parallel [(set (match_dup 0)
8779 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8780 (label_ref (match_dup 2))] UNSPEC_CASESI))
8781 (clobber (match_dup 3))])
8782 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8783 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8786 [(set (match_operand:SI 0 "register_operand" "")
8787 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8788 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8789 (clobber (match_scratch:SI 3 ""))
8790 (clobber (match_scratch:SI 4 ""))]
8791 "TARGET_SH2 && reload_completed"
8792 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8793 (parallel [(set (match_dup 0)
8794 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8795 (label_ref (match_dup 2))] UNSPEC_CASESI))
8796 (clobber (match_dup 3))])]
8797 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8799 (define_insn "casesi_worker_1"
8800 [(set (match_operand:SI 0 "register_operand" "=r,r")
8801 (unspec:SI [(reg:SI R0_REG)
8802 (match_operand:SI 1 "register_operand" "0,r")
8803 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8804 (clobber (match_scratch:SI 3 "=X,1"))]
8808 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8810 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8812 switch (GET_MODE (diff_vec))
8815 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8817 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8819 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8820 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8821 return \"mov.b @(r0,%1),%0\";
8826 [(set_attr "length" "4")])
8828 (define_insn "casesi_worker_2"
8829 [(set (match_operand:SI 0 "register_operand" "=r,r")
8830 (unspec:SI [(reg:SI R0_REG)
8831 (match_operand:SI 1 "register_operand" "0,r")
8832 (label_ref (match_operand 2 "" ""))
8833 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8834 (clobber (match_operand:SI 4 "" "=X,1"))]
8835 "TARGET_SH2 && reload_completed && flag_pic"
8838 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8841 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8843 switch (GET_MODE (diff_vec))
8846 output_asm_insn (\"shll2 %1\", operands);
8847 load = \"mov.l @(r0,%1),%0\"; break;
8849 output_asm_insn (\"add %1,%1\", operands);
8850 load = \"mov.w @(r0,%1),%0\"; break;
8852 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8853 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8855 load = \"mov.b @(r0,%1),%0\";
8860 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8863 [(set_attr "length" "8")])
8865 (define_insn "casesi_shift_media"
8866 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8867 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8868 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8873 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8875 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8877 switch (GET_MODE (diff_vec))
8880 return \"shlli %1, 2, %0\";
8882 return \"shlli %1, 1, %0\";
8884 if (rtx_equal_p (operands[0], operands[1]))
8886 return \"add %1, r63, %0\";
8891 [(set_attr "type" "arith_media")])
8893 (define_insn "casesi_load_media"
8894 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8895 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8896 (match_operand:DI 2 "arith_reg_operand" "r")
8897 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8901 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8903 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8905 switch (GET_MODE (diff_vec))
8908 return \"ldx.l %1, %2, %0\";
8911 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8912 return \"ldx.uw %1, %2, %0\";
8914 return \"ldx.w %1, %2, %0\";
8916 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8917 return \"ldx.ub %1, %2, %0\";
8918 return \"ldx.b %1, %2, %0\";
8923 [(set_attr "type" "load_media")])
8925 (define_expand "return"
8927 "reload_completed && ! sh_need_epilogue ()"
8932 emit_jump_insn (gen_return_media ());
8936 if (TARGET_SHCOMPACT
8937 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8939 emit_jump_insn (gen_shcompact_return_tramp ());
8944 (define_insn "*return_i"
8946 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8947 && (current_function_args_info.call_cookie
8948 & CALL_COOKIE_RET_TRAMP (1)))
8950 && lookup_attribute (\"trap_exit\",
8951 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8953 [(set_attr "type" "return")
8954 (set_attr "needs_delay_slot" "yes")])
8956 ;; trapa has no delay slot.
8957 (define_insn "*return_trapa"
8959 "TARGET_SH1 && !TARGET_SHCOMPACT
8960 && reload_completed"
8962 [(set_attr "type" "return")])
8964 (define_expand "shcompact_return_tramp"
8967 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8970 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8972 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8973 emit_jump_insn (gen_shcompact_return_tramp_i ());
8977 (define_insn "shcompact_return_tramp_i"
8978 [(parallel [(return) (use (reg:SI R0_REG))])]
8980 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8982 [(set_attr "type" "jump_ind")
8983 (set_attr "needs_delay_slot" "yes")])
8985 (define_insn "return_media_i"
8986 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8987 "TARGET_SHMEDIA && reload_completed"
8989 [(set_attr "type" "jump_media")])
8991 (define_insn "return_media_rte"
8993 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8995 [(set_attr "type" "jump_media")])
8997 (define_expand "return_media"
8999 "TARGET_SHMEDIA && reload_completed"
9002 int tr_regno = sh_media_register_for_return ();
9005 if (current_function_interrupt)
9007 emit_jump_insn (gen_return_media_rte ());
9012 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9014 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9016 tr = gen_rtx_REG (Pmode, tr_regno);
9017 emit_move_insn (tr, r18);
9020 tr = gen_rtx_REG (Pmode, tr_regno);
9022 emit_jump_insn (gen_return_media_i (tr));
9026 (define_insn "shcompact_preserve_incoming_args"
9027 [(set (match_operand:SI 0 "register_operand" "+r")
9028 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9031 [(set_attr "length" "0")])
9033 (define_insn "shcompact_incoming_args"
9034 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9035 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9036 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9037 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9038 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9039 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9040 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9041 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9042 (set (mem:BLK (reg:SI MACL_REG))
9043 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9044 (use (reg:SI R0_REG))
9045 (clobber (reg:SI R0_REG))
9046 (clobber (reg:SI MACL_REG))
9047 (clobber (reg:SI MACH_REG))
9048 (clobber (reg:SI PR_REG))]
9051 [(set_attr "needs_delay_slot" "yes")])
9053 (define_insn "shmedia_save_restore_regs_compact"
9054 [(set (reg:SI SP_REG)
9055 (plus:SI (reg:SI SP_REG)
9056 (match_operand:SI 0 "immediate_operand" "i")))
9057 (use (reg:SI R0_REG))
9058 (clobber (reg:SI PR_REG))]
9060 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9061 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9063 [(set_attr "needs_delay_slot" "yes")])
9065 (define_expand "prologue"
9068 "sh_expand_prologue (); DONE;")
9070 (define_expand "epilogue"
9075 sh_expand_epilogue (0);
9076 emit_jump_insn (gen_return ());
9080 (define_expand "eh_return"
9081 [(use (match_operand 0 "register_operand" ""))]
9084 rtx ra = operands[0];
9086 if (TARGET_SHMEDIA64)
9087 emit_insn (gen_eh_set_ra_di (ra));
9089 emit_insn (gen_eh_set_ra_si (ra));
9094 ;; Clobber the return address on the stack. We can't expand this
9095 ;; until we know where it will be put in the stack frame.
9097 (define_insn "eh_set_ra_si"
9098 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9099 (clobber (match_scratch:SI 1 "=&r"))]
9100 "! TARGET_SHMEDIA64"
9103 (define_insn "eh_set_ra_di"
9104 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9105 (clobber (match_scratch:DI 1 "=&r"))]
9110 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9111 (clobber (match_scratch 1 ""))]
9116 sh_set_return_address (operands[0], operands[1]);
9120 (define_insn "blockage"
9121 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9124 [(set_attr "length" "0")])
9126 ;; ------------------------------------------------------------------------
9128 ;; ------------------------------------------------------------------------
9131 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9132 (eq:SI (reg:SI T_REG) (const_int 1)))]
9135 [(set_attr "type" "arith")])
9137 (define_expand "seq"
9138 [(set (match_operand:SI 0 "arith_reg_dest" "")
9147 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9148 if (sh_compare_op1 != const0_rtx)
9149 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9150 ? GET_MODE (sh_compare_op0)
9151 : GET_MODE (sh_compare_op1),
9153 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9155 if (GET_MODE (operands[0]) != SImode)
9156 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9158 switch (GET_MODE (sh_compare_op0))
9161 emit_insn (gen_cmpeqsi_media (operands[0],
9162 sh_compare_op0, sh_compare_op1));
9166 emit_insn (gen_cmpeqdi_media (operands[0],
9167 sh_compare_op0, sh_compare_op1));
9171 if (! TARGET_SHMEDIA_FPU)
9173 emit_insn (gen_cmpeqsf_media (operands[0],
9174 sh_compare_op0, sh_compare_op1));
9178 if (! TARGET_SHMEDIA_FPU)
9180 emit_insn (gen_cmpeqdf_media (operands[0],
9181 sh_compare_op0, sh_compare_op1));
9191 if (GET_MODE (operands[0]) != SImode)
9192 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9193 : gen_reg_rtx (SImode);
9195 switch (GET_MODE (sh_compare_op0))
9198 emit_insn (gen_cmpeqsi_media (reg,
9199 sh_compare_op0, sh_compare_op1));
9203 emit_insn (gen_cmpeqdi_media (reg,
9204 sh_compare_op0, sh_compare_op1));
9208 if (! TARGET_SHMEDIA_FPU)
9210 emit_insn (gen_cmpeqsf_media (reg,
9211 sh_compare_op0, sh_compare_op1));
9215 if (! TARGET_SHMEDIA_FPU)
9217 emit_insn (gen_cmpeqdf_media (reg,
9218 sh_compare_op0, sh_compare_op1));
9225 if (GET_MODE (operands[0]) == DImode)
9226 emit_insn (gen_extendsidi2 (operands[0], reg));
9230 if (sh_expand_t_scc (EQ, operands[0]))
9232 if (! currently_expanding_to_rtl)
9234 operands[1] = prepare_scc_operands (EQ);
9237 (define_expand "slt"
9238 [(set (match_operand:SI 0 "arith_reg_operand" "")
9247 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9248 if (sh_compare_op1 != const0_rtx)
9249 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9250 ? GET_MODE (sh_compare_op0)
9251 : GET_MODE (sh_compare_op1),
9255 if (GET_MODE (operands[0]) != SImode)
9256 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9257 : gen_reg_rtx (SImode);
9259 switch (GET_MODE (sh_compare_op0))
9262 emit_insn (gen_cmpgtsi_media (reg,
9263 sh_compare_op1, sh_compare_op0));
9267 emit_insn (gen_cmpgtdi_media (reg,
9268 sh_compare_op1, sh_compare_op0));
9272 if (! TARGET_SHMEDIA_FPU)
9274 emit_insn (gen_cmpgtsf_media (reg,
9275 sh_compare_op1, sh_compare_op0));
9279 if (! TARGET_SHMEDIA_FPU)
9281 emit_insn (gen_cmpgtdf_media (reg,
9282 sh_compare_op1, sh_compare_op0));
9289 if (GET_MODE (operands[0]) == DImode)
9290 emit_insn (gen_extendsidi2 (operands[0], reg));
9294 if (! currently_expanding_to_rtl)
9296 operands[1] = prepare_scc_operands (LT);
9299 (define_expand "sle"
9300 [(match_operand:SI 0 "arith_reg_operand" "")]
9304 rtx tmp = sh_compare_op0;
9310 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9311 if (sh_compare_op1 != const0_rtx)
9312 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9313 ? GET_MODE (sh_compare_op0)
9314 : GET_MODE (sh_compare_op1),
9318 if (GET_MODE (operands[0]) != SImode)
9319 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9320 : gen_reg_rtx (SImode);
9322 switch (GET_MODE (sh_compare_op0))
9326 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9328 emit_insn (gen_cmpgtsi_media (tmp,
9329 sh_compare_op0, sh_compare_op1));
9330 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9336 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9338 emit_insn (gen_cmpgtdi_media (tmp,
9339 sh_compare_op0, sh_compare_op1));
9340 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9345 if (! TARGET_SHMEDIA_FPU)
9347 emit_insn (gen_cmpgesf_media (reg,
9348 sh_compare_op1, sh_compare_op0));
9352 if (! TARGET_SHMEDIA_FPU)
9354 emit_insn (gen_cmpgedf_media (reg,
9355 sh_compare_op1, sh_compare_op0));
9362 if (GET_MODE (operands[0]) == DImode)
9363 emit_insn (gen_extendsidi2 (operands[0], reg));
9368 sh_compare_op0 = sh_compare_op1;
9369 sh_compare_op1 = tmp;
9370 emit_insn (gen_sge (operands[0]));
9374 (define_expand "sgt"
9375 [(set (match_operand:SI 0 "arith_reg_operand" "")
9385 if (GET_MODE (operands[0]) != SImode)
9386 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9387 : gen_reg_rtx (SImode);
9388 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9389 if (sh_compare_op1 != const0_rtx)
9390 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9391 ? GET_MODE (sh_compare_op0)
9392 : GET_MODE (sh_compare_op1),
9395 switch (GET_MODE (sh_compare_op0))
9398 emit_insn (gen_cmpgtsi_media (reg,
9399 sh_compare_op0, sh_compare_op1));
9403 emit_insn (gen_cmpgtdi_media (reg,
9404 sh_compare_op0, sh_compare_op1));
9408 if (! TARGET_SHMEDIA_FPU)
9410 emit_insn (gen_cmpgtsf_media (reg,
9411 sh_compare_op0, sh_compare_op1));
9415 if (! TARGET_SHMEDIA_FPU)
9417 emit_insn (gen_cmpgtdf_media (reg,
9418 sh_compare_op0, sh_compare_op1));
9425 if (GET_MODE (operands[0]) == DImode)
9426 emit_insn (gen_extendsidi2 (operands[0], reg));
9430 if (! currently_expanding_to_rtl)
9432 operands[1] = prepare_scc_operands (GT);
9435 (define_expand "sge"
9436 [(set (match_operand:SI 0 "arith_reg_operand" "")
9444 enum machine_mode mode = GET_MODE (sh_compare_op0);
9446 if ((mode) == VOIDmode)
9447 mode = GET_MODE (sh_compare_op1);
9449 if (GET_MODE (operands[0]) != SImode)
9450 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9451 : gen_reg_rtx (SImode);
9452 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9453 if (sh_compare_op1 != const0_rtx)
9454 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9460 rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9462 emit_insn (gen_cmpgtsi_media (tmp,
9463 sh_compare_op1, sh_compare_op0));
9464 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9470 rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9472 emit_insn (gen_cmpgtdi_media (tmp,
9473 sh_compare_op1, sh_compare_op0));
9474 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9479 if (! TARGET_SHMEDIA_FPU)
9481 emit_insn (gen_cmpgesf_media (reg,
9482 sh_compare_op0, sh_compare_op1));
9486 if (! TARGET_SHMEDIA_FPU)
9488 emit_insn (gen_cmpgedf_media (reg,
9489 sh_compare_op0, sh_compare_op1));
9496 if (GET_MODE (operands[0]) == DImode)
9497 emit_insn (gen_extendsidi2 (operands[0], reg));
9502 if (! currently_expanding_to_rtl)
9504 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9508 rtx lab = gen_label_rtx ();
9509 prepare_scc_operands (EQ);
9510 emit_jump_insn (gen_branch_true (lab));
9511 prepare_scc_operands (GT);
9513 emit_insn (gen_movt (operands[0]));
9516 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9519 operands[1] = prepare_scc_operands (GE);
9522 (define_expand "sgtu"
9523 [(set (match_operand:SI 0 "arith_reg_operand" "")
9533 if (GET_MODE (operands[0]) == DImode)
9534 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9535 : gen_reg_rtx (SImode);
9536 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9537 if (sh_compare_op1 != const0_rtx)
9538 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9539 ? GET_MODE (sh_compare_op0)
9540 : GET_MODE (sh_compare_op1),
9543 emit_insn (gen_cmpgtudi_media (reg,
9544 sh_compare_op0, sh_compare_op1));
9545 if (GET_MODE (operands[0]) == DImode)
9546 emit_insn (gen_extendsidi2 (operands[0], reg));
9550 if (! currently_expanding_to_rtl)
9552 operands[1] = prepare_scc_operands (GTU);
9555 (define_expand "sltu"
9556 [(set (match_operand:SI 0 "arith_reg_operand" "")
9566 if (GET_MODE (operands[0]) == DImode)
9567 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9568 : gen_reg_rtx (SImode);
9569 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9570 if (sh_compare_op1 != const0_rtx)
9571 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9572 ? GET_MODE (sh_compare_op0)
9573 : GET_MODE (sh_compare_op1),
9576 emit_insn (gen_cmpgtudi_media (reg,
9577 sh_compare_op1, sh_compare_op0));
9578 if (GET_MODE (operands[0]) == DImode)
9579 emit_insn (gen_extendsidi2 (operands[0], reg));
9583 if (! currently_expanding_to_rtl)
9585 operands[1] = prepare_scc_operands (LTU);
9588 (define_expand "sleu"
9589 [(set (match_operand:SI 0 "arith_reg_operand" "")
9599 if (GET_MODE (operands[0]) != SImode)
9600 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9601 : gen_reg_rtx (SImode);
9602 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9603 if (sh_compare_op1 != const0_rtx)
9604 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9605 ? GET_MODE (sh_compare_op0)
9606 : GET_MODE (sh_compare_op1),
9609 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9611 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9612 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9613 if (GET_MODE (operands[0]) == DImode)
9614 emit_insn (gen_extendsidi2 (operands[0], reg));
9618 if (! currently_expanding_to_rtl)
9620 operands[1] = prepare_scc_operands (LEU);
9623 (define_expand "sgeu"
9624 [(set (match_operand:SI 0 "arith_reg_operand" "")
9634 if (GET_MODE (operands[0]) != SImode)
9635 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9636 : gen_reg_rtx (SImode);
9637 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9638 if (sh_compare_op1 != const0_rtx)
9639 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9640 ? GET_MODE (sh_compare_op0)
9641 : GET_MODE (sh_compare_op1),
9644 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9646 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9647 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9648 if (GET_MODE (operands[0]) == DImode)
9649 emit_insn (gen_extendsidi2 (operands[0], reg));
9654 if (! currently_expanding_to_rtl)
9656 operands[1] = prepare_scc_operands (GEU);
9659 ;; sne moves the complement of the T reg to DEST like this:
9663 ;; This is better than xoring compare result with 1 because it does
9664 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9667 (define_expand "sne"
9668 [(set (match_dup 2) (const_int -1))
9669 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9670 (neg:SI (plus:SI (match_dup 1)
9673 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9683 if (GET_MODE (operands[0]) != SImode)
9684 reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9685 : gen_reg_rtx (SImode);
9686 if (! TARGET_SHMEDIA_FPU
9687 && GET_MODE (sh_compare_op0) != DImode
9688 && GET_MODE (sh_compare_op0) != SImode)
9691 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9692 if (sh_compare_op1 != const0_rtx)
9693 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9694 ? GET_MODE (sh_compare_op0)
9695 : GET_MODE (sh_compare_op1),
9698 tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9700 emit_insn (gen_seq (tmp));
9701 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9702 if (GET_MODE (operands[0]) == DImode)
9703 emit_insn (gen_extendsidi2 (operands[0], reg));
9708 if (sh_expand_t_scc (NE, operands[0]))
9710 if (! currently_expanding_to_rtl)
9712 operands[1] = prepare_scc_operands (EQ);
9713 operands[2] = gen_reg_rtx (SImode);
9716 (define_expand "sunordered"
9717 [(set (match_operand:SI 0 "arith_reg_operand" "")
9718 (unordered:SI (match_dup 1) (match_dup 2)))]
9719 "TARGET_SHMEDIA_FPU"
9722 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9723 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9726 ;; Use the same trick for FP sle / sge
9728 ;; Apart from the constant use and the T setting, this is like movt,
9729 ;; except that it uses the logically negated value of T, i.e.
9730 ;; operand[0] := T ? 0 : 1.
9731 (define_expand "movnegt"
9732 [(set (match_dup 2) (const_int -1))
9733 (parallel [(set (match_operand 0 "" "")
9734 (neg:SI (plus:SI (match_dup 1)
9737 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9740 "operands[2] = gen_reg_rtx (SImode);")
9742 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9743 ;; This prevents a regression that occurred when we switched from xor to
9747 [(set (match_operand:SI 0 "arith_reg_dest" "")
9748 (plus:SI (reg:SI T_REG)
9751 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9752 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9755 ;; -------------------------------------------------------------------------
9756 ;; Instructions to cope with inline literal tables
9757 ;; -------------------------------------------------------------------------
9759 ; 2 byte integer in line
9761 (define_insn "consttable_2"
9762 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9763 (match_operand 1 "" "")]
9768 if (operands[1] != const0_rtx)
9769 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9772 [(set_attr "length" "2")
9773 (set_attr "in_delay_slot" "no")])
9775 ; 4 byte integer in line
9777 (define_insn "consttable_4"
9778 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9779 (match_operand 1 "" "")]
9784 if (operands[1] != const0_rtx)
9785 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9788 [(set_attr "length" "4")
9789 (set_attr "in_delay_slot" "no")])
9791 ; 8 byte integer in line
9793 (define_insn "consttable_8"
9794 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9795 (match_operand 1 "" "")]
9800 if (operands[1] != const0_rtx)
9801 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9804 [(set_attr "length" "8")
9805 (set_attr "in_delay_slot" "no")])
9807 ; 4 byte floating point
9809 (define_insn "consttable_sf"
9810 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9811 (match_operand 1 "" "")]
9816 if (operands[1] != const0_rtx)
9819 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9820 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9824 [(set_attr "length" "4")
9825 (set_attr "in_delay_slot" "no")])
9827 ; 8 byte floating point
9829 (define_insn "consttable_df"
9830 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9831 (match_operand 1 "" "")]
9836 if (operands[1] != const0_rtx)
9839 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9840 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9844 [(set_attr "length" "8")
9845 (set_attr "in_delay_slot" "no")])
9847 ;; Alignment is needed for some constant tables; it may also be added for
9848 ;; Instructions at the start of loops, or after unconditional branches.
9849 ;; ??? We would get more accurate lengths if we did instruction
9850 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9851 ;; here is too conservative.
9853 ; align to a two byte boundary
9855 (define_expand "align_2"
9856 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9860 ; align to a four byte boundary
9861 ;; align_4 and align_log are instructions for the starts of loops, or
9862 ;; after unconditional branches, which may take up extra room.
9864 (define_expand "align_4"
9865 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9869 ; align to a cache line boundary
9871 (define_insn "align_log"
9872 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9875 [(set_attr "length" "0")
9876 (set_attr "in_delay_slot" "no")])
9878 ; emitted at the end of the literal table, used to emit the
9879 ; 32bit branch labels if needed.
9881 (define_insn "consttable_end"
9882 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9884 "* return output_jump_label_table ();"
9885 [(set_attr "in_delay_slot" "no")])
9887 ; emitted at the end of the window in the literal table.
9889 (define_insn "consttable_window_end"
9890 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9893 [(set_attr "length" "0")
9894 (set_attr "in_delay_slot" "no")])
9896 ;; -------------------------------------------------------------------------
9898 ;; -------------------------------------------------------------------------
9900 ;; String/block move insn.
9902 (define_expand "movmemsi"
9903 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9904 (mem:BLK (match_operand:BLK 1 "" "")))
9905 (use (match_operand:SI 2 "nonmemory_operand" ""))
9906 (use (match_operand:SI 3 "immediate_operand" ""))
9907 (clobber (reg:SI PR_REG))
9908 (clobber (reg:SI R4_REG))
9909 (clobber (reg:SI R5_REG))
9910 (clobber (reg:SI R0_REG))])]
9911 "TARGET_SH1 && ! TARGET_SH5"
9914 if(expand_block_move (operands))
9919 (define_insn "block_move_real"
9920 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9921 (mem:BLK (reg:SI R5_REG)))
9922 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9923 (clobber (reg:SI PR_REG))
9924 (clobber (reg:SI R0_REG))])]
9925 "TARGET_SH1 && ! TARGET_HARD_SH4"
9927 [(set_attr "type" "sfunc")
9928 (set_attr "needs_delay_slot" "yes")])
9930 (define_insn "block_lump_real"
9931 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9932 (mem:BLK (reg:SI R5_REG)))
9933 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9934 (use (reg:SI R6_REG))
9935 (clobber (reg:SI PR_REG))
9936 (clobber (reg:SI T_REG))
9937 (clobber (reg:SI R4_REG))
9938 (clobber (reg:SI R5_REG))
9939 (clobber (reg:SI R6_REG))
9940 (clobber (reg:SI R0_REG))])]
9941 "TARGET_SH1 && ! TARGET_HARD_SH4"
9943 [(set_attr "type" "sfunc")
9944 (set_attr "needs_delay_slot" "yes")])
9946 (define_insn "block_move_real_i4"
9947 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9948 (mem:BLK (reg:SI R5_REG)))
9949 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9950 (clobber (reg:SI PR_REG))
9951 (clobber (reg:SI R0_REG))
9952 (clobber (reg:SI R1_REG))
9953 (clobber (reg:SI R2_REG))])]
9956 [(set_attr "type" "sfunc")
9957 (set_attr "needs_delay_slot" "yes")])
9959 (define_insn "block_lump_real_i4"
9960 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9961 (mem:BLK (reg:SI R5_REG)))
9962 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9963 (use (reg:SI R6_REG))
9964 (clobber (reg:SI PR_REG))
9965 (clobber (reg:SI T_REG))
9966 (clobber (reg:SI R4_REG))
9967 (clobber (reg:SI R5_REG))
9968 (clobber (reg:SI R6_REG))
9969 (clobber (reg:SI R0_REG))
9970 (clobber (reg:SI R1_REG))
9971 (clobber (reg:SI R2_REG))
9972 (clobber (reg:SI R3_REG))])]
9975 [(set_attr "type" "sfunc")
9976 (set_attr "needs_delay_slot" "yes")])
9978 ;; -------------------------------------------------------------------------
9979 ;; Floating point instructions.
9980 ;; -------------------------------------------------------------------------
9982 ;; ??? All patterns should have a type attribute.
9984 (define_expand "movpsi"
9985 [(set (match_operand:PSI 0 "register_operand" "")
9986 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9987 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9990 ;; The c / m alternative is a fake to guide reload to load directly into
9991 ;; fpscr, since reload doesn't know how to use post-increment.
9992 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9993 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9994 ;; predicate after reload.
9995 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9996 ;; like a mac -> gpr move.
9997 (define_insn "fpu_switch"
9998 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9999 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10001 && (! reload_completed
10002 || true_regnum (operands[0]) != FPSCR_REG
10003 || GET_CODE (operands[1]) != MEM
10004 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10006 ! precision stays the same
10015 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10016 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10019 [(set (reg:PSI FPSCR_REG)
10020 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10021 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10024 rtx fpscr, mem, new_insn;
10026 fpscr = SET_DEST (PATTERN (curr_insn));
10027 mem = SET_SRC (PATTERN (curr_insn));
10028 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10030 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10031 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10036 [(set (reg:PSI FPSCR_REG)
10037 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10038 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10039 && (flag_peephole2 ? flow2_completed : reload_completed)"
10042 rtx fpscr, mem, new_insn;
10044 fpscr = SET_DEST (PATTERN (curr_insn));
10045 mem = SET_SRC (PATTERN (curr_insn));
10046 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10048 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10049 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10051 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10052 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10056 ;; ??? This uses the fp unit, but has no type indicating that.
10057 ;; If we did that, this would either give a bogus latency or introduce
10058 ;; a bogus FIFO constraint.
10059 ;; Since this insn is currently only used for prologues/epilogues,
10060 ;; it is probably best to claim no function unit, which matches the
10061 ;; current setting.
10062 (define_insn "toggle_sz"
10063 [(set (reg:PSI FPSCR_REG)
10064 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10065 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10067 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10069 ;; There's no way we can use it today, since optimize mode switching
10070 ;; doesn't enable us to know from which mode we're switching to the
10071 ;; mode it requests, to tell whether we can use a relative mode switch
10072 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10074 (define_insn "toggle_pr"
10075 [(set (reg:PSI FPSCR_REG)
10076 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10077 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10079 [(set_attr "type" "fpscr_toggle")])
10081 (define_expand "addsf3"
10082 [(set (match_operand:SF 0 "arith_reg_operand" "")
10083 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10084 (match_operand:SF 2 "arith_reg_operand" "")))]
10085 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10090 expand_sf_binop (&gen_addsf3_i, operands);
10095 (define_insn "*addsf3_media"
10096 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10097 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10098 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10099 "TARGET_SHMEDIA_FPU"
10100 "fadd.s %1, %2, %0"
10101 [(set_attr "type" "fparith_media")])
10103 (define_insn_and_split "unary_sf_op"
10104 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10109 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10110 (match_operator:SF 2 "unary_float_operator"
10111 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10112 (parallel [(match_operand 4
10113 "const_int_operand" "n")]))]))
10114 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10115 "TARGET_SHMEDIA_FPU"
10117 "TARGET_SHMEDIA_FPU && reload_completed"
10118 [(set (match_dup 5) (match_dup 6))]
10121 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10122 rtx op1 = gen_rtx_REG (SFmode,
10123 (true_regnum (operands[1])
10124 + (INTVAL (operands[4]) ^ endian)));
10126 operands[7] = gen_rtx_REG (SFmode,
10127 (true_regnum (operands[0])
10128 + (INTVAL (operands[3]) ^ endian)));
10129 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10131 [(set_attr "type" "fparith_media")])
10133 (define_insn_and_split "binary_sf_op"
10134 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10139 (parallel [(match_operand 7 "const_int_operand" "n")]))
10140 (match_operator:SF 3 "binary_float_operator"
10141 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10142 (parallel [(match_operand 5
10143 "const_int_operand" "n")]))
10144 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10145 (parallel [(match_operand 6
10146 "const_int_operand" "n")]))]))
10147 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10148 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10150 "&& reload_completed"
10151 [(set (match_dup 8) (match_dup 9))]
10154 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10155 rtx op1 = gen_rtx_REG (SFmode,
10156 (true_regnum (operands[1])
10157 + (INTVAL (operands[5]) ^ endian)));
10158 rtx op2 = gen_rtx_REG (SFmode,
10159 (true_regnum (operands[2])
10160 + (INTVAL (operands[6]) ^ endian)));
10162 operands[8] = gen_rtx_REG (SFmode,
10163 (true_regnum (operands[0])
10164 + (INTVAL (operands[4]) ^ endian)));
10165 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10167 [(set_attr "type" "fparith_media")])
10169 (define_insn "addsf3_i"
10170 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10171 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10172 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10173 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10176 [(set_attr "type" "fp")
10177 (set_attr "fp_mode" "single")])
10179 (define_expand "subsf3"
10180 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10181 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10182 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10183 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10188 expand_sf_binop (&gen_subsf3_i, operands);
10193 (define_insn "*subsf3_media"
10194 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10195 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10196 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10197 "TARGET_SHMEDIA_FPU"
10198 "fsub.s %1, %2, %0"
10199 [(set_attr "type" "fparith_media")])
10201 (define_insn "subsf3_i"
10202 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10203 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10204 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10205 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10208 [(set_attr "type" "fp")
10209 (set_attr "fp_mode" "single")])
10211 (define_expand "mulsf3"
10212 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10213 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10214 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10215 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10218 (define_insn "*mulsf3_media"
10219 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10220 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10221 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10222 "TARGET_SHMEDIA_FPU"
10223 "fmul.s %1, %2, %0"
10224 [(set_attr "type" "fparith_media")])
10226 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10227 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10228 ;; we start out with a mulsf pattern that does not depend on fpscr.
10229 ;; This is split after combine to introduce the dependency, in order to
10230 ;; get mode switching and scheduling right.
10231 (define_insn_and_split "mulsf3_ie"
10232 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10233 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10234 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10237 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10241 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10242 get_fpscr_rtx ()));
10245 [(set_attr "type" "fp")])
10247 (define_insn "mulsf3_i4"
10248 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10249 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10250 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10251 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10254 [(set_attr "type" "fp")
10255 (set_attr "fp_mode" "single")])
10257 (define_insn "mac_media"
10258 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10259 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10260 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10261 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10262 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10263 "fmac.s %1, %2, %0"
10264 [(set_attr "type" "fparith_media")])
10266 (define_insn "*macsf3"
10267 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10268 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10269 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10270 (match_operand:SF 3 "arith_reg_operand" "0")))
10271 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10272 "TARGET_SH2E && TARGET_FMAC"
10274 [(set_attr "type" "fp")
10275 (set_attr "fp_mode" "single")])
10277 (define_expand "divsf3"
10278 [(set (match_operand:SF 0 "arith_reg_operand" "")
10279 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10280 (match_operand:SF 2 "arith_reg_operand" "")))]
10281 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10286 expand_sf_binop (&gen_divsf3_i, operands);
10291 (define_insn "*divsf3_media"
10292 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10293 (div: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 "fdiv.s %1, %2, %0"
10297 [(set_attr "type" "fdiv_media")])
10299 (define_insn "divsf3_i"
10300 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10301 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10302 (match_operand:SF 2 "arith_reg_operand" "f")))
10303 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10306 [(set_attr "type" "fdiv")
10307 (set_attr "fp_mode" "single")])
10309 (define_insn "floatdisf2"
10310 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10311 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10312 "TARGET_SHMEDIA_FPU"
10314 [(set_attr "type" "fpconv_media")])
10316 (define_expand "floatsisf2"
10317 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10318 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10319 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10322 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10324 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10329 (define_insn "*floatsisf2_media"
10330 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10331 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10332 "TARGET_SHMEDIA_FPU"
10334 [(set_attr "type" "fpconv_media")])
10336 (define_insn "floatsisf2_i4"
10337 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10338 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10339 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10340 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10342 [(set_attr "type" "fp")
10343 (set_attr "fp_mode" "single")])
10345 (define_insn "*floatsisf2_ie"
10346 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10347 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10348 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10350 [(set_attr "type" "fp")])
10352 (define_insn "fix_truncsfdi2"
10353 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10354 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10355 "TARGET_SHMEDIA_FPU"
10357 [(set_attr "type" "fpconv_media")])
10359 (define_expand "fix_truncsfsi2"
10360 [(set (match_operand:SI 0 "fpul_operand" "=y")
10361 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10362 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10365 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10367 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10372 (define_insn "*fix_truncsfsi2_media"
10373 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10374 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10375 "TARGET_SHMEDIA_FPU"
10377 [(set_attr "type" "fpconv_media")])
10379 (define_insn "fix_truncsfsi2_i4"
10380 [(set (match_operand:SI 0 "fpul_operand" "=y")
10381 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10382 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10383 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10385 [(set_attr "type" "ftrc_s")
10386 (set_attr "fp_mode" "single")])
10388 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10389 ;; fix_truncsfsi2_i4.
10390 ;; (define_insn "fix_truncsfsi2_i4_2"
10391 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10392 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10393 ;; (use (reg:PSI FPSCR_REG))
10394 ;; (clobber (reg:SI FPUL_REG))]
10397 ;; [(set_attr "length" "4")
10398 ;; (set_attr "fp_mode" "single")])
10401 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10402 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10403 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10404 ;; (clobber (reg:SI FPUL_REG))]
10406 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10407 ;; (use (match_dup 2))])
10408 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10410 (define_insn "*fixsfsi"
10411 [(set (match_operand:SI 0 "fpul_operand" "=y")
10412 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10413 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10415 [(set_attr "type" "fp")])
10417 (define_insn "cmpgtsf_t"
10418 [(set (reg:SI T_REG)
10419 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10420 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10421 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10423 [(set_attr "type" "fp_cmp")
10424 (set_attr "fp_mode" "single")])
10426 (define_insn "cmpeqsf_t"
10427 [(set (reg:SI T_REG)
10428 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10429 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10430 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10432 [(set_attr "type" "fp_cmp")
10433 (set_attr "fp_mode" "single")])
10435 (define_insn "ieee_ccmpeqsf_t"
10436 [(set (reg:SI T_REG)
10437 (ior:SI (reg:SI T_REG)
10438 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10439 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10440 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10441 "* return output_ieee_ccmpeq (insn, operands);"
10442 [(set_attr "length" "4")])
10445 (define_insn "cmpgtsf_t_i4"
10446 [(set (reg:SI T_REG)
10447 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10448 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10449 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10450 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10452 [(set_attr "type" "fp_cmp")
10453 (set_attr "fp_mode" "single")])
10455 (define_insn "cmpeqsf_t_i4"
10456 [(set (reg:SI T_REG)
10457 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10458 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10459 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10460 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10462 [(set_attr "type" "fp_cmp")
10463 (set_attr "fp_mode" "single")])
10465 (define_insn "*ieee_ccmpeqsf_t_4"
10466 [(set (reg:SI T_REG)
10467 (ior:SI (reg:SI T_REG)
10468 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10469 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10470 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10471 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10472 "* return output_ieee_ccmpeq (insn, operands);"
10473 [(set_attr "length" "4")
10474 (set_attr "fp_mode" "single")])
10476 (define_insn "cmpeqsf_media"
10477 [(set (match_operand:SI 0 "register_operand" "=r")
10478 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10479 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10480 "TARGET_SHMEDIA_FPU"
10481 "fcmpeq.s %1, %2, %0"
10482 [(set_attr "type" "fcmp_media")])
10484 (define_insn "cmpgtsf_media"
10485 [(set (match_operand:SI 0 "register_operand" "=r")
10486 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10487 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10488 "TARGET_SHMEDIA_FPU"
10489 "fcmpgt.s %1, %2, %0"
10490 [(set_attr "type" "fcmp_media")])
10492 (define_insn "cmpgesf_media"
10493 [(set (match_operand:SI 0 "register_operand" "=r")
10494 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10495 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10496 "TARGET_SHMEDIA_FPU"
10497 "fcmpge.s %1, %2, %0"
10498 [(set_attr "type" "fcmp_media")])
10500 (define_insn "cmpunsf_media"
10501 [(set (match_operand:SI 0 "register_operand" "=r")
10502 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10503 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10504 "TARGET_SHMEDIA_FPU"
10505 "fcmpun.s %1, %2, %0"
10506 [(set_attr "type" "fcmp_media")])
10508 (define_expand "cmpsf"
10509 [(set (reg:SI T_REG)
10510 (compare (match_operand:SF 0 "arith_operand" "")
10511 (match_operand:SF 1 "arith_operand" "")))]
10512 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10515 sh_compare_op0 = operands[0];
10516 sh_compare_op1 = operands[1];
10520 (define_expand "negsf2"
10521 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10522 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10523 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10528 expand_sf_unop (&gen_negsf2_i, operands);
10533 (define_insn "*negsf2_media"
10534 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10535 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10536 "TARGET_SHMEDIA_FPU"
10538 [(set_attr "type" "fmove_media")])
10540 (define_insn "negsf2_i"
10541 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10542 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10543 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10546 [(set_attr "type" "fmove")
10547 (set_attr "fp_mode" "single")])
10549 (define_expand "sqrtsf2"
10550 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10551 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10552 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10557 expand_sf_unop (&gen_sqrtsf2_i, operands);
10562 (define_insn "*sqrtsf2_media"
10563 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10564 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10565 "TARGET_SHMEDIA_FPU"
10567 [(set_attr "type" "fdiv_media")])
10569 (define_insn "sqrtsf2_i"
10570 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10571 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10572 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10575 [(set_attr "type" "fdiv")
10576 (set_attr "fp_mode" "single")])
10578 (define_insn "rsqrtsf2"
10579 [(set (match_operand:SF 0 "register_operand" "=f")
10580 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10581 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10582 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10583 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10584 && operands[1] == CONST1_RTX (SFmode)"
10586 [(set_attr "type" "fsrra")
10587 (set_attr "fp_mode" "single")])
10589 (define_insn "fsca"
10590 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10592 (unspec:SF [(mult:SF
10593 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10594 (match_operand:SF 2 "immediate_operand" "i"))
10596 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10598 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10599 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10600 && operands[2] == sh_fsca_int2sf ()"
10602 [(set_attr "type" "fsca")
10603 (set_attr "fp_mode" "single")])
10605 (define_expand "sinsf2"
10606 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10607 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10609 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10612 rtx scaled = gen_reg_rtx (SFmode);
10613 rtx truncated = gen_reg_rtx (SImode);
10614 rtx fsca = gen_reg_rtx (V2SFmode);
10615 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10617 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10618 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10619 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10620 get_fpscr_rtx ()));
10621 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10625 (define_expand "cossf2"
10626 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10627 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10629 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10632 rtx scaled = gen_reg_rtx (SFmode);
10633 rtx truncated = gen_reg_rtx (SImode);
10634 rtx fsca = gen_reg_rtx (V2SFmode);
10635 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10637 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10638 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10639 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10640 get_fpscr_rtx ()));
10641 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10645 (define_expand "sindf2"
10646 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10647 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10649 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10652 rtx scaled = gen_reg_rtx (DFmode);
10653 rtx truncated = gen_reg_rtx (SImode);
10654 rtx fsca = gen_reg_rtx (V2SFmode);
10655 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10656 rtx sfresult = gen_reg_rtx (SFmode);
10658 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10659 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10660 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10661 get_fpscr_rtx ()));
10662 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10663 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10667 (define_expand "cosdf2"
10668 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10669 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10671 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10674 rtx scaled = gen_reg_rtx (DFmode);
10675 rtx truncated = gen_reg_rtx (SImode);
10676 rtx fsca = gen_reg_rtx (V2SFmode);
10677 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10678 rtx sfresult = gen_reg_rtx (SFmode);
10680 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10681 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10682 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10683 get_fpscr_rtx ()));
10684 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10685 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10689 (define_expand "abssf2"
10690 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10691 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10692 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10697 expand_sf_unop (&gen_abssf2_i, operands);
10702 (define_insn "*abssf2_media"
10703 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10704 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10705 "TARGET_SHMEDIA_FPU"
10707 [(set_attr "type" "fmove_media")])
10709 (define_insn "abssf2_i"
10710 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10711 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10715 [(set_attr "type" "fmove")
10716 (set_attr "fp_mode" "single")])
10718 (define_expand "adddf3"
10719 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10720 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10721 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10722 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10725 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10727 expand_df_binop (&gen_adddf3_i, operands);
10732 (define_insn "*adddf3_media"
10733 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10734 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10735 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10736 "TARGET_SHMEDIA_FPU"
10737 "fadd.d %1, %2, %0"
10738 [(set_attr "type" "dfparith_media")])
10740 (define_insn "adddf3_i"
10741 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10742 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10743 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10744 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10745 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10747 [(set_attr "type" "dfp_arith")
10748 (set_attr "fp_mode" "double")])
10750 (define_expand "subdf3"
10751 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10752 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10753 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10754 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10757 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10759 expand_df_binop (&gen_subdf3_i, operands);
10764 (define_insn "*subdf3_media"
10765 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10766 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10767 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10768 "TARGET_SHMEDIA_FPU"
10769 "fsub.d %1, %2, %0"
10770 [(set_attr "type" "dfparith_media")])
10772 (define_insn "subdf3_i"
10773 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10774 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10775 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10776 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10777 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10779 [(set_attr "type" "dfp_arith")
10780 (set_attr "fp_mode" "double")])
10782 (define_expand "muldf3"
10783 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10784 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10785 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10786 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10789 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10791 expand_df_binop (&gen_muldf3_i, operands);
10796 (define_insn "*muldf3_media"
10797 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10798 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10799 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10800 "TARGET_SHMEDIA_FPU"
10801 "fmul.d %1, %2, %0"
10802 [(set_attr "type" "dfmul_media")])
10804 (define_insn "muldf3_i"
10805 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10806 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10807 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10808 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10809 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10811 [(set_attr "type" "dfp_mul")
10812 (set_attr "fp_mode" "double")])
10814 (define_expand "divdf3"
10815 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10816 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10817 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10818 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10821 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10823 expand_df_binop (&gen_divdf3_i, operands);
10828 (define_insn "*divdf3_media"
10829 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10830 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10831 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10832 "TARGET_SHMEDIA_FPU"
10833 "fdiv.d %1, %2, %0"
10834 [(set_attr "type" "dfdiv_media")])
10836 (define_insn "divdf3_i"
10837 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10838 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10839 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10840 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10841 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10843 [(set_attr "type" "dfdiv")
10844 (set_attr "fp_mode" "double")])
10846 (define_insn "floatdidf2"
10847 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10848 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10849 "TARGET_SHMEDIA_FPU"
10851 [(set_attr "type" "dfpconv_media")])
10853 (define_expand "floatsidf2"
10854 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10855 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10856 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10859 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10861 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10862 get_fpscr_rtx ()));
10867 (define_insn "*floatsidf2_media"
10868 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10869 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10870 "TARGET_SHMEDIA_FPU"
10872 [(set_attr "type" "dfpconv_media")])
10874 (define_insn "floatsidf2_i"
10875 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10876 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10877 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10878 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10880 [(set_attr "type" "dfp_conv")
10881 (set_attr "fp_mode" "double")])
10883 (define_insn "fix_truncdfdi2"
10884 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10885 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10886 "TARGET_SHMEDIA_FPU"
10888 [(set_attr "type" "dfpconv_media")])
10890 (define_expand "fix_truncdfsi2"
10891 [(set (match_operand:SI 0 "fpul_operand" "")
10892 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10893 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10896 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10898 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10899 get_fpscr_rtx ()));
10904 (define_insn "*fix_truncdfsi2_media"
10905 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10906 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10907 "TARGET_SHMEDIA_FPU"
10909 [(set_attr "type" "dfpconv_media")])
10911 (define_insn "fix_truncdfsi2_i"
10912 [(set (match_operand:SI 0 "fpul_operand" "=y")
10913 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10914 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10917 [(set_attr "type" "dfp_conv")
10918 (set_attr "dfp_comp" "no")
10919 (set_attr "fp_mode" "double")])
10921 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10922 ;; fix_truncdfsi2_i.
10923 ;; (define_insn "fix_truncdfsi2_i4"
10924 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10925 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10926 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10927 ;; (clobber (reg:SI FPUL_REG))]
10930 ;; [(set_attr "length" "4")
10931 ;; (set_attr "fp_mode" "double")])
10934 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10935 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10936 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10937 ;; (clobber (reg:SI FPUL_REG))]
10939 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10940 ;; (use (match_dup 2))])
10941 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10943 (define_insn "cmpgtdf_t"
10944 [(set (reg:SI T_REG)
10945 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10946 (match_operand:DF 1 "arith_reg_operand" "f")))
10947 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10948 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10950 [(set_attr "type" "dfp_cmp")
10951 (set_attr "fp_mode" "double")])
10953 (define_insn "cmpeqdf_t"
10954 [(set (reg:SI T_REG)
10955 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10956 (match_operand:DF 1 "arith_reg_operand" "f")))
10957 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10958 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10960 [(set_attr "type" "dfp_cmp")
10961 (set_attr "fp_mode" "double")])
10963 (define_insn "*ieee_ccmpeqdf_t"
10964 [(set (reg:SI T_REG)
10965 (ior:SI (reg:SI T_REG)
10966 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10967 (match_operand:DF 1 "arith_reg_operand" "f"))))
10968 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10969 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10970 "* return output_ieee_ccmpeq (insn, operands);"
10971 [(set_attr "length" "4")
10972 (set_attr "fp_mode" "double")])
10974 (define_insn "cmpeqdf_media"
10975 [(set (match_operand:SI 0 "register_operand" "=r")
10976 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10977 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10978 "TARGET_SHMEDIA_FPU"
10979 "fcmpeq.d %1,%2,%0"
10980 [(set_attr "type" "fcmp_media")])
10982 (define_insn "cmpgtdf_media"
10983 [(set (match_operand:SI 0 "register_operand" "=r")
10984 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10985 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10986 "TARGET_SHMEDIA_FPU"
10987 "fcmpgt.d %1,%2,%0"
10988 [(set_attr "type" "fcmp_media")])
10990 (define_insn "cmpgedf_media"
10991 [(set (match_operand:SI 0 "register_operand" "=r")
10992 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10993 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10994 "TARGET_SHMEDIA_FPU"
10995 "fcmpge.d %1,%2,%0"
10996 [(set_attr "type" "fcmp_media")])
10998 (define_insn "cmpundf_media"
10999 [(set (match_operand:SI 0 "register_operand" "=r")
11000 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11001 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11002 "TARGET_SHMEDIA_FPU"
11003 "fcmpun.d %1,%2,%0"
11004 [(set_attr "type" "fcmp_media")])
11006 (define_expand "cmpdf"
11007 [(set (reg:SI T_REG)
11008 (compare (match_operand:DF 0 "arith_operand" "")
11009 (match_operand:DF 1 "arith_operand" "")))]
11010 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11013 sh_compare_op0 = operands[0];
11014 sh_compare_op1 = operands[1];
11018 (define_expand "negdf2"
11019 [(set (match_operand:DF 0 "arith_reg_operand" "")
11020 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11021 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11024 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11026 expand_df_unop (&gen_negdf2_i, operands);
11031 (define_insn "*negdf2_media"
11032 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11033 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11034 "TARGET_SHMEDIA_FPU"
11036 [(set_attr "type" "fmove_media")])
11038 (define_insn "negdf2_i"
11039 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11040 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11041 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11042 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11044 [(set_attr "type" "fmove")
11045 (set_attr "fp_mode" "double")])
11047 (define_expand "sqrtdf2"
11048 [(set (match_operand:DF 0 "arith_reg_operand" "")
11049 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11050 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11053 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11055 expand_df_unop (&gen_sqrtdf2_i, operands);
11060 (define_insn "*sqrtdf2_media"
11061 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11062 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11063 "TARGET_SHMEDIA_FPU"
11065 [(set_attr "type" "dfdiv_media")])
11067 (define_insn "sqrtdf2_i"
11068 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11069 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11070 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11071 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11073 [(set_attr "type" "dfdiv")
11074 (set_attr "fp_mode" "double")])
11076 (define_expand "absdf2"
11077 [(set (match_operand:DF 0 "arith_reg_operand" "")
11078 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11079 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11082 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11084 expand_df_unop (&gen_absdf2_i, operands);
11089 (define_insn "*absdf2_media"
11090 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11091 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11092 "TARGET_SHMEDIA_FPU"
11094 [(set_attr "type" "fmove_media")])
11096 (define_insn "absdf2_i"
11097 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11098 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11099 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11100 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11102 [(set_attr "type" "fmove")
11103 (set_attr "fp_mode" "double")])
11105 (define_expand "extendsfdf2"
11106 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11107 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11108 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11111 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11113 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11114 get_fpscr_rtx ()));
11119 (define_insn "*extendsfdf2_media"
11120 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11121 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11122 "TARGET_SHMEDIA_FPU"
11124 [(set_attr "type" "dfpconv_media")])
11126 (define_insn "extendsfdf2_i4"
11127 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11128 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11129 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11130 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11132 [(set_attr "type" "fp")
11133 (set_attr "fp_mode" "double")])
11135 (define_expand "truncdfsf2"
11136 [(set (match_operand:SF 0 "fpul_operand" "")
11137 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11138 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11141 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11143 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11144 get_fpscr_rtx ()));
11149 (define_insn "*truncdfsf2_media"
11150 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11151 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11152 "TARGET_SHMEDIA_FPU"
11154 [(set_attr "type" "dfpconv_media")])
11156 (define_insn "truncdfsf2_i4"
11157 [(set (match_operand:SF 0 "fpul_operand" "=y")
11158 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11159 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11160 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11162 [(set_attr "type" "fp")
11163 (set_attr "fp_mode" "double")])
11165 ;; Bit field extract patterns. These give better code for packed bitfields,
11166 ;; because they allow auto-increment addresses to be generated.
11168 (define_expand "insv"
11169 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11170 (match_operand:SI 1 "immediate_operand" "")
11171 (match_operand:SI 2 "immediate_operand" ""))
11172 (match_operand:SI 3 "general_operand" ""))]
11173 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11176 rtx addr_target, orig_address, shift_reg, qi_val;
11177 HOST_WIDE_INT bitsize, size, v = 0;
11178 rtx x = operands[3];
11180 /* ??? expmed doesn't care for non-register predicates. */
11181 if (! memory_operand (operands[0], VOIDmode)
11182 || ! immediate_operand (operands[1], VOIDmode)
11183 || ! immediate_operand (operands[2], VOIDmode)
11184 || ! general_operand (x, VOIDmode))
11186 /* If this isn't a 16 / 24 / 32 bit field, or if
11187 it doesn't start on a byte boundary, then fail. */
11188 bitsize = INTVAL (operands[1]);
11189 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11190 || (INTVAL (operands[2]) % 8) != 0)
11193 size = bitsize / 8;
11194 orig_address = XEXP (operands[0], 0);
11195 shift_reg = gen_reg_rtx (SImode);
11196 if (GET_CODE (x) == CONST_INT)
11199 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11203 emit_insn (gen_movsi (shift_reg, operands[3]));
11204 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11206 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11208 operands[0] = replace_equiv_address (operands[0], addr_target);
11209 emit_insn (gen_movqi (operands[0], qi_val));
11213 if (GET_CODE (x) == CONST_INT)
11215 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11218 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11219 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11221 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11222 emit_insn (gen_movqi (operands[0], qi_val));
11228 (define_insn "movua"
11229 [(set (match_operand:SI 0 "register_operand" "=z")
11230 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11234 [(set_attr "type" "movua")])
11236 ;; We shouldn't need this, but cse replaces increments with references
11237 ;; to other regs before flow has a chance to create post_inc
11238 ;; addressing modes, and only postreload's cse_move2add brings the
11239 ;; increments back to a usable form.
11241 [(set (match_operand:SI 0 "register_operand" "")
11242 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11243 (const_int 32) (const_int 0)))
11244 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11245 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11246 [(set (match_operand:SI 0 "register_operand" "")
11247 (sign_extract:SI (mem:SI (post_inc:SI
11248 (match_operand:SI 1 "register_operand" "")))
11249 (const_int 32) (const_int 0)))]
11252 (define_expand "extv"
11253 [(set (match_operand:SI 0 "register_operand" "")
11254 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11255 (match_operand 2 "const_int_operand" "")
11256 (match_operand 3 "const_int_operand" "")))]
11259 if (TARGET_SH4A_ARCH
11260 && INTVAL (operands[2]) == 32
11261 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11262 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11264 rtx src = adjust_address (operands[1], BLKmode, 0);
11265 set_mem_size (src, GEN_INT (4));
11266 emit_insn (gen_movua (operands[0], src));
11273 (define_expand "extzv"
11274 [(set (match_operand:SI 0 "register_operand" "")
11275 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11276 (match_operand 2 "const_int_operand" "")
11277 (match_operand 3 "const_int_operand" "")))]
11280 if (TARGET_SH4A_ARCH
11281 && INTVAL (operands[2]) == 32
11282 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11283 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11285 rtx src = adjust_address (operands[1], BLKmode, 0);
11286 set_mem_size (src, GEN_INT (4));
11287 emit_insn (gen_movua (operands[0], src));
11295 ;; -------------------------------------------------------------------------
11297 ;; -------------------------------------------------------------------------
11299 ;; This matches cases where a stack pointer increment at the start of the
11300 ;; epilogue combines with a stack slot read loading the return value.
11303 [(set (match_operand:SI 0 "arith_reg_operand" "")
11304 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11305 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11306 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11309 ;; See the comment on the dt combiner pattern above.
11312 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11313 (plus:SI (match_dup 0)
11315 (set (reg:SI T_REG)
11316 (eq:SI (match_dup 0)
11321 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11322 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11323 ;; reload when the constant is too large for a reg+offset address.
11325 ;; ??? We would get much better code if this was done in reload. This would
11326 ;; require modifying find_reloads_address to recognize that if the constant
11327 ;; is out-of-range for an immediate add, then we get better code by reloading
11328 ;; the constant into a register than by reloading the sum into a register,
11329 ;; since the former is one instruction shorter if the address does not need
11330 ;; to be offsettable. Unfortunately this does not work, because there is
11331 ;; only one register, r0, that can be used as an index register. This register
11332 ;; is also the function return value register. So, if we try to force reload
11333 ;; to use double-reg addresses, then we end up with some instructions that
11334 ;; need to use r0 twice. The only way to fix this is to change the calling
11335 ;; convention so that r0 is not used to return values.
11338 [(set (match_operand:SI 0 "register_operand" "=r")
11339 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11340 (set (mem:SI (match_dup 0))
11341 (match_operand:SI 2 "general_movsrc_operand" ""))]
11342 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11343 "mov.l %2,@(%0,%1)")
11346 [(set (match_operand:SI 0 "register_operand" "=r")
11347 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11348 (set (match_operand:SI 2 "general_movdst_operand" "")
11349 (mem:SI (match_dup 0)))]
11350 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11351 "mov.l @(%0,%1),%2")
11354 [(set (match_operand:SI 0 "register_operand" "=r")
11355 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11356 (set (mem:HI (match_dup 0))
11357 (match_operand:HI 2 "general_movsrc_operand" ""))]
11358 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11359 "mov.w %2,@(%0,%1)")
11362 [(set (match_operand:SI 0 "register_operand" "=r")
11363 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11364 (set (match_operand:HI 2 "general_movdst_operand" "")
11365 (mem:HI (match_dup 0)))]
11366 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11367 "mov.w @(%0,%1),%2")
11370 [(set (match_operand:SI 0 "register_operand" "=r")
11371 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11372 (set (mem:QI (match_dup 0))
11373 (match_operand:QI 2 "general_movsrc_operand" ""))]
11374 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11375 "mov.b %2,@(%0,%1)")
11378 [(set (match_operand:SI 0 "register_operand" "=r")
11379 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11380 (set (match_operand:QI 2 "general_movdst_operand" "")
11381 (mem:QI (match_dup 0)))]
11382 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11383 "mov.b @(%0,%1),%2")
11386 [(set (match_operand:SI 0 "register_operand" "=r")
11387 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11388 (set (mem:SF (match_dup 0))
11389 (match_operand:SF 2 "general_movsrc_operand" ""))]
11390 "TARGET_SH1 && REGNO (operands[0]) == 0
11391 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11392 || (GET_CODE (operands[2]) == SUBREG
11393 && REGNO (SUBREG_REG (operands[2])) < 16))
11394 && reg_unused_after (operands[0], insn)"
11395 "mov.l %2,@(%0,%1)")
11398 [(set (match_operand:SI 0 "register_operand" "=r")
11399 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11400 (set (match_operand:SF 2 "general_movdst_operand" "")
11402 (mem:SF (match_dup 0)))]
11403 "TARGET_SH1 && REGNO (operands[0]) == 0
11404 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11405 || (GET_CODE (operands[2]) == SUBREG
11406 && REGNO (SUBREG_REG (operands[2])) < 16))
11407 && reg_unused_after (operands[0], insn)"
11408 "mov.l @(%0,%1),%2")
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:SF (match_dup 0))
11414 (match_operand:SF 2 "general_movsrc_operand" ""))]
11415 "TARGET_SH2E && REGNO (operands[0]) == 0
11416 && ((GET_CODE (operands[2]) == REG
11417 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11418 || (GET_CODE (operands[2]) == SUBREG
11419 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11420 && reg_unused_after (operands[0], insn)"
11421 "fmov{.s|} %2,@(%0,%1)")
11424 [(set (match_operand:SI 0 "register_operand" "=r")
11425 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11426 (set (match_operand:SF 2 "general_movdst_operand" "")
11428 (mem:SF (match_dup 0)))]
11429 "TARGET_SH2E && REGNO (operands[0]) == 0
11430 && ((GET_CODE (operands[2]) == REG
11431 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11432 || (GET_CODE (operands[2]) == SUBREG
11433 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11434 && reg_unused_after (operands[0], insn)"
11435 "fmov{.s|} @(%0,%1),%2")
11437 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11438 (define_insn "sp_switch_1"
11439 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11443 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11444 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11445 return \"mov r0,r15\";
11447 [(set_attr "length" "10")])
11449 ;; Switch back to the original stack for interrupt functions with the
11450 ;; sp_switch attribute. */
11451 (define_insn "sp_switch_2"
11454 "mov.l @r15+,r15\;mov.l @r15+,r0"
11455 [(set_attr "length" "4")])
11457 ;; Integer vector moves
11459 (define_expand "movv8qi"
11460 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11461 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11463 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11465 (define_insn "movv8qi_i"
11466 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11467 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11469 && (register_operand (operands[0], V8QImode)
11470 || sh_register_operand (operands[1], V8QImode))"
11477 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11478 (set_attr "length" "4,4,16,4,4")])
11481 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11482 (subreg:V8QI (const_int 0) 0))]
11484 [(set (match_dup 0)
11485 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11486 (const_int 0) (const_int 0) (const_int 0)
11487 (const_int 0) (const_int 0)]))])
11490 [(set (match_operand 0 "arith_reg_dest" "")
11491 (match_operand 1 "sh_rep_vec" ""))]
11492 "TARGET_SHMEDIA && reload_completed
11493 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11494 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11495 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11496 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11497 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11498 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11499 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11500 [(set (match_dup 0) (match_dup 1))
11504 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11505 rtx elt1 = XVECEXP (operands[1], 0, 1);
11508 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11512 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11513 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11515 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11516 operands[1] = XVECEXP (operands[1], 0, 0);
11519 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11521 = GEN_INT (TARGET_LITTLE_ENDIAN
11522 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11523 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11526 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11528 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11534 [(set (match_operand 0 "arith_reg_dest" "")
11535 (match_operand 1 "sh_const_vec" ""))]
11536 "TARGET_SHMEDIA && reload_completed
11537 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11538 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11539 [(set (match_dup 0) (match_dup 1))]
11542 rtx v = operands[1];
11543 enum machine_mode new_mode
11544 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11546 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11548 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11551 (define_expand "movv2hi"
11552 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11553 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11555 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11557 (define_insn "movv2hi_i"
11558 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11559 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11561 && (register_operand (operands[0], V2HImode)
11562 || sh_register_operand (operands[1], V2HImode))"
11569 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11570 (set_attr "length" "4,4,16,4,4")
11571 (set (attr "highpart")
11572 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11573 (const_string "user")]
11574 (const_string "ignore")))])
11576 (define_expand "movv4hi"
11577 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11578 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11580 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11582 (define_insn "movv4hi_i"
11583 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11584 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11586 && (register_operand (operands[0], V4HImode)
11587 || sh_register_operand (operands[1], V4HImode))"
11594 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11595 (set_attr "length" "4,4,16,4,4")
11596 (set_attr "highpart" "depend")])
11598 (define_expand "movv2si"
11599 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11600 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11602 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11604 (define_insn "movv2si_i"
11605 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11606 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11608 && (register_operand (operands[0], V2SImode)
11609 || sh_register_operand (operands[1], V2SImode))"
11616 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11617 (set_attr "length" "4,4,16,4,4")
11618 (set_attr "highpart" "depend")])
11620 ;; Multimedia Intrinsics
11622 (define_insn "absv2si2"
11623 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11624 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11627 [(set_attr "type" "mcmp_media")
11628 (set_attr "highpart" "depend")])
11630 (define_insn "absv4hi2"
11631 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11632 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11635 [(set_attr "type" "mcmp_media")
11636 (set_attr "highpart" "depend")])
11638 (define_insn "addv2si3"
11639 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11640 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11641 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11643 "madd.l %1, %2, %0"
11644 [(set_attr "type" "arith_media")
11645 (set_attr "highpart" "depend")])
11647 (define_insn "addv4hi3"
11648 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11649 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11650 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11652 "madd.w %1, %2, %0"
11653 [(set_attr "type" "arith_media")
11654 (set_attr "highpart" "depend")])
11656 (define_insn_and_split "addv2hi3"
11657 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11658 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11659 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11666 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11667 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11668 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11669 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11670 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11672 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11673 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11676 [(set_attr "highpart" "must_split")])
11678 (define_insn "ssaddv2si3"
11679 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11680 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11681 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11683 "madds.l %1, %2, %0"
11684 [(set_attr "type" "mcmp_media")
11685 (set_attr "highpart" "depend")])
11687 (define_insn "usaddv8qi3"
11688 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11689 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11690 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11692 "madds.ub %1, %2, %0"
11693 [(set_attr "type" "mcmp_media")
11694 (set_attr "highpart" "depend")])
11696 (define_insn "ssaddv4hi3"
11697 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11698 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11699 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11701 "madds.w %1, %2, %0"
11702 [(set_attr "type" "mcmp_media")
11703 (set_attr "highpart" "depend")])
11705 (define_insn "negcmpeqv8qi"
11706 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11707 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11708 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11710 "mcmpeq.b %N1, %N2, %0"
11711 [(set_attr "type" "mcmp_media")
11712 (set_attr "highpart" "depend")])
11714 (define_insn "negcmpeqv2si"
11715 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11716 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11717 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11719 "mcmpeq.l %N1, %N2, %0"
11720 [(set_attr "type" "mcmp_media")
11721 (set_attr "highpart" "depend")])
11723 (define_insn "negcmpeqv4hi"
11724 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11725 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11726 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11728 "mcmpeq.w %N1, %N2, %0"
11729 [(set_attr "type" "mcmp_media")
11730 (set_attr "highpart" "depend")])
11732 (define_insn "negcmpgtuv8qi"
11733 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11734 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11735 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11737 "mcmpgt.ub %N1, %N2, %0"
11738 [(set_attr "type" "mcmp_media")
11739 (set_attr "highpart" "depend")])
11741 (define_insn "negcmpgtv2si"
11742 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11743 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11744 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11746 "mcmpgt.l %N1, %N2, %0"
11747 [(set_attr "type" "mcmp_media")
11748 (set_attr "highpart" "depend")])
11750 (define_insn "negcmpgtv4hi"
11751 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11752 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11753 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11755 "mcmpgt.w %N1, %N2, %0"
11756 [(set_attr "type" "mcmp_media")
11757 (set_attr "highpart" "depend")])
11759 (define_insn "mcmv"
11760 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11761 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11762 (match_operand:DI 2 "arith_reg_operand" "r"))
11763 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11764 (not:DI (match_dup 2)))))]
11767 [(set_attr "type" "arith_media")
11768 (set_attr "highpart" "depend")])
11770 (define_insn "mcnvs_lw"
11771 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11773 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11774 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11776 "mcnvs.lw %N1, %N2, %0"
11777 [(set_attr "type" "mcmp_media")])
11779 (define_insn "mcnvs_wb"
11780 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11782 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11783 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11785 "mcnvs.wb %N1, %N2, %0"
11786 [(set_attr "type" "mcmp_media")])
11788 (define_insn "mcnvs_wub"
11789 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11791 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11792 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11794 "mcnvs.wub %N1, %N2, %0"
11795 [(set_attr "type" "mcmp_media")])
11797 (define_insn "mextr_rl"
11798 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11799 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11800 (match_operand:HI 3 "mextr_bit_offset" "i"))
11801 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11802 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11803 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11806 static char templ[21];
11808 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11809 (int) INTVAL (operands[3]) >> 3);
11812 [(set_attr "type" "arith_media")])
11814 (define_insn "*mextr_lr"
11815 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11816 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11817 (match_operand:HI 3 "mextr_bit_offset" "i"))
11818 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11819 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11820 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11823 static char templ[21];
11825 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11826 (int) INTVAL (operands[4]) >> 3);
11829 [(set_attr "type" "arith_media")])
11831 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11832 ; vector then varies depending on endianness.
11833 (define_expand "mextr1"
11834 [(match_operand:DI 0 "arith_reg_dest" "")
11835 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11836 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11840 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11841 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11845 (define_expand "mextr2"
11846 [(match_operand:DI 0 "arith_reg_dest" "")
11847 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11848 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11852 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11853 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11857 (define_expand "mextr3"
11858 [(match_operand:DI 0 "arith_reg_dest" "")
11859 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11860 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11864 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11865 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11869 (define_expand "mextr4"
11870 [(match_operand:DI 0 "arith_reg_dest" "")
11871 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11872 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11876 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11877 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11881 (define_expand "mextr5"
11882 [(match_operand:DI 0 "arith_reg_dest" "")
11883 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11884 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11888 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11889 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11893 (define_expand "mextr6"
11894 [(match_operand:DI 0 "arith_reg_dest" "")
11895 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11896 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11900 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11901 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11905 (define_expand "mextr7"
11906 [(match_operand:DI 0 "arith_reg_dest" "")
11907 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11908 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11912 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11913 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11917 (define_expand "mmacfx_wl"
11918 [(match_operand:V2SI 0 "arith_reg_dest" "")
11919 (match_operand:V2HI 1 "extend_reg_operand" "")
11920 (match_operand:V2HI 2 "extend_reg_operand" "")
11921 (match_operand:V2SI 3 "arith_reg_operand" "")]
11925 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11926 operands[1], operands[2]));
11930 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11932 (define_insn "mmacfx_wl_i"
11933 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11935 (match_operand:V2SI 1 "arith_reg_operand" "0")
11940 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11941 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11944 "mmacfx.wl %2, %3, %0"
11945 [(set_attr "type" "mac_media")
11946 (set_attr "highpart" "depend")])
11948 (define_expand "mmacnfx_wl"
11949 [(match_operand:V2SI 0 "arith_reg_dest" "")
11950 (match_operand:V2HI 1 "extend_reg_operand" "")
11951 (match_operand:V2HI 2 "extend_reg_operand" "")
11952 (match_operand:V2SI 3 "arith_reg_operand" "")]
11956 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11957 operands[1], operands[2]));
11961 (define_insn "mmacnfx_wl_i"
11962 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11964 (match_operand:V2SI 1 "arith_reg_operand" "0")
11969 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11970 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11973 "mmacnfx.wl %2, %3, %0"
11974 [(set_attr "type" "mac_media")
11975 (set_attr "highpart" "depend")])
11977 (define_insn "mulv2si3"
11978 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11979 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11980 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11982 "mmul.l %1, %2, %0"
11983 [(set_attr "type" "d2mpy_media")
11984 (set_attr "highpart" "depend")])
11986 (define_insn "mulv4hi3"
11987 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11988 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11989 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11991 "mmul.w %1, %2, %0"
11992 [(set_attr "type" "dmpy_media")
11993 (set_attr "highpart" "depend")])
11995 (define_insn "mmulfx_l"
11996 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12000 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12001 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12004 "mmulfx.l %1, %2, %0"
12005 [(set_attr "type" "d2mpy_media")
12006 (set_attr "highpart" "depend")])
12008 (define_insn "mmulfx_w"
12009 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12013 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12014 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12017 "mmulfx.w %1, %2, %0"
12018 [(set_attr "type" "dmpy_media")
12019 (set_attr "highpart" "depend")])
12021 (define_insn "mmulfxrp_w"
12022 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12027 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12028 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12032 "mmulfxrp.w %1, %2, %0"
12033 [(set_attr "type" "dmpy_media")
12034 (set_attr "highpart" "depend")])
12037 (define_expand "mmulhi_wl"
12038 [(match_operand:V2SI 0 "arith_reg_dest" "")
12039 (match_operand:V4HI 1 "arith_reg_operand" "")
12040 (match_operand:V4HI 2 "arith_reg_operand" "")]
12044 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12045 (operands[0], operands[1], operands[2]));
12049 (define_expand "mmullo_wl"
12050 [(match_operand:V2SI 0 "arith_reg_dest" "")
12051 (match_operand:V4HI 1 "arith_reg_operand" "")
12052 (match_operand:V4HI 2 "arith_reg_operand" "")]
12056 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12057 (operands[0], operands[1], operands[2]));
12061 (define_insn "mmul23_wl"
12062 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12065 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12066 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12067 (parallel [(const_int 2) (const_int 3)])))]
12069 "* return (TARGET_LITTLE_ENDIAN
12070 ? \"mmulhi.wl %1, %2, %0\"
12071 : \"mmullo.wl %1, %2, %0\");"
12072 [(set_attr "type" "dmpy_media")
12073 (set (attr "highpart")
12074 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12075 (const_string "user")))])
12077 (define_insn "mmul01_wl"
12078 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12081 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12082 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12083 (parallel [(const_int 0) (const_int 1)])))]
12085 "* return (TARGET_LITTLE_ENDIAN
12086 ? \"mmullo.wl %1, %2, %0\"
12087 : \"mmulhi.wl %1, %2, %0\");"
12088 [(set_attr "type" "dmpy_media")
12089 (set (attr "highpart")
12090 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12091 (const_string "user")))])
12094 (define_expand "mmulsum_wq"
12095 [(match_operand:DI 0 "arith_reg_dest" "")
12096 (match_operand:V4HI 1 "arith_reg_operand" "")
12097 (match_operand:V4HI 2 "arith_reg_operand" "")
12098 (match_operand:DI 3 "arith_reg_operand" "")]
12102 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12103 operands[1], operands[2]));
12107 (define_insn "mmulsum_wq_i"
12108 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12109 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12114 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12115 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12116 (parallel [(const_int 0)]))
12117 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12118 (sign_extend:V4DI (match_dup 3)))
12119 (parallel [(const_int 1)])))
12121 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12122 (sign_extend:V4DI (match_dup 3)))
12123 (parallel [(const_int 2)]))
12124 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12125 (sign_extend:V4DI (match_dup 3)))
12126 (parallel [(const_int 3)]))))))]
12128 "mmulsum.wq %2, %3, %0"
12129 [(set_attr "type" "mac_media")])
12131 (define_expand "mperm_w"
12132 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12133 (match_operand:V4HI 1 "arith_reg_operand" "r")
12134 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12138 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12139 (operands[0], operands[1], operands[2]));
12143 ; This use of vec_select isn't exactly correct according to rtl.texi
12144 ; (because not constant), but it seems a straightforward extension.
12145 (define_insn "mperm_w_little"
12146 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12148 (match_operand:V4HI 1 "arith_reg_operand" "r")
12150 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12151 (const_int 2) (const_int 0))
12152 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12153 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12154 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12155 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12156 "mperm.w %1, %N2, %0"
12157 [(set_attr "type" "arith_media")])
12159 (define_insn "mperm_w_big"
12160 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12162 (match_operand:V4HI 1 "arith_reg_operand" "r")
12164 [(zero_extract:QI (not:QI (match_operand:QI 2
12165 "extend_reg_or_0_operand" "rZ"))
12166 (const_int 2) (const_int 0))
12167 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12168 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12169 (zero_extract:QI (not:QI (match_dup 2))
12170 (const_int 2) (const_int 6))])))]
12171 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12172 "mperm.w %1, %N2, %0"
12173 [(set_attr "type" "arith_media")])
12175 (define_insn "mperm_w0"
12176 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12177 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12178 "trunc_hi_operand" "r"))))]
12180 "mperm.w %1, r63, %0"
12181 [(set_attr "type" "arith_media")
12182 (set_attr "highpart" "ignore")])
12184 (define_expand "msad_ubq"
12185 [(match_operand:DI 0 "arith_reg_dest" "")
12186 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12187 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12188 (match_operand:DI 3 "arith_reg_operand" "")]
12192 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12193 operands[1], operands[2]));
12197 (define_insn "msad_ubq_i"
12198 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12203 (match_operand:DI 1 "arith_reg_operand" "0")
12204 (abs:DI (vec_select:DI
12207 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12209 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12210 (parallel [(const_int 0)]))))
12211 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12212 (zero_extend:V8DI (match_dup 3)))
12213 (parallel [(const_int 1)]))))
12215 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12216 (zero_extend:V8DI (match_dup 3)))
12217 (parallel [(const_int 2)])))
12218 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12219 (zero_extend:V8DI (match_dup 3)))
12220 (parallel [(const_int 3)])))))
12223 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12224 (zero_extend:V8DI (match_dup 3)))
12225 (parallel [(const_int 4)])))
12226 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12227 (zero_extend:V8DI (match_dup 3)))
12228 (parallel [(const_int 5)]))))
12230 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12231 (zero_extend:V8DI (match_dup 3)))
12232 (parallel [(const_int 6)])))
12233 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12234 (zero_extend:V8DI (match_dup 3)))
12235 (parallel [(const_int 7)])))))))]
12237 "msad.ubq %N2, %N3, %0"
12238 [(set_attr "type" "mac_media")])
12240 (define_insn "mshalds_l"
12241 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12244 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12245 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12246 (const_int 31)))))]
12248 "mshalds.l %1, %2, %0"
12249 [(set_attr "type" "mcmp_media")
12250 (set_attr "highpart" "depend")])
12252 (define_insn "mshalds_w"
12253 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12256 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12257 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12258 (const_int 15)))))]
12260 "mshalds.w %1, %2, %0"
12261 [(set_attr "type" "mcmp_media")
12262 (set_attr "highpart" "depend")])
12264 (define_insn "ashrv2si3"
12265 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12266 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12267 (match_operand:DI 2 "arith_reg_operand" "r")))]
12269 "mshard.l %1, %2, %0"
12270 [(set_attr "type" "arith_media")
12271 (set_attr "highpart" "depend")])
12273 (define_insn "ashrv4hi3"
12274 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12275 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12276 (match_operand:DI 2 "arith_reg_operand" "r")))]
12278 "mshard.w %1, %2, %0"
12279 [(set_attr "type" "arith_media")
12280 (set_attr "highpart" "depend")])
12282 (define_insn "mshards_q"
12283 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12285 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12286 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12288 "mshards.q %1, %N2, %0"
12289 [(set_attr "type" "mcmp_media")])
12291 (define_expand "mshfhi_b"
12292 [(match_operand:V8QI 0 "arith_reg_dest" "")
12293 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12294 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12298 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12299 (operands[0], operands[1], operands[2]));
12303 (define_expand "mshflo_b"
12304 [(match_operand:V8QI 0 "arith_reg_dest" "")
12305 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12306 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12310 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12311 (operands[0], operands[1], operands[2]));
12315 (define_insn "mshf4_b"
12317 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12319 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12320 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12321 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12322 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12324 "* return (TARGET_LITTLE_ENDIAN
12325 ? \"mshfhi.b %N1, %N2, %0\"
12326 : \"mshflo.b %N1, %N2, %0\");"
12327 [(set_attr "type" "arith_media")
12328 (set (attr "highpart")
12329 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12330 (const_string "user")))])
12332 (define_insn "mshf0_b"
12334 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12336 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12337 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12338 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12339 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12341 "* return (TARGET_LITTLE_ENDIAN
12342 ? \"mshflo.b %N1, %N2, %0\"
12343 : \"mshfhi.b %N1, %N2, %0\");"
12344 [(set_attr "type" "arith_media")
12345 (set (attr "highpart")
12346 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12347 (const_string "user")))])
12349 (define_expand "mshfhi_l"
12350 [(match_operand:V2SI 0 "arith_reg_dest" "")
12351 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12352 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12356 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12357 (operands[0], operands[1], operands[2]));
12361 (define_expand "mshflo_l"
12362 [(match_operand:V2SI 0 "arith_reg_dest" "")
12363 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12364 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12368 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12369 (operands[0], operands[1], operands[2]));
12373 (define_insn "mshf4_l"
12374 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12376 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12377 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12378 (parallel [(const_int 1) (const_int 3)])))]
12380 "* return (TARGET_LITTLE_ENDIAN
12381 ? \"mshfhi.l %N1, %N2, %0\"
12382 : \"mshflo.l %N1, %N2, %0\");"
12383 [(set_attr "type" "arith_media")
12384 (set (attr "highpart")
12385 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12386 (const_string "user")))])
12388 (define_insn "mshf0_l"
12389 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12391 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12392 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12393 (parallel [(const_int 0) (const_int 2)])))]
12395 "* return (TARGET_LITTLE_ENDIAN
12396 ? \"mshflo.l %N1, %N2, %0\"
12397 : \"mshfhi.l %N1, %N2, %0\");"
12398 [(set_attr "type" "arith_media")
12399 (set (attr "highpart")
12400 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12401 (const_string "user")))])
12403 (define_expand "mshfhi_w"
12404 [(match_operand:V4HI 0 "arith_reg_dest" "")
12405 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12406 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12410 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12411 (operands[0], operands[1], operands[2]));
12415 (define_expand "mshflo_w"
12416 [(match_operand:V4HI 0 "arith_reg_dest" "")
12417 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12418 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12422 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12423 (operands[0], operands[1], operands[2]));
12427 (define_insn "mshf4_w"
12428 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12430 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12431 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12432 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12434 "* return (TARGET_LITTLE_ENDIAN
12435 ? \"mshfhi.w %N1, %N2, %0\"
12436 : \"mshflo.w %N1, %N2, %0\");"
12437 [(set_attr "type" "arith_media")
12438 (set (attr "highpart")
12439 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12440 (const_string "user")))])
12442 (define_insn "mshf0_w"
12443 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12445 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12446 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12447 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12449 "* return (TARGET_LITTLE_ENDIAN
12450 ? \"mshflo.w %N1, %N2, %0\"
12451 : \"mshfhi.w %N1, %N2, %0\");"
12452 [(set_attr "type" "arith_media")
12453 (set (attr "highpart")
12454 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12455 (const_string "user")))])
12457 (define_insn "mshflo_w_x"
12458 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12460 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12461 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12462 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12464 "mshflo.w %N1, %N2, %0"
12465 [(set_attr "type" "arith_media")
12466 (set_attr "highpart" "ignore")])
12468 /* These are useful to expand ANDs and as combiner patterns. */
12469 (define_insn_and_split "mshfhi_l_di"
12470 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12471 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12473 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12474 (const_int -4294967296))))]
12477 mshfhi.l %N1, %N2, %0
12479 "TARGET_SHMEDIA && reload_completed
12480 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12481 [(set (match_dup 3) (match_dup 4))
12482 (set (match_dup 5) (match_dup 6))]
12485 operands[3] = gen_lowpart (SImode, operands[0]);
12486 operands[4] = gen_highpart (SImode, operands[1]);
12487 operands[5] = gen_highpart (SImode, operands[0]);
12488 operands[6] = gen_highpart (SImode, operands[2]);
12490 [(set_attr "type" "arith_media")])
12492 (define_insn "*mshfhi_l_di_rev"
12493 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12494 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12495 (const_int -4294967296))
12496 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12499 "mshfhi.l %N2, %N1, %0"
12500 [(set_attr "type" "arith_media")])
12503 [(set (match_operand:DI 0 "arith_reg_dest" "")
12504 (ior:DI (zero_extend:DI (match_operand:SI 1
12505 "extend_reg_or_0_operand" ""))
12506 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12507 (const_int -4294967296))))
12508 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12513 emit_insn (gen_ashldi3_media (operands[3],
12514 simplify_gen_subreg (DImode, operands[1],
12517 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12521 (define_insn "mshflo_l_di"
12522 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12523 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12524 (const_int 4294967295))
12525 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12529 "mshflo.l %N1, %N2, %0"
12530 [(set_attr "type" "arith_media")
12531 (set_attr "highpart" "ignore")])
12533 (define_insn "*mshflo_l_di_rev"
12534 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12535 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12537 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12538 (const_int 4294967295))))]
12541 "mshflo.l %N2, %N1, %0"
12542 [(set_attr "type" "arith_media")
12543 (set_attr "highpart" "ignore")])
12545 ;; Combiner pattern for trampoline initialization.
12546 (define_insn_and_split "*double_shori"
12547 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12548 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12550 (match_operand:DI 2 "const_int_operand" "n")))]
12552 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12554 "rtx_equal_p (operands[0], operands[1])"
12558 HOST_WIDE_INT v = INTVAL (operands[2]);
12560 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12561 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12564 [(set_attr "highpart" "ignore")])
12567 (define_insn "*mshflo_l_di_x"
12568 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12569 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12571 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12575 "mshflo.l %N1, %N2, %0"
12576 [(set_attr "type" "arith_media")
12577 (set_attr "highpart" "ignore")])
12579 (define_insn_and_split "concat_v2sf"
12580 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12581 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12582 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12583 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12587 mshflo.l %N1, %N2, %0
12590 "TARGET_SHMEDIA && reload_completed
12591 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12592 [(set (match_dup 3) (match_dup 1))
12593 (set (match_dup 4) (match_dup 2))]
12596 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12597 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12599 [(set_attr "type" "arith_media")
12600 (set_attr "highpart" "ignore")])
12602 (define_insn "*mshflo_l_di_x_rev"
12603 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12604 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12606 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12609 "mshflo.l %N2, %N1, %0"
12610 [(set_attr "type" "arith_media")
12611 (set_attr "highpart" "ignore")])
12613 (define_insn "ashlv2si3"
12614 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12615 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12616 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12618 "mshlld.l %1, %2, %0"
12619 [(set_attr "type" "arith_media")
12620 (set_attr "highpart" "depend")])
12623 [(set (match_operand 0 "any_register_operand" "")
12624 (match_operator 3 "shift_operator"
12625 [(match_operand 1 "any_register_operand" "")
12626 (match_operand 2 "shift_count_reg_operand" "")]))]
12627 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12628 [(set (match_dup 0) (match_dup 3))]
12631 rtx count = operands[2];
12632 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12634 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12635 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12636 || GET_CODE (count) == TRUNCATE)
12637 count = XEXP (count, 0);
12638 inner_mode = GET_MODE (count);
12639 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12640 subreg_lowpart_offset (outer_mode, inner_mode));
12641 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12642 operands[1], count);
12645 (define_insn "ashlv4hi3"
12646 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12647 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12648 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12650 "mshlld.w %1, %2, %0"
12651 [(set_attr "type" "arith_media")
12652 (set_attr "highpart" "depend")])
12654 (define_insn "lshrv2si3"
12655 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12656 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12657 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12659 "mshlrd.l %1, %2, %0"
12660 [(set_attr "type" "arith_media")
12661 (set_attr "highpart" "depend")])
12663 (define_insn "lshrv4hi3"
12664 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12665 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12666 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12668 "mshlrd.w %1, %2, %0"
12669 [(set_attr "type" "arith_media")
12670 (set_attr "highpart" "depend")])
12672 (define_insn "subv2si3"
12673 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12674 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12675 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12677 "msub.l %N1, %2, %0"
12678 [(set_attr "type" "arith_media")
12679 (set_attr "highpart" "depend")])
12681 (define_insn "subv4hi3"
12682 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12683 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12684 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12686 "msub.w %N1, %2, %0"
12687 [(set_attr "type" "arith_media")
12688 (set_attr "highpart" "depend")])
12690 (define_insn_and_split "subv2hi3"
12691 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12692 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12693 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12700 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12701 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12702 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12703 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12704 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12706 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12707 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12710 [(set_attr "highpart" "must_split")])
12712 (define_insn "sssubv2si3"
12713 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12714 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12715 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12717 "msubs.l %N1, %2, %0"
12718 [(set_attr "type" "mcmp_media")
12719 (set_attr "highpart" "depend")])
12721 (define_insn "ussubv8qi3"
12722 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12723 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12724 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12726 "msubs.ub %N1, %2, %0"
12727 [(set_attr "type" "mcmp_media")
12728 (set_attr "highpart" "depend")])
12730 (define_insn "sssubv4hi3"
12731 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12732 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12733 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12735 "msubs.w %N1, %2, %0"
12736 [(set_attr "type" "mcmp_media")
12737 (set_attr "highpart" "depend")])
12739 ;; Floating Point Intrinsics
12741 (define_insn "fcosa_s"
12742 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12743 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12747 [(set_attr "type" "atrans_media")])
12749 (define_insn "fsina_s"
12750 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12751 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12755 [(set_attr "type" "atrans_media")])
12757 (define_insn "fipr"
12758 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12759 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12760 "fp_arith_reg_operand" "f")
12761 (match_operand:V4SF 2
12762 "fp_arith_reg_operand" "f"))
12763 (parallel [(const_int 0)]))
12764 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12765 (parallel [(const_int 1)])))
12766 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12767 (parallel [(const_int 2)]))
12768 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12769 (parallel [(const_int 3)])))))]
12771 "fipr.s %1, %2, %0"
12772 [(set_attr "type" "fparith_media")])
12774 (define_insn "fsrra_s"
12775 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12776 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12780 [(set_attr "type" "atrans_media")])
12782 (define_insn "ftrv"
12783 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12787 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12788 (parallel [(const_int 0) (const_int 5)
12789 (const_int 10) (const_int 15)]))
12790 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12792 (vec_select:V4SF (match_dup 1)
12793 (parallel [(const_int 4) (const_int 9)
12794 (const_int 14) (const_int 3)]))
12795 (vec_select:V4SF (match_dup 2)
12796 (parallel [(const_int 1) (const_int 2)
12797 (const_int 3) (const_int 0)]))))
12800 (vec_select:V4SF (match_dup 1)
12801 (parallel [(const_int 8) (const_int 13)
12802 (const_int 2) (const_int 7)]))
12803 (vec_select:V4SF (match_dup 2)
12804 (parallel [(const_int 2) (const_int 3)
12805 (const_int 0) (const_int 1)])))
12807 (vec_select:V4SF (match_dup 1)
12808 (parallel [(const_int 12) (const_int 1)
12809 (const_int 6) (const_int 11)]))
12810 (vec_select:V4SF (match_dup 2)
12811 (parallel [(const_int 3) (const_int 0)
12812 (const_int 1) (const_int 2)]))))))]
12814 "ftrv.s %1, %2, %0"
12815 [(set_attr "type" "fparith_media")])
12817 (define_insn "ldhi_l"
12818 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12820 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12823 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12827 [(set_attr "type" "load_media")])
12829 (define_insn "ldhi_q"
12830 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12832 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12835 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12839 [(set_attr "type" "load_media")])
12841 (define_insn_and_split "*ldhi_q_comb0"
12842 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12844 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12845 "register_operand" "r")
12846 (match_operand:SI 2
12847 "ua_offset" "I06"))
12850 (plus:SI (and:SI (match_dup 1) (const_int 7))
12853 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12857 "emit_insn (gen_ldhi_q (operands[0],
12858 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12862 (define_insn_and_split "*ldhi_q_comb1"
12863 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12865 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12866 "register_operand" "r")
12867 (match_operand:SI 2
12868 "ua_offset" "I06"))
12871 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12872 "ua_offset" "I06"))
12876 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12877 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12881 "emit_insn (gen_ldhi_q (operands[0],
12882 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12886 (define_insn "ldlo_l"
12887 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12889 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12891 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12892 (and:SI (match_dup 1) (const_int 3))))]
12895 [(set_attr "type" "load_media")])
12897 (define_insn "ldlo_q"
12898 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12900 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12902 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12903 (and:SI (match_dup 1) (const_int 7))))]
12906 [(set_attr "type" "load_media")])
12908 (define_insn_and_split "*ldlo_q_comb0"
12909 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12911 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12912 (match_operand:SI 2 "ua_offset" "I06"))
12914 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12915 (and:SI (match_dup 1) (const_int 7))))]
12916 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12920 "emit_insn (gen_ldlo_q (operands[0],
12921 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12924 (define_insn_and_split "*ldlo_q_comb1"
12925 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12927 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12928 (match_operand:SI 2 "ua_offset" "I06"))
12930 (minus:SI (const_int 8)
12931 (and:SI (plus:SI (match_dup 1)
12932 (match_operand:SI 3 "ua_offset" "I06"))
12934 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12935 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12936 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12940 "emit_insn (gen_ldlo_q (operands[0],
12941 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12944 (define_insn "sthi_l"
12945 [(set (zero_extract:SI
12946 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12949 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12951 (match_operand:SI 1 "arith_reg_operand" "r"))]
12954 [(set_attr "type" "ustore_media")])
12956 ;; All unaligned stores are considered to be 'narrow' because they typically
12957 ;; operate on less that a quadword, and when they operate on a full quadword,
12958 ;; the vanilla store high / store low sequence will cause a stall if not
12959 ;; scheduled apart.
12960 (define_insn "sthi_q"
12961 [(set (zero_extract:DI
12962 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12965 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12967 (match_operand:DI 1 "arith_reg_operand" "r"))]
12970 [(set_attr "type" "ustore_media")])
12972 (define_insn_and_split "*sthi_q_comb0"
12973 [(set (zero_extract:DI
12974 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12975 "register_operand" "r")
12976 (match_operand:SI 1 "ua_offset"
12980 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12982 (match_operand:DI 2 "arith_reg_operand" "r"))]
12983 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12987 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12991 (define_insn_and_split "*sthi_q_comb1"
12992 [(set (zero_extract:DI
12993 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12994 "register_operand" "r")
12995 (match_operand:SI 1 "ua_offset"
12999 (plus:SI (and:SI (plus:SI (match_dup 0)
13000 (match_operand:SI 2 "ua_offset" "I06"))
13004 (match_operand:DI 3 "arith_reg_operand" "r"))]
13005 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13006 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13010 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13014 ;; This is highpart user because the address is used as full 64 bit.
13015 (define_insn "stlo_l"
13016 [(set (zero_extract:SI
13017 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13019 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13020 (and:SI (match_dup 0) (const_int 3)))
13021 (match_operand:SI 1 "arith_reg_operand" "r"))]
13024 [(set_attr "type" "ustore_media")])
13026 (define_insn "stlo_q"
13027 [(set (zero_extract:DI
13028 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13030 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13031 (and:SI (match_dup 0) (const_int 7)))
13032 (match_operand:DI 1 "arith_reg_operand" "r"))]
13035 [(set_attr "type" "ustore_media")])
13037 (define_insn_and_split "*stlo_q_comb0"
13038 [(set (zero_extract:DI
13039 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13040 (match_operand:SI 1 "ua_offset" "I06"))
13042 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13043 (and:SI (match_dup 0) (const_int 7)))
13044 (match_operand:DI 2 "arith_reg_operand" "r"))]
13045 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13049 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13053 (define_insn_and_split "*stlo_q_comb1"
13054 [(set (zero_extract:DI
13055 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13056 (match_operand:SI 1 "ua_offset" "I06"))
13058 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13059 (match_operand:SI 2
13060 "ua_offset" "I06"))
13062 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13063 (match_operand:DI 3 "arith_reg_operand" "r"))]
13064 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13068 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13072 (define_insn "ldhi_l64"
13073 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13075 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13078 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13082 [(set_attr "type" "load_media")])
13084 (define_insn "ldhi_q64"
13085 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13087 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13090 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13094 [(set_attr "type" "load_media")])
13096 (define_insn "ldlo_l64"
13097 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13099 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13101 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13102 (and:DI (match_dup 1) (const_int 3))))]
13105 [(set_attr "type" "load_media")])
13107 (define_insn "ldlo_q64"
13108 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13110 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13112 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13113 (and:DI (match_dup 1) (const_int 7))))]
13116 [(set_attr "type" "load_media")])
13118 (define_insn "sthi_l64"
13119 [(set (zero_extract:SI
13120 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13123 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13125 (match_operand:SI 1 "arith_reg_operand" "r"))]
13128 [(set_attr "type" "ustore_media")])
13130 (define_insn "sthi_q64"
13131 [(set (zero_extract:DI
13132 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13135 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13137 (match_operand:DI 1 "arith_reg_operand" "r"))]
13140 [(set_attr "type" "ustore_media")])
13142 (define_insn "stlo_l64"
13143 [(set (zero_extract:SI
13144 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13146 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13147 (and:DI (match_dup 0) (const_int 3)))
13148 (match_operand:SI 1 "arith_reg_operand" "r"))]
13151 [(set_attr "type" "ustore_media")])
13153 (define_insn "stlo_q64"
13154 [(set (zero_extract:DI
13155 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13157 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13158 (and:DI (match_dup 0) (const_int 7)))
13159 (match_operand:DI 1 "arith_reg_operand" "r"))]
13162 [(set_attr "type" "ustore_media")])
13165 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13166 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13170 [(set_attr "type" "arith_media")])
13172 (define_insn "nsbsi"
13173 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13175 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13179 [(set_attr "type" "arith_media")])
13181 (define_insn "nsbdi"
13182 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13184 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13188 [(set_attr "type" "arith_media")])
13190 (define_expand "ffsdi2"
13191 [(set (match_operand:DI 0 "arith_reg_dest" "")
13192 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13196 rtx scratch = gen_reg_rtx (DImode);
13199 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13200 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13201 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13202 emit_insn (gen_nsbdi (scratch, scratch));
13203 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13204 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13205 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13207 = gen_rtx_EXPR_LIST (REG_EQUAL,
13208 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13212 (define_expand "ffssi2"
13213 [(set (match_operand:SI 0 "arith_reg_dest" "")
13214 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13218 rtx scratch = gen_reg_rtx (SImode);
13219 rtx discratch = gen_reg_rtx (DImode);
13222 emit_insn (gen_adddi3 (discratch,
13223 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13225 emit_insn (gen_andcdi3 (discratch,
13226 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13228 emit_insn (gen_nsbsi (scratch, discratch));
13229 last = emit_insn (gen_subsi3 (operands[0],
13230 force_reg (SImode, GEN_INT (63)), scratch));
13232 = gen_rtx_EXPR_LIST (REG_EQUAL,
13233 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13237 (define_insn "byterev"
13238 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13239 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13240 (parallel [(const_int 7) (const_int 6) (const_int 5)
13241 (const_int 4) (const_int 3) (const_int 2)
13242 (const_int 1) (const_int 0)])))]
13245 [(set_attr "type" "arith_media")])
13247 (define_insn "*prefetch_media"
13248 [(prefetch (match_operand:QI 0 "address_operand" "p")
13249 (match_operand:SI 1 "const_int_operand" "n")
13250 (match_operand:SI 2 "const_int_operand" "n"))]
13254 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13255 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13258 [(set_attr "type" "other")])
13260 (define_insn "*prefetch_i4"
13261 [(prefetch (match_operand:SI 0 "register_operand" "r")
13262 (match_operand:SI 1 "const_int_operand" "n")
13263 (match_operand:SI 2 "const_int_operand" "n"))]
13264 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13267 return \"pref @%0\";
13269 [(set_attr "type" "other")])
13271 (define_expand "prefetch"
13272 [(prefetch (match_operand 0 "address_operand" "p")
13273 (match_operand:SI 1 "const_int_operand" "n")
13274 (match_operand:SI 2 "const_int_operand" "n"))]
13275 "TARGET_HARD_SH4 || TARGET_SH5"
13278 if (GET_MODE (operands[0]) != Pmode
13279 || GET_CODE (operands[1]) != CONST_INT
13280 || GET_CODE (operands[2]) != CONST_INT)
13282 if (! TARGET_SHMEDIA)
13283 operands[0] = force_reg (Pmode, operands[0]);
13286 (define_insn "alloco_i"
13287 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13288 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13294 if (GET_CODE (operands[0]) == PLUS)
13296 xops[0] = XEXP (operands[0], 0);
13297 xops[1] = XEXP (operands[0], 1);
13301 xops[0] = operands[0];
13302 xops[1] = const0_rtx;
13304 output_asm_insn (\"alloco %0, %1\", xops);
13307 [(set_attr "type" "other")])
13310 [(set (match_operand 0 "any_register_operand" "")
13311 (match_operand 1 "" ""))]
13312 "TARGET_SHMEDIA && reload_completed"
13313 [(set (match_dup 0) (match_dup 1))]
13318 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13323 ; Stack Protector Patterns
13325 (define_expand "stack_protect_set"
13326 [(set (match_operand 0 "memory_operand" "")
13327 (match_operand 1 "memory_operand" ""))]
13330 if (TARGET_SHMEDIA)
13332 if (TARGET_SHMEDIA64)
13333 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13335 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13338 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13343 (define_insn "stack_protect_set_si"
13344 [(set (match_operand:SI 0 "memory_operand" "=m")
13345 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13346 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13348 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13349 [(set_attr "type" "other")
13350 (set_attr "length" "6")])
13352 (define_insn "stack_protect_set_si_media"
13353 [(set (match_operand:SI 0 "memory_operand" "=m")
13354 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13355 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13357 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13358 [(set_attr "type" "other")
13359 (set_attr "length" "12")])
13361 (define_insn "stack_protect_set_di_media"
13362 [(set (match_operand:DI 0 "memory_operand" "=m")
13363 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13364 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13366 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13367 [(set_attr "type" "other")
13368 (set_attr "length" "12")])
13370 (define_expand "stack_protect_test"
13371 [(match_operand 0 "memory_operand" "")
13372 (match_operand 1 "memory_operand" "")
13373 (match_operand 2 "" "")]
13376 if (TARGET_SHMEDIA)
13378 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13380 if (TARGET_SHMEDIA64)
13381 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13384 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13387 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13391 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13392 emit_jump_insn (gen_branch_true (operands[2]));
13398 (define_insn "stack_protect_test_si"
13399 [(set (reg:SI T_REG)
13400 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13401 (match_operand:SI 1 "memory_operand" "m")]
13403 (set (match_scratch:SI 2 "=&r") (const_int 0))
13404 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13406 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13407 [(set_attr "type" "other")
13408 (set_attr "length" "10")])
13410 (define_insn "stack_protect_test_si_media"
13411 [(set (match_operand:SI 0 "register_operand" "=&r")
13412 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13413 (match_operand:SI 2 "memory_operand" "m")]
13415 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13417 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13418 [(set_attr "type" "other")
13419 (set_attr "length" "16")])
13421 (define_insn "stack_protect_test_di_media"
13422 [(set (match_operand:DI 0 "register_operand" "=&r")
13423 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13424 (match_operand:DI 2 "memory_operand" "m")]
13426 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13428 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13429 [(set_attr "type" "other")
13430 (set_attr "length" "16")])