1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005 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, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, 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)
154 ;; These are used with unspec_volatile.
160 (UNSPECV_WINDOW_END 10)
161 (UNSPECV_CONST_END 11)
164 ;; -------------------------------------------------------------------------
166 ;; -------------------------------------------------------------------------
171 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
172 (const (symbol_ref "sh_cpu_attr")))
174 (define_attr "endian" "big,little"
175 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
176 (const_string "little") (const_string "big"))))
178 ;; Indicate if the default fpu mode is single precision.
179 (define_attr "fpu_single" "yes,no"
180 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
181 (const_string "yes") (const_string "no"))))
183 (define_attr "fmovd" "yes,no"
184 (const (if_then_else (symbol_ref "TARGET_FMOVD")
185 (const_string "yes") (const_string "no"))))
187 (define_attr "pipe_model" "sh1,sh4,sh5media"
189 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
190 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
191 (const_string "sh1"))))
193 ;; cbranch conditional branch instructions
194 ;; jump unconditional jumps
195 ;; arith ordinary arithmetic
196 ;; arith3 a compound insn that behaves similarly to a sequence of
197 ;; three insns of type arith
198 ;; arith3b like above, but might end with a redirected branch
200 ;; load_si Likewise, SImode variant for general register.
201 ;; fload Likewise, but load to fp register.
203 ;; move general purpose register to register
204 ;; mt_group other sh4 mt instructions
205 ;; fmove register to register, floating point
206 ;; smpy word precision integer multiply
207 ;; dmpy longword or doublelongword precision integer multiply
209 ;; pload load of pr reg, which can't be put into delay slot of rts
210 ;; prset copy register to pr reg, ditto
211 ;; pstore store of pr reg, which can't be put into delay slot of jsr
212 ;; prget copy pr to register, ditto
213 ;; pcload pc relative load of constant value
214 ;; pcfload Likewise, but load to fp register.
215 ;; pcload_si Likewise, SImode variant for general register.
216 ;; rte return from exception
217 ;; sfunc special function call with known used registers
218 ;; call function call
220 ;; fdiv floating point divide (or square root)
221 ;; gp_fpul move from general purpose register to fpul
222 ;; fpul_gp move from fpul to general purpose register
223 ;; mac_gp move from mac[lh] to general purpose register
224 ;; dfp_arith, dfp_cmp,dfp_conv
225 ;; ftrc_s fix_truncsfsi2_i4
226 ;; dfdiv double precision floating point divide (or square root)
227 ;; cwb ic_invalidate_line_i
228 ;; movua SH4a unaligned load
229 ;; fsrra square root reciprocal approximate
230 ;; fsca sine and cosine approximate
231 ;; tls_load load TLS related address
232 ;; arith_media SHmedia arithmetic, logical, and shift instructions
233 ;; cbranch_media SHmedia conditional branch instructions
234 ;; cmp_media SHmedia compare instructions
235 ;; dfdiv_media SHmedia double precision divide and square root
236 ;; dfmul_media SHmedia double precision multiply instruction
237 ;; dfparith_media SHmedia double precision floating point arithmetic
238 ;; dfpconv_media SHmedia double precision floating point conversions
239 ;; dmpy_media SHmedia longword multiply
240 ;; fcmp_media SHmedia floating point compare instructions
241 ;; fdiv_media SHmedia single precision divide and square root
242 ;; fload_media SHmedia floating point register load instructions
243 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
244 ;; fparith_media SHmedia single precision floating point arithmetic
245 ;; fpconv_media SHmedia single precision floating point conversions
246 ;; fstore_media SHmedia floating point register store instructions
247 ;; gettr_media SHmedia gettr instruction
248 ;; invalidate_line_media SHmedia invalidate_line sequence
249 ;; jump_media SHmedia unconditional branch instructions
250 ;; load_media SHmedia general register load instructions
251 ;; pt_media SHmedia pt instruction (expanded by assembler)
252 ;; ptabs_media SHmedia ptabs instruction
253 ;; store_media SHmedia general register store instructions
254 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
255 ;; mac_media SHmedia mac-style fixed point operations
256 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
257 ;; atrans_media SHmedia approximate transcendental functions
258 ;; ustore_media SHmedia unaligned stores
259 ;; nil no-op move, will be deleted.
262 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
263 (const_string "other"))
265 ;; We define a new attribute namely "insn_class".We use
266 ;; this for the DFA based pipeline description.
268 ;; mt_group SH4 "mt" group instructions.
270 ;; ex_group SH4 "ex" group instructions.
272 ;; ls_group SH4 "ls" group instructions.
275 (define_attr "insn_class"
276 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
277 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
278 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
279 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
280 (eq_attr "type" "cbranch,jump") (const_string "br_group")
281 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
282 (const_string "fe_group")
283 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
284 (const_string "none")))
285 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
286 ;; so these do not belong in an insn group, although they are modeled
287 ;; with their own define_insn_reservations.
289 ;; Indicate what precision must be selected in fpscr for this insn, if any.
291 (define_attr "fp_mode" "single,double,none" (const_string "none"))
293 ;; Indicate if the fpu mode is set by this instruction
294 ;; "unknown" must have the value as "none" in fp_mode, and means
295 ;; that the instruction/abi has left the processor in an unknown
297 ;; "none" means that nothing has changed and no mode is set.
298 ;; This attribute is only used for the Renesas ABI.
299 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
301 ; If a conditional branch destination is within -252..258 bytes away
302 ; from the instruction it can be 2 bytes long. Something in the
303 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
304 ; branches are initially assumed to be 16 bytes long.
305 ; In machine_dependent_reorg, we split all branches that are longer than
308 ;; The maximum range used for SImode constant pool entries is 1018. A final
309 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
310 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
311 ;; instruction around the pool table, 2 bytes of alignment before the table,
312 ;; and 30 bytes of alignment after the table. That gives a maximum total
313 ;; pool size of 1058 bytes.
314 ;; Worst case code/pool content size ratio is 1:2 (using asms).
315 ;; Thus, in the worst case, there is one instruction in front of a maximum
316 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
317 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
318 ;; If we have a forward branch, the initial table will be put after the
319 ;; unconditional branch.
321 ;; ??? We could do much better by keeping track of the actual pcloads within
322 ;; the branch range and in the pcload range in front of the branch range.
324 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
326 (define_attr "short_cbranch_p" "no,yes"
327 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
329 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
331 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
333 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
335 ] (const_string "no")))
337 (define_attr "med_branch_p" "no,yes"
338 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
341 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
346 ] (const_string "no")))
348 (define_attr "med_cbranch_p" "no,yes"
349 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
352 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
354 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
357 ] (const_string "no")))
359 (define_attr "braf_branch_p" "no,yes"
360 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
362 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
365 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
367 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
370 ] (const_string "no")))
372 (define_attr "braf_cbranch_p" "no,yes"
373 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
375 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
378 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
380 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
383 ] (const_string "no")))
385 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
386 ; For wider ranges, we need a combination of a code and a data part.
387 ; If we can get a scratch register for a long range jump, the code
388 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
389 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
390 ; long; otherwise, it must be 6 bytes long.
392 ; All other instructions are two bytes long by default.
394 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
395 ;; but getattrtab doesn't understand this.
396 (define_attr "length" ""
397 (cond [(eq_attr "type" "cbranch")
398 (cond [(eq_attr "short_cbranch_p" "yes")
400 (eq_attr "med_cbranch_p" "yes")
402 (eq_attr "braf_cbranch_p" "yes")
404 ;; ??? using pc is not computed transitively.
405 (ne (match_dup 0) (match_dup 0))
407 (ne (symbol_ref ("flag_pic")) (const_int 0))
410 (eq_attr "type" "jump")
411 (cond [(eq_attr "med_branch_p" "yes")
413 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
415 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
416 (symbol_ref "code_for_indirect_jump_scratch")))
417 (cond [(eq_attr "braf_branch_p" "yes")
419 (eq (symbol_ref "flag_pic") (const_int 0))
421 (ne (symbol_ref "TARGET_SH2") (const_int 0))
422 (const_int 10)] (const_int 18))
423 (eq_attr "braf_branch_p" "yes")
425 ;; ??? using pc is not computed transitively.
426 (ne (match_dup 0) (match_dup 0))
428 (ne (symbol_ref ("flag_pic")) (const_int 0))
431 (eq_attr "type" "pt_media")
432 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
433 (const_int 20) (const_int 12))
434 (and (eq_attr "type" "jump_media")
435 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
437 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
441 ;; DFA descriptions for the pipelines
444 (include "shmedia.md")
447 (include "predicates.md")
449 ;; Definitions for filling delay slots
451 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
453 ;; ??? This should be (nil) instead of (const_int 0)
454 (define_attr "hit_stack" "yes,no"
455 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
458 (const_string "yes")))
460 (define_attr "interrupt_function" "no,yes"
461 (const (symbol_ref "current_function_interrupt")))
463 (define_attr "in_delay_slot" "yes,no"
464 (cond [(eq_attr "type" "cbranch") (const_string "no")
465 (eq_attr "type" "pcload,pcload_si") (const_string "no")
466 (eq_attr "needs_delay_slot" "yes") (const_string "no")
467 (eq_attr "length" "2") (const_string "yes")
468 ] (const_string "no")))
470 (define_attr "cond_delay_slot" "yes,no"
471 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
472 ] (const_string "no")))
474 (define_attr "is_sfunc" ""
475 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
477 (define_attr "is_mac_media" ""
478 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
480 (define_attr "branch_zero" "yes,no"
481 (cond [(eq_attr "type" "!cbranch") (const_string "no")
482 (ne (symbol_ref "(next_active_insn (insn)\
483 == (prev_active_insn\
484 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
485 && get_attr_length (next_active_insn (insn)) == 2")
487 (const_string "yes")]
488 (const_string "no")))
490 ;; SH4 Double-precision computation with double-precision result -
491 ;; the two halves are ready at different times.
492 (define_attr "dfp_comp" "yes,no"
493 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
494 (const_string "no")))
496 ;; Insns for which the latency of a preceding fp insn is decreased by one.
497 (define_attr "late_fp_use" "yes,no" (const_string "no"))
498 ;; And feeding insns for which this relevant.
499 (define_attr "any_fp_comp" "yes,no"
500 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
501 (const_string "yes")]
502 (const_string "no")))
504 (define_attr "any_int_load" "yes,no"
505 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
506 (const_string "yes")]
507 (const_string "no")))
509 (define_attr "highpart" "user, ignore, extend, depend, must_split"
510 (const_string "user"))
513 (eq_attr "needs_delay_slot" "yes")
514 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
516 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
517 ;; and thus we can't put a pop instruction in its delay slot.
518 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
519 ;; instruction can go in the delay slot.
521 ;; Since a normal return (rts) implicitly uses the PR register,
522 ;; we can't allow PR register loads in an rts delay slot.
525 (eq_attr "type" "return")
526 [(and (eq_attr "in_delay_slot" "yes")
527 (ior (and (eq_attr "interrupt_function" "no")
528 (eq_attr "type" "!pload,prset"))
529 (and (eq_attr "interrupt_function" "yes")
531 (ne (symbol_ref "TARGET_SH3") (const_int 0))
532 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
534 ;; Since a call implicitly uses the PR register, we can't allow
535 ;; a PR register store in a jsr delay slot.
538 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
539 [(and (eq_attr "in_delay_slot" "yes")
540 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
542 ;; Say that we have annulled true branches, since this gives smaller and
543 ;; faster code when branches are predicted as not taken.
545 ;; ??? The non-annulled condition should really be "in_delay_slot",
546 ;; but insns that can be filled in non-annulled get priority over insns
547 ;; that can only be filled in anulled.
550 (and (eq_attr "type" "cbranch")
551 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
552 ;; SH2e has a hardware bug that pretty much prohibits the use of
553 ;; annuled delay slots.
554 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
555 (not (eq_attr "cpu" "sh2e"))) (nil)])
557 ;; -------------------------------------------------------------------------
558 ;; SImode signed integer comparisons
559 ;; -------------------------------------------------------------------------
563 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
564 (match_operand:SI 1 "arith_operand" "K08,r"))
568 [(set_attr "type" "mt_group")])
570 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
571 ;; That would still allow reload to create cmpi instructions, but would
572 ;; perhaps allow forcing the constant into a register when that is better.
573 ;; Probably should use r0 for mem/imm compares, but force constant into a
574 ;; register for pseudo/imm compares.
576 (define_insn "cmpeqsi_t"
578 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
579 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
585 [(set_attr "type" "mt_group")])
587 (define_insn "cmpgtsi_t"
589 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
590 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
595 [(set_attr "type" "mt_group")])
597 (define_insn "cmpgesi_t"
599 (ge: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 ;; -------------------------------------------------------------------------
608 ;; SImode unsigned integer comparisons
609 ;; -------------------------------------------------------------------------
611 (define_insn "cmpgeusi_t"
613 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
614 (match_operand:SI 1 "arith_reg_operand" "r")))]
617 [(set_attr "type" "mt_group")])
619 (define_insn "cmpgtusi_t"
621 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
622 (match_operand:SI 1 "arith_reg_operand" "r")))]
625 [(set_attr "type" "mt_group")])
627 ;; We save the compare operands in the cmpxx patterns and use them when
628 ;; we generate the branch.
630 (define_expand "cmpsi"
632 (compare (match_operand:SI 0 "cmpsi_operand" "")
633 (match_operand:SI 1 "arith_operand" "")))]
634 "TARGET_SH1 || TARGET_SHMEDIA"
637 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
638 && GET_CODE (operands[1]) != CONST_INT)
639 operands[0] = copy_to_mode_reg (SImode, operands[0]);
640 sh_compare_op0 = operands[0];
641 sh_compare_op1 = operands[1];
645 ;; -------------------------------------------------------------------------
646 ;; DImode signed integer comparisons
647 ;; -------------------------------------------------------------------------
649 ;; ??? Could get better scheduling by splitting the initial test from the
650 ;; rest of the insn after reload. However, the gain would hardly justify
651 ;; the sh.md size increase necessary to do that.
655 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
656 (match_operand:DI 1 "arith_operand" "r"))
659 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
661 [(set_attr "length" "6")
662 (set_attr "type" "arith3b")])
664 (define_insn "cmpeqdi_t"
666 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
667 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
670 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
671 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
672 [(set_attr "length" "6")
673 (set_attr "type" "arith3b")])
677 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
678 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
679 ;; If we applied this split when not optimizing, it would only be
680 ;; applied during the machine-dependent reorg, when no new basic blocks
682 "TARGET_SH1 && reload_completed && optimize"
683 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
684 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
685 (label_ref (match_dup 6))
687 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
692 = gen_rtx_REG (SImode,
693 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
695 = (operands[1] == const0_rtx
697 : gen_rtx_REG (SImode,
698 true_regnum (operands[1])
699 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
700 operands[4] = gen_lowpart (SImode, operands[0]);
701 operands[5] = gen_lowpart (SImode, operands[1]);
702 operands[6] = gen_label_rtx ();
705 (define_insn "cmpgtdi_t"
707 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
708 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
711 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
712 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
713 [(set_attr "length" "8")
714 (set_attr "type" "arith3")])
716 (define_insn "cmpgedi_t"
718 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
719 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
722 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
724 [(set_attr "length" "8,2")
725 (set_attr "type" "arith3,mt_group")])
727 ;; -------------------------------------------------------------------------
728 ;; DImode unsigned integer comparisons
729 ;; -------------------------------------------------------------------------
731 (define_insn "cmpgeudi_t"
733 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
734 (match_operand:DI 1 "arith_reg_operand" "r")))]
736 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
737 [(set_attr "length" "8")
738 (set_attr "type" "arith3")])
740 (define_insn "cmpgtudi_t"
742 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
743 (match_operand:DI 1 "arith_reg_operand" "r")))]
745 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
746 [(set_attr "length" "8")
747 (set_attr "type" "arith3")])
749 (define_insn "cmpeqsi_media"
750 [(set (match_operand:DI 0 "register_operand" "=r")
751 (eq:DI (match_operand:SI 1 "logical_operand" "%r")
752 (match_operand:SI 2 "cmp_operand" "Nr")))]
755 [(set_attr "type" "cmp_media")])
757 (define_insn "cmpeqdi_media"
758 [(set (match_operand:DI 0 "register_operand" "=r")
759 (eq:DI (match_operand:DI 1 "register_operand" "%r")
760 (match_operand:DI 2 "cmp_operand" "Nr")))]
763 [(set_attr "type" "cmp_media")])
765 (define_insn "cmpgtsi_media"
766 [(set (match_operand:DI 0 "register_operand" "=r")
767 (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
768 (match_operand:SI 2 "cmp_operand" "rN")))]
771 [(set_attr "type" "cmp_media")])
773 (define_insn "cmpgtdi_media"
774 [(set (match_operand:DI 0 "register_operand" "=r")
775 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
776 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
779 [(set_attr "type" "cmp_media")])
781 (define_insn "cmpgtusi_media"
782 [(set (match_operand:DI 0 "register_operand" "=r")
783 (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
784 (match_operand:SI 2 "cmp_operand" "rN")))]
786 "cmpgtu %N1, %N2, %0"
787 [(set_attr "type" "cmp_media")])
789 (define_insn "cmpgtudi_media"
790 [(set (match_operand:DI 0 "register_operand" "=r")
791 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
792 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
794 "cmpgtu %N1, %N2, %0"
795 [(set_attr "type" "cmp_media")])
797 (define_insn "cmpsieqsi_media"
798 [(set (match_operand:SI 0 "register_operand" "=r")
799 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
800 (match_operand:SI 2 "cmp_operand" "Nr")))]
803 [(set_attr "type" "cmp_media")])
805 (define_insn "cmpsieqdi_media"
806 [(set (match_operand:SI 0 "register_operand" "=r")
807 (eq:SI (match_operand:DI 1 "register_operand" "%r")
808 (match_operand:DI 2 "cmp_operand" "Nr")))]
811 [(set_attr "type" "cmp_media")])
813 (define_insn "cmpsigtsi_media"
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
816 (match_operand:SI 2 "cmp_operand" "rN")))]
819 [(set_attr "type" "cmp_media")])
821 (define_insn "cmpsigtdi_media"
822 [(set (match_operand:SI 0 "register_operand" "=r")
823 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
824 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827 [(set_attr "type" "cmp_media")])
829 (define_insn "cmpsigtusi_media"
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
832 (match_operand:SI 2 "cmp_operand" "rN")))]
834 "cmpgtu %N1, %N2, %0"
835 [(set_attr "type" "cmp_media")])
837 (define_insn "cmpsigtudi_media"
838 [(set (match_operand:SI 0 "register_operand" "=r")
839 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
840 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
842 "cmpgtu %N1, %N2, %0"
843 [(set_attr "type" "cmp_media")])
845 ; These two patterns are for combine.
846 (define_insn "*cmpne0si_media"
847 [(set (match_operand:DI 0 "register_operand" "=r")
848 (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
851 [(set_attr "type" "cmp_media")])
853 (define_insn "*cmpne0sisi_media"
854 [(set (match_operand:SI 0 "register_operand" "=r")
855 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
858 [(set_attr "type" "cmp_media")])
860 ;; We save the compare operands in the cmpxx patterns and use them when
861 ;; we generate the branch.
863 (define_expand "cmpdi"
865 (compare (match_operand:DI 0 "arith_operand" "")
866 (match_operand:DI 1 "arith_operand" "")))]
867 "TARGET_SH2 || TARGET_SHMEDIA"
870 sh_compare_op0 = operands[0];
871 sh_compare_op1 = operands[1];
874 ;; -------------------------------------------------------------------------
875 ;; Conditional move instructions
876 ;; -------------------------------------------------------------------------
878 ;; The insn names may seem reversed, but note that cmveq performs the move
879 ;; if op1 == 0, and cmvne does it if op1 != 0.
881 (define_insn "movdicc_false"
882 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
883 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
885 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
886 (match_operand:DI 3 "arith_reg_operand" "0")))]
889 [(set_attr "type" "arith_media")])
891 (define_insn "movdicc_true"
892 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
893 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
895 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
896 (match_operand:DI 3 "arith_reg_operand" "0")))]
899 [(set_attr "type" "arith_media")])
902 [(set (match_operand:DI 0 "arith_reg_dest" "")
903 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
904 [(match_operand:DI 1 "arith_reg_operand" "")
906 (match_operand:DI 2 "arith_reg_dest" "")
908 (set (match_dup 2) (match_dup 0))]
909 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
911 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
914 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
915 VOIDmode, operands[1], CONST0_RTX (DImode));
919 [(set (match_operand:DI 0 "general_movdst_operand" "")
920 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
921 (set (match_operand:DI 2 "arith_reg_dest" "")
922 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
923 [(match_operand:DI 3 "arith_reg_operand" "")
927 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
929 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
932 (define_expand "movdicc"
933 [(set (match_operand:DI 0 "register_operand" "")
934 (if_then_else:DI (match_operand 1 "comparison_operator" "")
935 (match_operand:DI 2 "register_operand" "")
936 (match_operand:DI 3 "register_operand" "")))]
940 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
941 && GET_MODE (sh_compare_op0) == DImode
942 && sh_compare_op1 == const0_rtx)
943 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
944 sh_compare_op0, sh_compare_op1);
952 tmp = gen_reg_rtx (DImode);
954 switch (GET_CODE (operands[1]))
957 emit_insn (gen_seq (tmp));
958 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
962 emit_insn (gen_seq (tmp));
963 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
967 emit_insn (gen_sgt (tmp));
968 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
972 emit_insn (gen_slt (tmp));
973 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
977 emit_insn (gen_slt (tmp));
978 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
982 emit_insn (gen_sgt (tmp));
983 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
987 emit_insn (gen_sgtu (tmp));
988 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
992 emit_insn (gen_sltu (tmp));
993 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
997 emit_insn (gen_sltu (tmp));
998 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1002 emit_insn (gen_sgtu (tmp));
1003 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1007 emit_insn (gen_sunordered (tmp));
1008 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1012 emit_insn (gen_sunordered (tmp));
1013 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1030 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1031 ;; SImode to DImode.
1032 (define_insn "movsicc_false"
1033 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1034 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1036 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1037 (match_operand:SI 3 "arith_reg_operand" "0")))]
1040 [(set_attr "type" "arith_media")])
1042 (define_insn "movsicc_true"
1043 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1044 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1046 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1047 (match_operand:SI 3 "arith_reg_operand" "0")))]
1050 [(set_attr "type" "arith_media")])
1053 [(set (match_operand:SI 0 "arith_reg_dest" "")
1054 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1055 [(match_operand:SI 1 "arith_reg_operand" "")
1057 (match_operand:SI 2 "arith_reg_dest" "")
1059 (set (match_dup 2) (match_dup 0))]
1060 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1062 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1065 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1066 VOIDmode, operands[1], CONST0_RTX (SImode));
1070 [(set (match_operand:SI 0 "general_movdst_operand" "")
1071 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1072 (set (match_operand:SI 2 "arith_reg_dest" "")
1073 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1074 [(match_operand:SI 3 "arith_reg_operand" "")
1078 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1079 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1081 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1084 replace_rtx (operands[4], operands[0], operands[1]);
1088 [(set (match_operand 0 "any_register_operand" "")
1089 (match_operand 1 "any_register_operand" ""))
1090 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1091 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1092 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1093 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1094 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1095 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1096 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1097 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1098 && (REGNO_REG_CLASS (REGNO (operands[0]))
1099 == REGNO_REG_CLASS (REGNO (operands[2])))
1100 && (REGNO_REG_CLASS (REGNO (operands[1]))
1101 == REGNO_REG_CLASS (REGNO (operands[0])))"
1102 [(set (match_dup 0) (match_dup 3))
1103 (set (match_dup 4) (match_dup 5))]
1107 rtx replacements[4];
1109 /* We want to replace occurences of operands[0] with operands[1] and
1110 operands[2] with operands[0] in operands[4]/operands[5].
1111 Doing just two replace_rtx calls naiively would result in the second
1112 replacement undoing all that the first did if operands[1] and operands[2]
1113 are identical, so we must do this simultaneously. */
1114 replacements[0] = operands[0];
1115 replacements[1] = operands[1];
1116 replacements[2] = operands[2];
1117 replacements[3] = operands[0];
1118 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1119 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1120 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1123 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1124 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1125 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1126 /* The operands array is aliased to recog_data.operand, which gets
1127 clobbered by extract_insn, so finish with it now. */
1128 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1129 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1130 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1131 always uses emit_insn. */
1132 /* Check that we don't violate matching constraints or earlyclobbers. */
1133 extract_insn (emit_insn (set1));
1134 if (! constrain_operands (1))
1136 extract_insn (emit (set2));
1137 if (! constrain_operands (1))
1141 tmp = replacements[0];
1142 replacements[0] = replacements[1];
1143 replacements[1] = tmp;
1144 tmp = replacements[2];
1145 replacements[2] = replacements[3];
1146 replacements[3] = tmp;
1147 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1148 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1149 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1155 ;; The register allocator is rather clumsy in handling multi-way conditional
1156 ;; moves, so allow the combiner to make them, and we split them up after
1158 (define_insn_and_split "*movsicc_umin"
1159 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1160 (umin:SI (if_then_else:SI
1161 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1163 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1164 (match_operand:SI 3 "register_operand" "0"))
1165 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1166 (clobber (match_scratch:SI 5 "=&r"))]
1167 "TARGET_SHMEDIA && no_new_pseudos"
1169 "TARGET_SHMEDIA && reload_completed"
1173 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1175 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1176 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1181 (define_expand "movsicc"
1182 [(set (match_operand:SI 0 "register_operand" "")
1183 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1184 (match_operand:SI 2 "register_operand" "")
1185 (match_operand:SI 3 "register_operand" "")))]
1189 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1190 && GET_MODE (sh_compare_op0) == SImode
1191 && sh_compare_op1 == const0_rtx)
1192 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1193 sh_compare_op0, sh_compare_op1);
1201 tmp = gen_reg_rtx (SImode);
1203 switch (GET_CODE (operands[1]))
1206 emit_insn (gen_seq (tmp));
1207 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1211 emit_insn (gen_seq (tmp));
1212 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1216 emit_insn (gen_sgt (tmp));
1217 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1221 emit_insn (gen_slt (tmp));
1222 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1226 emit_insn (gen_slt (tmp));
1227 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1231 emit_insn (gen_sgt (tmp));
1232 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1236 emit_insn (gen_sgtu (tmp));
1237 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1241 emit_insn (gen_sltu (tmp));
1242 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1246 emit_insn (gen_sltu (tmp));
1247 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1251 emit_insn (gen_sgtu (tmp));
1252 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1256 emit_insn (gen_sunordered (tmp));
1257 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1261 emit_insn (gen_sunordered (tmp));
1262 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1279 (define_expand "movqicc"
1280 [(set (match_operand:QI 0 "register_operand" "")
1281 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1282 (match_operand:QI 2 "register_operand" "")
1283 (match_operand:QI 3 "register_operand" "")))]
1287 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1288 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1289 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1290 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1294 ;; -------------------------------------------------------------------------
1295 ;; Addition instructions
1296 ;; -------------------------------------------------------------------------
1298 (define_expand "adddi3"
1299 [(set (match_operand:DI 0 "arith_reg_operand" "")
1300 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1301 (match_operand:DI 2 "arith_operand" "")))]
1307 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1309 operands[2] = force_reg (DImode, operands[2]);
1310 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1315 (define_insn "*adddi3_media"
1316 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1317 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1318 (match_operand:DI 2 "arith_operand" "r,I10")))]
1323 [(set_attr "type" "arith_media")])
1325 (define_insn "*adddisi3_media"
1326 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1327 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1328 (match_operand:DI 2 "arith_operand" "r,I10")))]
1333 [(set_attr "type" "arith_media")
1334 (set_attr "highpart" "ignore")])
1336 (define_insn "adddi3z_media"
1337 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1339 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1340 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1342 "addz.l %1, %N2, %0"
1343 [(set_attr "type" "arith_media")
1344 (set_attr "highpart" "ignore")])
1346 (define_insn "adddi3_compact"
1347 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1348 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1349 (match_operand:DI 2 "arith_reg_operand" "r")))
1350 (clobber (reg:SI T_REG))]
1353 [(set_attr "length" "6")])
1356 [(set (match_operand:DI 0 "arith_reg_dest" "")
1357 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1358 (match_operand:DI 2 "arith_reg_operand" "")))
1359 (clobber (reg:SI T_REG))]
1360 "TARGET_SH1 && reload_completed"
1364 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1365 high0 = gen_rtx_REG (SImode,
1366 true_regnum (operands[0])
1367 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1368 high2 = gen_rtx_REG (SImode,
1369 true_regnum (operands[2])
1370 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1371 emit_insn (gen_clrt ());
1372 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1373 emit_insn (gen_addc1 (high0, high0, high2));
1378 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1379 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1380 (match_operand:SI 2 "arith_reg_operand" "r"))
1383 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1386 [(set_attr "type" "arith")])
1388 (define_insn "addc1"
1389 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1390 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1391 (match_operand:SI 2 "arith_reg_operand" "r"))
1393 (clobber (reg:SI T_REG))]
1396 [(set_attr "type" "arith")])
1398 (define_expand "addsi3"
1399 [(set (match_operand:SI 0 "arith_reg_operand" "")
1400 (plus:SI (match_operand:SI 1 "arith_operand" "")
1401 (match_operand:SI 2 "arith_operand" "")))]
1406 operands[1] = force_reg (SImode, operands[1]);
1409 (define_insn "addsi3_media"
1410 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1411 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1412 (match_operand:SI 2 "arith_operand" "r,I10")))]
1417 [(set_attr "type" "arith_media")
1418 (set_attr "highpart" "ignore")])
1420 (define_insn "addsidi3_media"
1421 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1422 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1424 (match_operand:SI 2 "arith_operand"
1430 [(set_attr "type" "arith_media")
1431 (set_attr "highpart" "ignore")])
1433 (define_insn "*addsi3_compact"
1434 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1435 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1436 (match_operand:SI 2 "arith_operand" "rI08")))]
1439 [(set_attr "type" "arith")])
1441 ;; -------------------------------------------------------------------------
1442 ;; Subtraction instructions
1443 ;; -------------------------------------------------------------------------
1445 (define_expand "subdi3"
1446 [(set (match_operand:DI 0 "arith_reg_operand" "")
1447 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1448 (match_operand:DI 2 "arith_reg_operand" "")))]
1454 operands[1] = force_reg (DImode, operands[1]);
1455 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1460 (define_insn "*subdi3_media"
1461 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1462 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1463 (match_operand:DI 2 "arith_reg_operand" "r")))]
1466 [(set_attr "type" "arith_media")])
1468 (define_insn "subdisi3_media"
1469 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1470 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1471 (match_operand:DI 2 "arith_reg_operand" "r")))]
1474 [(set_attr "type" "arith_media")
1475 (set_attr "highpart" "ignore")])
1477 (define_insn "subdi3_compact"
1478 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1479 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1480 (match_operand:DI 2 "arith_reg_operand" "r")))
1481 (clobber (reg:SI T_REG))]
1484 [(set_attr "length" "6")])
1487 [(set (match_operand:DI 0 "arith_reg_dest" "")
1488 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1489 (match_operand:DI 2 "arith_reg_operand" "")))
1490 (clobber (reg:SI T_REG))]
1491 "TARGET_SH1 && reload_completed"
1495 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1496 high0 = gen_rtx_REG (SImode,
1497 true_regnum (operands[0])
1498 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1499 high2 = gen_rtx_REG (SImode,
1500 true_regnum (operands[2])
1501 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1502 emit_insn (gen_clrt ());
1503 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1504 emit_insn (gen_subc1 (high0, high0, high2));
1509 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1510 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1511 (match_operand:SI 2 "arith_reg_operand" "r"))
1514 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1519 [(set_attr "type" "arith")])
1521 (define_insn "subc1"
1522 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1523 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1524 (match_operand:SI 2 "arith_reg_operand" "r"))
1526 (clobber (reg:SI T_REG))]
1529 [(set_attr "type" "arith")])
1531 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1532 ;; pattern for this case. This helps multimedia applications that compute
1533 ;; the sum of absolute differences.
1534 (define_insn "mov_neg_si_t"
1535 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1538 [(set_attr "type" "arith")])
1540 (define_insn "*subsi3_internal"
1541 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1542 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1543 (match_operand:SI 2 "arith_reg_operand" "r")))]
1546 [(set_attr "type" "arith")])
1548 (define_insn_and_split "*subsi3_media"
1549 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1550 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1551 (match_operand:SI 2 "extend_reg_operand" "r")))]
1553 && (operands[1] != constm1_rtx
1554 || (GET_CODE (operands[2]) != TRUNCATE
1555 && GET_CODE (operands[2]) != SUBREG))"
1557 "operands[1] == constm1_rtx"
1558 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1560 [(set_attr "type" "arith_media")
1561 (set_attr "highpart" "ignore")])
1564 [(set (match_operand:SI 0 "arith_reg_dest" "")
1565 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1566 "general_extend_operand"
1568 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1569 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1570 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1574 [(set (match_operand:SI 0 "arith_reg_dest" "")
1575 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1576 "general_extend_operand"
1578 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1579 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1580 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1582 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1583 ;; will sometimes save one instruction. Otherwise we might get
1584 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1587 (define_expand "subsi3"
1588 [(set (match_operand:SI 0 "arith_reg_operand" "")
1589 (minus:SI (match_operand:SI 1 "arith_operand" "")
1590 (match_operand:SI 2 "arith_reg_operand" "")))]
1594 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1596 emit_insn (gen_negsi2 (operands[0], operands[2]));
1597 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1602 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1604 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1605 operands[1] = force_reg (SImode, operands[1]);
1609 ;; -------------------------------------------------------------------------
1610 ;; Division instructions
1611 ;; -------------------------------------------------------------------------
1613 ;; We take advantage of the library routines which don't clobber as many
1614 ;; registers as a normal function call would.
1616 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1617 ;; also has an effect on the register that holds the address of the sfunc.
1618 ;; To make this work, we have an extra dummy insn that shows the use
1619 ;; of this register for reorg.
1621 (define_insn "use_sfunc_addr"
1622 [(set (reg:SI PR_REG)
1623 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1624 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1626 [(set_attr "length" "0")])
1628 (define_insn "udivsi3_sh2a"
1629 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1630 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1631 (match_operand:SI 2 "arith_reg_operand" "z")))]
1634 [(set_attr "type" "arith")
1635 (set_attr "in_delay_slot" "no")])
1637 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1638 ;; hard register 0. If we used hard register 0, then the next instruction
1639 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1640 ;; gets allocated to a stack slot that needs its address reloaded, then
1641 ;; there is nothing to prevent reload from using r0 to reload the address.
1642 ;; This reload would clobber the value in r0 we are trying to store.
1643 ;; If we let reload allocate r0, then this problem can never happen.
1645 (define_insn "udivsi3_i1"
1646 [(set (match_operand:SI 0 "register_operand" "=z")
1647 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1648 (clobber (reg:SI T_REG))
1649 (clobber (reg:SI PR_REG))
1650 (clobber (reg:SI R4_REG))
1651 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1652 "TARGET_SH1 && ! TARGET_SH4"
1654 [(set_attr "type" "sfunc")
1655 (set_attr "needs_delay_slot" "yes")])
1657 ; Since shmedia-nofpu code could be linked against shcompact code, and
1658 ; the udivsi3 libcall has the same name, we must consider all registers
1659 ; clobbered that are in the union of the registers clobbered by the
1660 ; shmedia and the shcompact implementation. Note, if the shcompact
1661 ; implementation actually used shcompact code, we'd need to clobber
1662 ; also r23 and fr23.
1663 (define_insn "udivsi3_i1_media"
1664 [(set (match_operand:SI 0 "register_operand" "=z")
1665 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1666 (clobber (reg:SI T_MEDIA_REG))
1667 (clobber (reg:SI PR_MEDIA_REG))
1668 (clobber (reg:SI R20_REG))
1669 (clobber (reg:SI R21_REG))
1670 (clobber (reg:SI R22_REG))
1671 (clobber (reg:DI TR0_REG))
1672 (clobber (reg:DI TR1_REG))
1673 (clobber (reg:DI TR2_REG))
1674 (use (match_operand 1 "target_operand" "b"))]
1675 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1677 [(set_attr "type" "sfunc")
1678 (set_attr "needs_delay_slot" "yes")])
1680 (define_expand "udivsi3_i4_media"
1682 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1684 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1685 (set (match_dup 5) (float:DF (match_dup 3)))
1686 (set (match_dup 6) (float:DF (match_dup 4)))
1687 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1688 (set (match_dup 8) (fix:DI (match_dup 7)))
1689 (set (match_operand:SI 0 "register_operand" "")
1690 (truncate:SI (match_dup 8)))]
1691 "TARGET_SHMEDIA_FPU"
1694 operands[3] = gen_reg_rtx (DImode);
1695 operands[4] = gen_reg_rtx (DImode);
1696 operands[5] = gen_reg_rtx (DFmode);
1697 operands[6] = gen_reg_rtx (DFmode);
1698 operands[7] = gen_reg_rtx (DFmode);
1699 operands[8] = gen_reg_rtx (DImode);
1702 (define_insn "udivsi3_i4"
1703 [(set (match_operand:SI 0 "register_operand" "=y")
1704 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1705 (clobber (reg:SI T_REG))
1706 (clobber (reg:SI PR_REG))
1707 (clobber (reg:DF DR0_REG))
1708 (clobber (reg:DF DR2_REG))
1709 (clobber (reg:DF DR4_REG))
1710 (clobber (reg:SI R0_REG))
1711 (clobber (reg:SI R1_REG))
1712 (clobber (reg:SI R4_REG))
1713 (clobber (reg:SI R5_REG))
1714 (use (reg:PSI FPSCR_REG))
1715 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1716 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1718 [(set_attr "type" "sfunc")
1719 (set_attr "fp_mode" "double")
1720 (set_attr "needs_delay_slot" "yes")])
1722 (define_insn "udivsi3_i4_single"
1723 [(set (match_operand:SI 0 "register_operand" "=y")
1724 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1725 (clobber (reg:SI T_REG))
1726 (clobber (reg:SI PR_REG))
1727 (clobber (reg:DF DR0_REG))
1728 (clobber (reg:DF DR2_REG))
1729 (clobber (reg:DF DR4_REG))
1730 (clobber (reg:SI R0_REG))
1731 (clobber (reg:SI R1_REG))
1732 (clobber (reg:SI R4_REG))
1733 (clobber (reg:SI R5_REG))
1734 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1735 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1737 [(set_attr "type" "sfunc")
1738 (set_attr "needs_delay_slot" "yes")])
1740 (define_expand "udivsi3"
1741 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1742 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1743 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1744 (parallel [(set (match_operand:SI 0 "register_operand" "")
1745 (udiv:SI (reg:SI R4_REG)
1747 (clobber (reg:SI T_REG))
1748 (clobber (reg:SI PR_REG))
1749 (clobber (reg:SI R4_REG))
1750 (use (match_dup 3))])]
1756 operands[3] = gen_reg_rtx (Pmode);
1757 /* Emit the move of the address to a pseudo outside of the libcall. */
1758 if (TARGET_HARD_SH4 && TARGET_SH2E)
1760 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1761 if (TARGET_FPU_SINGLE)
1762 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1764 last = gen_udivsi3_i4 (operands[0], operands[3]);
1766 else if (TARGET_SHMEDIA_FPU)
1768 operands[1] = force_reg (SImode, operands[1]);
1769 operands[2] = force_reg (SImode, operands[2]);
1770 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1773 else if (TARGET_SH2A)
1775 operands[1] = force_reg (SImode, operands[1]);
1776 operands[2] = force_reg (SImode, operands[2]);
1777 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1780 else if (TARGET_SH5)
1782 function_symbol (operands[3],
1783 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1787 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1788 else if (TARGET_FPU_ANY)
1789 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1791 last = gen_udivsi3_i1 (operands[0], operands[3]);
1795 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1796 last = gen_udivsi3_i1 (operands[0], operands[3]);
1798 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1799 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1800 last = emit_insn (last);
1801 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1802 invariant code motion can move it. */
1803 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1804 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1808 (define_insn "divsi3_sh2a"
1809 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1810 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1811 (match_operand:SI 2 "arith_reg_operand" "z")))]
1814 [(set_attr "type" "arith")
1815 (set_attr "in_delay_slot" "no")])
1817 (define_insn "divsi3_i1"
1818 [(set (match_operand:SI 0 "register_operand" "=z")
1819 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1820 (clobber (reg:SI T_REG))
1821 (clobber (reg:SI PR_REG))
1822 (clobber (reg:SI R1_REG))
1823 (clobber (reg:SI R2_REG))
1824 (clobber (reg:SI R3_REG))
1825 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1826 "TARGET_SH1 && ! TARGET_SH4"
1828 [(set_attr "type" "sfunc")
1829 (set_attr "needs_delay_slot" "yes")])
1831 (define_insn "divsi3_i1_media"
1832 [(set (match_operand:SI 0 "register_operand" "=z")
1833 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1834 (clobber (reg:SI T_MEDIA_REG))
1835 (clobber (reg:SI PR_MEDIA_REG))
1836 (clobber (reg:SI R1_REG))
1837 (clobber (reg:SI R20_REG))
1838 (clobber (reg:SI R21_REG))
1839 (clobber (reg:SI TR0_REG))
1840 (use (match_operand 1 "target_operand" "b"))]
1841 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1843 [(set_attr "type" "sfunc")])
1845 (define_insn "divsi3_media_2"
1846 [(set (match_operand:SI 0 "register_operand" "=z")
1847 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1848 (clobber (reg:SI T_MEDIA_REG))
1849 (clobber (reg:SI PR_MEDIA_REG))
1850 (clobber (reg:SI R1_REG))
1851 (clobber (reg:SI R21_REG))
1852 (clobber (reg:SI TR0_REG))
1853 (use (reg:SI R20_REG))
1854 (use (match_operand 1 "target_operand" "b"))]
1855 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1857 [(set_attr "type" "sfunc")])
1859 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1860 ;; hard reg clobbers and data dependencies that we need when we want
1861 ;; to rematerialize the division into a call.
1862 (define_insn_and_split "divsi_inv_call"
1863 [(set (match_operand:SI 0 "register_operand" "=r")
1864 (div:SI (match_operand:SI 1 "register_operand" "r")
1865 (match_operand:SI 2 "register_operand" "r")))
1866 (clobber (reg:SI R4_REG))
1867 (clobber (reg:SI R5_REG))
1868 (clobber (reg:SI T_MEDIA_REG))
1869 (clobber (reg:SI PR_MEDIA_REG))
1870 (clobber (reg:SI R1_REG))
1871 (clobber (reg:SI R21_REG))
1872 (clobber (reg:SI TR0_REG))
1873 (clobber (reg:SI R20_REG))
1874 (use (match_operand:SI 3 "register_operand" "r"))]
1877 "&& (high_life_started || reload_completed)"
1878 [(set (match_dup 0) (match_dup 3))]
1880 [(set_attr "highpart" "must_split")])
1882 ;; This is the combiner pattern for -mdiv=inv:call .
1883 (define_insn_and_split "*divsi_inv_call_combine"
1884 [(set (match_operand:SI 0 "register_operand" "=z")
1885 (div:SI (match_operand:SI 1 "register_operand" "r")
1886 (match_operand:SI 2 "register_operand" "r")))
1887 (clobber (reg:SI R4_REG))
1888 (clobber (reg:SI R5_REG))
1889 (clobber (reg:SI T_MEDIA_REG))
1890 (clobber (reg:SI PR_MEDIA_REG))
1891 (clobber (reg:SI R1_REG))
1892 (clobber (reg:SI R21_REG))
1893 (clobber (reg:SI TR0_REG))
1894 (clobber (reg:SI R20_REG))
1895 (use (unspec:SI [(match_dup 1)
1896 (match_operand:SI 3 "" "")
1897 (unspec:SI [(match_operand:SI 4 "" "")
1899 (match_operand:DI 5 "" "")]
1901 (match_operand:DI 6 "" "")
1904 UNSPEC_DIV_INV_M3))]
1907 "&& (high_life_started || reload_completed)"
1911 const char *name = sh_divsi3_libfunc;
1912 enum sh_function_kind kind = SFUNC_GOT;
1915 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1916 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1917 while (TARGET_DIVIDE_INV_CALL2)
1919 rtx x = operands[3];
1921 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1923 x = XVECEXP (x, 0, 0);
1924 name = \"__sdivsi3_2\";
1925 kind = SFUNC_STATIC;
1926 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1929 sym = function_symbol (NULL, name, kind);
1930 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1933 [(set_attr "highpart" "must_split")])
1935 (define_expand "divsi3_i4_media"
1936 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1937 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1938 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1939 (set (match_operand:SI 0 "register_operand" "=r")
1940 (fix:SI (match_dup 5)))]
1941 "TARGET_SHMEDIA_FPU"
1944 operands[3] = gen_reg_rtx (DFmode);
1945 operands[4] = gen_reg_rtx (DFmode);
1946 operands[5] = gen_reg_rtx (DFmode);
1949 (define_insn "divsi3_i4"
1950 [(set (match_operand:SI 0 "register_operand" "=y")
1951 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1952 (clobber (reg:SI PR_REG))
1953 (clobber (reg:DF DR0_REG))
1954 (clobber (reg:DF DR2_REG))
1955 (use (reg:PSI FPSCR_REG))
1956 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1957 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1959 [(set_attr "type" "sfunc")
1960 (set_attr "fp_mode" "double")
1961 (set_attr "needs_delay_slot" "yes")])
1963 (define_insn "divsi3_i4_single"
1964 [(set (match_operand:SI 0 "register_operand" "=y")
1965 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1966 (clobber (reg:SI PR_REG))
1967 (clobber (reg:DF DR0_REG))
1968 (clobber (reg:DF DR2_REG))
1969 (clobber (reg:SI R2_REG))
1970 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1971 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1973 [(set_attr "type" "sfunc")
1974 (set_attr "needs_delay_slot" "yes")])
1976 (define_expand "divsi3"
1977 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1978 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1979 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1980 (parallel [(set (match_operand:SI 0 "register_operand" "")
1981 (div:SI (reg:SI R4_REG)
1983 (clobber (reg:SI T_REG))
1984 (clobber (reg:SI PR_REG))
1985 (clobber (reg:SI R1_REG))
1986 (clobber (reg:SI R2_REG))
1987 (clobber (reg:SI R3_REG))
1988 (use (match_dup 3))])]
1994 operands[3] = gen_reg_rtx (Pmode);
1995 /* Emit the move of the address to a pseudo outside of the libcall. */
1996 if (TARGET_HARD_SH4 && TARGET_SH2E)
1998 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
1999 if (TARGET_FPU_SINGLE)
2000 last = gen_divsi3_i4_single (operands[0], operands[3]);
2002 last = gen_divsi3_i4 (operands[0], operands[3]);
2004 else if (TARGET_SH2A)
2006 operands[1] = force_reg (SImode, operands[1]);
2007 operands[2] = force_reg (SImode, operands[2]);
2008 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2011 else if (TARGET_DIVIDE_INV)
2013 rtx dividend = operands[1];
2014 rtx divisor = operands[2];
2016 rtx nsb_res = gen_reg_rtx (DImode);
2017 rtx norm64 = gen_reg_rtx (DImode);
2018 rtx tab_ix = gen_reg_rtx (DImode);
2019 rtx norm32 = gen_reg_rtx (SImode);
2020 rtx i92 = force_reg (DImode, GEN_INT (92));
2021 rtx scratch0a = gen_reg_rtx (DImode);
2022 rtx scratch0b = gen_reg_rtx (DImode);
2023 rtx inv0 = gen_reg_rtx (SImode);
2024 rtx scratch1a = gen_reg_rtx (DImode);
2025 rtx scratch1b = gen_reg_rtx (DImode);
2026 rtx shift = gen_reg_rtx (DImode);
2028 rtx inv1 = gen_reg_rtx (SImode);
2029 rtx scratch2a = gen_reg_rtx (DImode);
2030 rtx scratch2b = gen_reg_rtx (SImode);
2031 rtx inv2 = gen_reg_rtx (SImode);
2032 rtx scratch3a = gen_reg_rtx (DImode);
2033 rtx scratch3b = gen_reg_rtx (DImode);
2034 rtx scratch3c = gen_reg_rtx (DImode);
2035 rtx scratch3d = gen_reg_rtx (SImode);
2036 rtx scratch3e = gen_reg_rtx (DImode);
2037 rtx result = gen_reg_rtx (SImode);
2039 if (! arith_reg_or_0_operand (dividend, SImode))
2040 dividend = force_reg (SImode, dividend);
2041 if (! arith_reg_operand (divisor, SImode))
2042 divisor = force_reg (SImode, divisor);
2043 if (flag_pic && Pmode != DImode)
2045 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2046 tab_base = gen_datalabel_ref (tab_base);
2047 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2051 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2052 tab_base = gen_datalabel_ref (tab_base);
2053 tab_base = force_reg (DImode, tab_base);
2055 if (TARGET_DIVIDE_INV20U)
2056 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2058 i2p27 = GEN_INT (0);
2059 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2060 i43 = force_reg (DImode, GEN_INT (43));
2063 emit_insn (gen_nsbdi (nsb_res,
2064 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2065 emit_insn (gen_ashldi3_media (norm64,
2066 gen_rtx_SUBREG (DImode, divisor, 0),
2068 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2069 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2070 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2071 inv0, scratch0a, scratch0b,
2072 scratch1a, scratch1b));
2073 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2074 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2076 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2078 scratch3a, scratch3b, scratch3c,
2079 scratch2a, scratch2b, scratch3d, scratch3e));
2080 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2081 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2082 else if (TARGET_DIVIDE_INV_FP)
2083 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2084 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2085 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2086 gen_reg_rtx (DFmode)));
2088 emit_move_insn (operands[0], result);
2091 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2093 operands[1] = force_reg (SImode, operands[1]);
2094 operands[2] = force_reg (SImode, operands[2]);
2095 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2098 else if (TARGET_SH5)
2100 if (TARGET_DIVIDE_CALL2)
2102 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2103 tab_base = gen_datalabel_ref (tab_base);
2104 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2106 if (TARGET_FPU_ANY && TARGET_SH1)
2107 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2108 else if (TARGET_DIVIDE_CALL2)
2109 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2111 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2114 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2115 (operands[0], operands[3]));
2116 else if (TARGET_FPU_ANY)
2117 last = gen_divsi3_i4_single (operands[0], operands[3]);
2119 last = gen_divsi3_i1 (operands[0], operands[3]);
2123 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2124 last = gen_divsi3_i1 (operands[0], operands[3]);
2126 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2127 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2128 last = emit_insn (last);
2129 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2130 invariant code motion can move it. */
2131 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2132 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2136 ;; operands: inv0, tab_base, tab_ix, norm32
2137 ;; scratch equiv in sdivsi3_2: r19, r21
2138 (define_expand "divsi_inv_m0"
2139 [(set (match_operand:SI 0 "register_operand" "=r")
2140 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2141 (match_operand:DI 2 "register_operand" "r")
2142 (match_operand:SI 3 "register_operand" "r")]
2144 (clobber (match_operand:DI 4 "register_operand" "=r"))
2145 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2153 ldx.ub r20, r21, r19 // u0.8
2155 muls.l r25, r19, r19 // s2.38
2156 ldx.w r20, r21, r21 // s2.14
2157 shari r19, 24, r19 // truncate to s2.14
2158 sub r21, r19, r19 // some 11 bit inverse in s1.14
2161 rtx inv0 = operands[0];
2162 rtx tab_base = operands[1];
2163 rtx tab_ix = operands[2];
2164 rtx norm32 = operands[3];
2165 rtx scratch0 = operands[4];
2166 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2167 rtx scratch1 = operands[5];
2170 mem = gen_rtx_MEM (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2171 emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2172 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2173 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2174 mem = gen_rtx_MEM (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2175 emit_insn (gen_extendhidi2 (scratch1, mem));
2176 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2177 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2181 ;; operands: inv1, tab_base, tab_ix, norm32
2182 (define_insn_and_split "divsi_inv_m1"
2183 [(set (match_operand:SI 0 "register_operand" "=r")
2184 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2185 (match_operand:DI 2 "register_operand" "r")
2186 (match_operand:SI 3 "register_operand" "r")]
2188 (clobber (match_operand:SI 4 "register_operand" "=r"))
2189 (clobber (match_operand:DI 5 "register_operand" "=r"))
2190 (clobber (match_operand:DI 6 "register_operand" "=r"))
2191 (clobber (match_operand:DI 7 "register_operand" "=r"))
2192 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2200 muls.l r19, r19, r18 // u0.28
2201 muls.l r25, r18, r18 // s2.58
2202 shlli r19, 45, r0 // multiply by two and convert to s2.58
2204 shari r18, 28, r18 // some 18 bit inverse in s1.30
2207 rtx inv1 = operands[0];
2208 rtx tab_base = operands[1];
2209 rtx tab_ix = operands[2];
2210 rtx norm32 = operands[3];
2211 rtx inv0 = operands[4];
2212 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2213 rtx scratch0a = operands[5];
2214 rtx scratch0b = operands[6];
2215 rtx scratch0 = operands[7];
2216 rtx scratch1 = operands[8];
2217 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2219 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2220 scratch0a, scratch0b));
2221 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2222 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2223 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2224 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2225 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2229 ;; operands: inv2, norm32, inv1, i92
2230 (define_insn_and_split "divsi_inv_m2"
2231 [(set (match_operand:SI 0 "register_operand" "=r")
2232 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2233 (match_operand:SI 2 "register_operand" "r")
2234 (match_operand:DI 3 "register_operand" "r")]
2236 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2244 muls.l r18, r25, r0 // s2.60
2245 shari r0, 16, r0 // s-16.44
2247 muls.l r0, r18, r19 // s-16.74
2248 shari r19, 30, r19 // s-16.44
2250 rtx inv2 = operands[0];
2251 rtx norm32 = operands[1];
2252 rtx inv1 = operands[2];
2253 rtx i92 = operands[3];
2254 rtx scratch0 = operands[4];
2255 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2257 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2258 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2259 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2260 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2261 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2265 (define_insn_and_split "divsi_inv_m3"
2266 [(set (match_operand:SI 0 "register_operand" "=r")
2267 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2268 (match_operand:SI 2 "register_operand" "r")
2269 (match_operand:SI 3 "register_operand" "r")
2270 (match_operand:DI 4 "register_operand" "r")
2271 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2272 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2274 (clobber (match_operand:DI 7 "register_operand" "=r"))
2275 (clobber (match_operand:DI 8 "register_operand" "=r"))
2276 (clobber (match_operand:DI 9 "register_operand" "=r"))
2277 (clobber (match_operand:DI 10 "register_operand" "=r"))
2278 (clobber (match_operand:SI 11 "register_operand" "=r"))
2279 (clobber (match_operand:SI 12 "register_operand" "=r"))
2280 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2288 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2289 r0: scratch0 r19: scratch1 r21: scratch2
2291 muls.l r18, r4, r25 // s32.30
2292 muls.l r19, r4, r19 // s15.30
2294 shari r19, 14, r19 // s18.-14
2300 rtx result = operands[0];
2301 rtx dividend = operands[1];
2302 rtx inv1 = operands[2];
2303 rtx inv2 = operands[3];
2304 rtx shift = operands[4];
2305 rtx scratch0 = operands[7];
2306 rtx scratch1 = operands[8];
2307 rtx scratch2 = operands[9];
2309 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2310 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2311 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2312 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2313 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2314 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2315 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2319 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2320 ;; inv1: tab_base, tab_ix, norm32
2321 ;; inv2: norm32, inv1, i92
2322 (define_insn_and_split "divsi_inv_m1_3"
2323 [(set (match_operand:SI 0 "register_operand" "=r")
2324 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2325 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2326 (match_operand:DI 3 "register_operand" "r")
2327 (match_operand:SI 4 "register_operand" "r")]
2329 (unspec:SI [(match_dup 4)
2330 (unspec:SI [(match_dup 2)
2332 (match_dup 4)] UNSPEC_DIV_INV_M1)
2333 (match_operand:SI 5 "" "")]
2335 (match_operand:DI 6 "register_operand" "r")
2336 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2337 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2339 (clobber (match_operand:DI 9 "register_operand" "=r"))
2340 (clobber (match_operand:DI 10 "register_operand" "=r"))
2341 (clobber (match_operand:DI 11 "register_operand" "=r"))
2342 (clobber (match_operand:DI 12 "register_operand" "=r"))
2343 (clobber (match_operand:SI 13 "register_operand" "=r"))
2344 (clobber (match_operand:SI 14 "register_operand" "=r"))
2345 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2347 && (TARGET_DIVIDE_INV_MINLAT
2348 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2354 rtx result = operands[0];
2355 rtx dividend = operands[1];
2356 rtx tab_base = operands[2];
2357 rtx tab_ix = operands[3];
2358 rtx norm32 = operands[4];
2359 /* rtx i92 = operands[5]; */
2360 rtx shift = operands[6];
2361 rtx i2p27 = operands[7];
2362 rtx i43 = operands[8];
2363 rtx scratch0 = operands[9];
2364 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2365 rtx scratch1 = operands[10];
2366 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2367 rtx scratch2 = operands[11];
2368 rtx scratch3 = operands[12];
2369 rtx scratch4 = operands[13];
2370 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2371 rtx scratch5 = operands[14];
2372 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2373 rtx scratch6 = operands[15];
2375 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2376 scratch0, scratch1));
2377 /* inv0 == scratch4 */
2378 if (! TARGET_DIVIDE_INV20U)
2380 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2382 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2386 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2387 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2389 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2390 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2391 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2392 /* inv1 == scratch4 */
2394 if (TARGET_DIVIDE_INV_MINLAT)
2396 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2397 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2398 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2399 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2400 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2401 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2402 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2403 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2404 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2405 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2406 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2410 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2411 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2412 emit_insn (gen_nsbdi (scratch6,
2413 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2414 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2415 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2416 emit_insn (gen_divsi_inv20 (scratch2,
2417 norm32, scratch4, dividend,
2418 scratch6, scratch3, i43,
2419 /* scratch0 may be shared with i2p27. */
2420 scratch0, scratch1, scratch5,
2421 label, label, i2p27));
2423 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2424 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2428 (define_insn "divsi_inv20"
2429 [(set (match_operand:DI 0 "register_operand" "=&r")
2430 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
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 "register_operand" "r")
2435 (match_operand:DI 6 "register_operand" "r")
2436 (match_operand:DI 12 "register_operand" "r")
2437 (match_operand 10 "target_operand" "b")
2438 (match_operand 11 "immediate_operand" "i")]
2440 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2441 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2442 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2444 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2447 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2448 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2449 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2450 %10 label (tr), %11 label (imm)
2452 muls.l inv1, norm32, scratch0 // s2.60
2453 muls.l inv1, dividend, result // s32.30
2454 xor i2p27, result_sign, round_scratch
2455 bge/u dividend_nsb, i43, tr.. (label)
2456 shari scratch0, 16, scratch0 // s-16.44
2457 muls.l sratch0_si, inv1, scratch0 // s-16.74
2458 sub result, round_scratch, result
2459 shari dividend, 14, scratch1 // s19.-14
2460 shari scratch0, 30, scratch0 // s-16.44
2461 muls.l scratch0, scratch1, round_scratch // s15.30
2463 sub result, round_scratch, result */
2465 int likely = TARGET_DIVIDE_INV20L;
2467 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2468 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2469 output_asm_insn (likely
2470 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2471 : \"bge/u\t%4, %6, %10\", operands);
2472 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2473 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2474 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2476 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2477 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2480 (define_insn_and_split "divsi_inv_fp"
2481 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2482 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2483 (match_operand:SI 2 "register_operand" "rf")))
2484 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2485 (clobber (match_operand:SI 4 "register_operand" "=r"))
2486 (clobber (match_operand:SI 5 "register_operand" "=r"))
2487 (clobber (match_operand:DF 6 "register_operand" "=r"))
2488 (clobber (match_operand:DF 7 "register_operand" "=r"))
2489 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2490 "TARGET_SHMEDIA_FPU"
2492 "&& (high_life_started || reload_completed)"
2493 [(set (match_dup 0) (match_dup 3))]
2495 [(set_attr "highpart" "must_split")])
2497 ;; If a matching group of divide-by-inverse instructions is in the same
2498 ;; basic block after gcse & loop optimizations, we want to transform them
2499 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2500 (define_insn_and_split "*divsi_inv_fp_combine"
2501 [(set (match_operand:SI 0 "register_operand" "=f")
2502 (div:SI (match_operand:SI 1 "register_operand" "f")
2503 (match_operand:SI 2 "register_operand" "f")))
2504 (use (unspec:SI [(match_dup 1)
2505 (match_operand:SI 3 "" "")
2506 (unspec:SI [(match_operand:SI 4 "" "")
2508 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2509 (match_operand:DI 6 "" "")
2511 (const_int 0)] UNSPEC_DIV_INV_M3))
2512 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2513 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2514 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2515 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2516 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2517 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2520 [(set (match_dup 9) (float:DF (match_dup 1)))
2521 (set (match_dup 10) (float:DF (match_dup 2)))
2522 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2524 (fix:SI (match_dup 11)))
2525 (set (match_dup 0) (match_dup 8))]
2528 if (! fp_arith_reg_operand (operands[1], SImode))
2530 emit_move_insn (operands[7], operands[1]);
2531 operands[1] = operands[7];
2533 if (! fp_arith_reg_operand (operands[2], SImode))
2535 emit_move_insn (operands[8], operands[2]);
2536 operands[2] = operands[8];
2539 [(set_attr "highpart" "must_split")])
2541 ;; -------------------------------------------------------------------------
2542 ;; Multiplication instructions
2543 ;; -------------------------------------------------------------------------
2545 (define_insn "umulhisi3_i"
2546 [(set (reg:SI MACL_REG)
2547 (mult:SI (zero_extend:SI
2548 (match_operand:HI 0 "arith_reg_operand" "r"))
2550 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2553 [(set_attr "type" "smpy")])
2555 (define_insn "mulhisi3_i"
2556 [(set (reg:SI MACL_REG)
2557 (mult:SI (sign_extend:SI
2558 (match_operand:HI 0 "arith_reg_operand" "r"))
2560 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2563 [(set_attr "type" "smpy")])
2565 (define_expand "mulhisi3"
2566 [(set (reg:SI MACL_REG)
2567 (mult:SI (sign_extend:SI
2568 (match_operand:HI 1 "arith_reg_operand" ""))
2570 (match_operand:HI 2 "arith_reg_operand" ""))))
2571 (set (match_operand:SI 0 "arith_reg_operand" "")
2578 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2579 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2580 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2581 invariant code motion can move it. */
2582 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2583 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2584 /* expand_binop can't find a suitable code in umul_widen_optab to
2585 make a REG_EQUAL note from, so make one here.
2586 See also smulsi3_highpart.
2587 ??? Alternatively, we could put this at the calling site of expand_binop,
2588 i.e. expand_expr. */
2590 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2595 (define_expand "umulhisi3"
2596 [(set (reg:SI MACL_REG)
2597 (mult:SI (zero_extend:SI
2598 (match_operand:HI 1 "arith_reg_operand" ""))
2600 (match_operand:HI 2 "arith_reg_operand" ""))))
2601 (set (match_operand:SI 0 "arith_reg_operand" "")
2608 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2609 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2610 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2611 invariant code motion can move it. */
2612 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2613 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2614 /* expand_binop can't find a suitable code in umul_widen_optab to
2615 make a REG_EQUAL note from, so make one here.
2616 See also smulsi3_highpart.
2617 ??? Alternatively, we could put this at the calling site of expand_binop,
2618 i.e. expand_expr. */
2620 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2625 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2626 ;; a call to a routine which clobbers known registers.
2629 [(set (match_operand:SI 1 "register_operand" "=z")
2630 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2631 (clobber (reg:SI MACL_REG))
2632 (clobber (reg:SI T_REG))
2633 (clobber (reg:SI PR_REG))
2634 (clobber (reg:SI R3_REG))
2635 (clobber (reg:SI R2_REG))
2636 (clobber (reg:SI R1_REG))
2637 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2640 [(set_attr "type" "sfunc")
2641 (set_attr "needs_delay_slot" "yes")])
2643 (define_expand "mulsi3_call"
2644 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2645 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2646 (parallel[(set (match_operand:SI 0 "register_operand" "")
2647 (mult:SI (reg:SI R4_REG)
2649 (clobber (reg:SI MACL_REG))
2650 (clobber (reg:SI T_REG))
2651 (clobber (reg:SI PR_REG))
2652 (clobber (reg:SI R3_REG))
2653 (clobber (reg:SI R2_REG))
2654 (clobber (reg:SI R1_REG))
2655 (use (match_operand:SI 3 "register_operand" ""))])]
2659 (define_insn "mul_r"
2660 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2661 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2662 (match_operand:SI 2 "arith_reg_operand" "z")))]
2665 [(set_attr "type" "dmpy")])
2667 (define_insn "mul_l"
2668 [(set (reg:SI MACL_REG)
2669 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2670 (match_operand:SI 1 "arith_reg_operand" "r")))]
2673 [(set_attr "type" "dmpy")])
2675 (define_expand "mulsi3"
2676 [(set (reg:SI MACL_REG)
2677 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2678 (match_operand:SI 2 "arith_reg_operand" "")))
2679 (set (match_operand:SI 0 "arith_reg_operand" "")
2688 /* The address must be set outside the libcall,
2689 since it goes into a pseudo. */
2690 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2691 rtx addr = force_reg (SImode, sym);
2692 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2695 last = emit_insn (insns);
2699 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2701 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2702 /* consec_sets_giv can only recognize the first insn that sets a
2703 giv as the giv insn. So we must tag this also with a REG_EQUAL
2705 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2707 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2708 invariant code motion can move it. */
2709 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2710 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2714 (define_insn "mulsidi3_i"
2715 [(set (reg:SI MACH_REG)
2719 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2720 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2722 (set (reg:SI MACL_REG)
2723 (mult:SI (match_dup 0)
2727 [(set_attr "type" "dmpy")])
2729 (define_expand "mulsidi3"
2730 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2731 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2732 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2733 "TARGET_SH2 || TARGET_SHMEDIA"
2738 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2744 (define_insn "mulsidi3_media"
2745 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2746 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2747 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2750 [(set_attr "type" "dmpy_media")
2751 (set_attr "highpart" "ignore")])
2753 (define_insn "mulsidi3_compact"
2754 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2756 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2757 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2758 (clobber (reg:SI MACH_REG))
2759 (clobber (reg:SI MACL_REG))]
2764 [(set (match_operand:DI 0 "arith_reg_dest" "")
2766 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2767 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2768 (clobber (reg:SI MACH_REG))
2769 (clobber (reg:SI MACL_REG))]
2774 rtx low_dst = gen_lowpart (SImode, operands[0]);
2775 rtx high_dst = gen_highpart (SImode, operands[0]);
2777 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2779 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2780 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2781 /* We need something to tag the possible REG_EQUAL notes on to. */
2782 emit_move_insn (operands[0], operands[0]);
2786 (define_insn "umulsidi3_i"
2787 [(set (reg:SI MACH_REG)
2791 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2792 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2794 (set (reg:SI MACL_REG)
2795 (mult:SI (match_dup 0)
2799 [(set_attr "type" "dmpy")])
2801 (define_expand "umulsidi3"
2802 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2803 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2804 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2805 "TARGET_SH2 || TARGET_SHMEDIA"
2810 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2816 (define_insn "umulsidi3_media"
2817 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2818 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2819 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2822 [(set_attr "type" "dmpy_media")
2823 (set_attr "highpart" "ignore")])
2825 (define_insn "umulsidi3_compact"
2826 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2828 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2829 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2830 (clobber (reg:SI MACH_REG))
2831 (clobber (reg:SI MACL_REG))]
2836 [(set (match_operand:DI 0 "arith_reg_dest" "")
2837 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2838 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2839 (clobber (reg:SI MACH_REG))
2840 (clobber (reg:SI MACL_REG))]
2845 rtx low_dst = gen_lowpart (SImode, operands[0]);
2846 rtx high_dst = gen_highpart (SImode, operands[0]);
2848 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2850 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2851 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2852 /* We need something to tag the possible REG_EQUAL notes on to. */
2853 emit_move_insn (operands[0], operands[0]);
2857 (define_insn "smulsi3_highpart_i"
2858 [(set (reg:SI MACH_REG)
2862 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2863 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2865 (clobber (reg:SI MACL_REG))]
2868 [(set_attr "type" "dmpy")])
2870 (define_expand "smulsi3_highpart"
2872 [(set (reg:SI MACH_REG)
2876 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2877 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2879 (clobber (reg:SI MACL_REG))])
2880 (set (match_operand:SI 0 "arith_reg_operand" "")
2887 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2888 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2889 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2890 invariant code motion can move it. */
2891 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2892 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2893 /* expand_binop can't find a suitable code in mul_highpart_optab to
2894 make a REG_EQUAL note from, so make one here.
2895 See also {,u}mulhisi.
2896 ??? Alternatively, we could put this at the calling site of expand_binop,
2897 i.e. expand_mult_highpart. */
2899 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2904 (define_insn "umulsi3_highpart_i"
2905 [(set (reg:SI MACH_REG)
2909 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2910 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2912 (clobber (reg:SI MACL_REG))]
2915 [(set_attr "type" "dmpy")])
2917 (define_expand "umulsi3_highpart"
2919 [(set (reg:SI MACH_REG)
2923 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2924 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2926 (clobber (reg:SI MACL_REG))])
2927 (set (match_operand:SI 0 "arith_reg_operand" "")
2934 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2935 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2936 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2937 invariant code motion can move it. */
2938 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2939 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2943 (define_insn_and_split "muldi3"
2944 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2945 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2946 (match_operand:DI 2 "arith_reg_operand" "r")))
2947 (clobber (match_scratch:DI 3 "=&r"))
2948 (clobber (match_scratch:DI 4 "=r"))]
2955 rtx op3_v2si, op2_v2si;
2957 op3_v2si = operands[3];
2958 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2960 op3_v2si = XEXP (op3_v2si, 0);
2961 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2963 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2964 op2_v2si = operands[2];
2965 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2967 op2_v2si = XEXP (op2_v2si, 0);
2968 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2970 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2971 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2972 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2973 emit_insn (gen_umulsidi3_media (operands[4],
2974 sh_gen_truncate (SImode, operands[1], 0),
2975 sh_gen_truncate (SImode, operands[2], 0)));
2976 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2977 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2978 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2979 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2984 ;; -------------------------------------------------------------------------
2985 ;; Logical operations
2986 ;; -------------------------------------------------------------------------
2988 (define_insn "*andsi3_compact"
2989 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2990 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2991 (match_operand:SI 2 "logical_operand" "r,K08")))]
2994 [(set_attr "type" "arith")])
2996 (define_insn "*andsi3_media"
2997 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2998 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
2999 (match_operand:SI 2 "logical_operand" "r,I10")))]
3004 [(set_attr "type" "arith_media")])
3006 ;; If the constant is 255, then emit an extu.b instruction instead of an
3007 ;; and, since that will give better code.
3009 (define_expand "andsi3"
3010 [(set (match_operand:SI 0 "arith_reg_operand" "")
3011 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3012 (match_operand:SI 2 "logical_operand" "")))]
3017 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3019 emit_insn (gen_zero_extendqisi2 (operands[0],
3020 gen_lowpart (QImode, operands[1])));
3025 (define_insn_and_split "anddi3"
3026 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3027 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3028 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3035 && ! logical_operand (operands[2], DImode)"
3039 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3040 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3042 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3045 [(set_attr "type" "arith_media")])
3047 (define_insn "andcsi3"
3048 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3049 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3050 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3053 [(set_attr "type" "arith_media")])
3055 (define_insn "andcdi3"
3056 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3057 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3058 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3061 [(set_attr "type" "arith_media")])
3063 (define_expand "iorsi3"
3064 [(set (match_operand:SI 0 "arith_reg_operand" "")
3065 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3066 (match_operand:SI 2 "logical_operand" "")))]
3070 (define_insn "*iorsi3_compact"
3071 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3072 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3073 (match_operand:SI 2 "logical_operand" "r,K08")))]
3076 [(set_attr "type" "arith")])
3078 (define_insn "*iorsi3_media"
3079 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3080 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3081 (match_operand:SI 2 "logical_operand" "r,I10")))]
3086 [(set_attr "type" "arith_media")])
3088 (define_insn "iordi3"
3089 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3090 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3091 (match_operand:DI 2 "logical_operand" "r,I10")))]
3096 [(set_attr "type" "arith_media")])
3098 (define_insn_and_split "*logical_sidi3"
3099 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3100 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3101 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3102 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3105 "&& reload_completed"
3106 [(set (match_dup 0) (match_dup 3))]
3110 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3111 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3112 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3115 (define_insn_and_split "*logical_sidisi3"
3116 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3117 (truncate:SI (sign_extend:DI
3118 (match_operator:SI 3 "logical_operator"
3119 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3120 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3124 [(set (match_dup 0) (match_dup 3))])
3126 (define_insn_and_split "*logical_sidi3_2"
3127 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3128 (sign_extend:DI (truncate:SI (sign_extend:DI
3129 (match_operator:SI 3 "logical_operator"
3130 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3131 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3135 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3137 (define_expand "xorsi3"
3138 [(set (match_operand:SI 0 "arith_reg_operand" "")
3139 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3140 (match_operand:SI 2 "xor_operand" "")))]
3144 (define_insn "*xorsi3_compact"
3145 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3146 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3147 (match_operand:SI 2 "logical_operand" "K08,r")))]
3150 [(set_attr "type" "arith")])
3152 (define_insn "*xorsi3_media"
3153 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3154 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3155 (match_operand:SI 2 "xor_operand" "r,I06")))]
3160 [(set_attr "type" "arith_media")])
3162 (define_insn "xordi3"
3163 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3164 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3165 (match_operand:DI 2 "xor_operand" "r,I06")))]
3170 [(set_attr "type" "arith_media")])
3172 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3173 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3175 [(set (match_operand:DI 0 "arith_reg_dest" "")
3176 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3177 [(match_operand 1 "any_register_operand" "")
3178 (match_operand 2 "any_register_operand" "")])))]
3180 [(set (match_dup 5) (match_dup 4))
3181 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3184 enum machine_mode inmode = GET_MODE (operands[1]);
3187 if (GET_CODE (operands[0]) == SUBREG)
3189 offset = SUBREG_BYTE (operands[0]);
3190 operands[0] = SUBREG_REG (operands[0]);
3192 gcc_assert (GET_CODE (operands[0]) == REG);
3193 if (! TARGET_LITTLE_ENDIAN)
3194 offset += 8 - GET_MODE_SIZE (inmode);
3195 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3198 ;; -------------------------------------------------------------------------
3199 ;; Shifts and rotates
3200 ;; -------------------------------------------------------------------------
3202 (define_expand "rotldi3"
3203 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3204 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3205 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3207 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3209 (define_insn "rotldi3_mextr"
3210 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3211 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3212 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3216 static char templ[16];
3218 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3219 8 - (int) (INTVAL (operands[2]) >> 3));
3222 [(set_attr "type" "arith_media")])
3224 (define_expand "rotrdi3"
3225 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3226 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3227 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3229 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3231 (define_insn "rotrdi3_mextr"
3232 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3233 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3234 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3238 static char templ[16];
3240 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3243 [(set_attr "type" "arith_media")])
3246 [(set (match_operand:DI 0 "arith_reg_dest" "")
3247 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3248 "ua_address_operand" "")))
3249 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3251 (clobber (match_operand:DI 3 "register_operand" ""))]
3253 [(match_dup 4) (match_dup 5)]
3256 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3257 (operands[3], operands[1]));
3258 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3259 GEN_INT (56), GEN_INT (8));
3262 (define_insn "rotlsi3_1"
3263 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3264 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3267 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3270 [(set_attr "type" "arith")])
3272 (define_insn "rotlsi3_31"
3273 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3274 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3276 (clobber (reg:SI T_REG))]
3279 [(set_attr "type" "arith")])
3281 (define_insn "rotlsi3_16"
3282 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3283 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3287 [(set_attr "type" "arith")])
3289 (define_expand "rotlsi3"
3290 [(set (match_operand:SI 0 "arith_reg_dest" "")
3291 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3292 (match_operand:SI 2 "immediate_operand" "")))]
3296 static const char rot_tab[] = {
3297 000, 000, 000, 000, 000, 000, 010, 001,
3298 001, 001, 011, 013, 003, 003, 003, 003,
3299 003, 003, 003, 003, 003, 013, 012, 002,
3300 002, 002, 010, 000, 000, 000, 000, 000,
3305 if (GET_CODE (operands[2]) != CONST_INT)
3307 count = INTVAL (operands[2]);
3308 choice = rot_tab[count];
3309 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3315 emit_move_insn (operands[0], operands[1]);
3316 count -= (count & 16) * 2;
3319 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3326 parts[0] = gen_reg_rtx (SImode);
3327 parts[1] = gen_reg_rtx (SImode);
3328 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3329 emit_move_insn (parts[choice-1], operands[1]);
3330 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3331 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3332 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3333 count = (count & ~16) - 8;
3337 for (; count > 0; count--)
3338 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3339 for (; count < 0; count++)
3340 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3345 (define_insn "*rotlhi3_8"
3346 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3347 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3351 [(set_attr "type" "arith")])
3353 (define_expand "rotlhi3"
3354 [(set (match_operand:HI 0 "arith_reg_operand" "")
3355 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3356 (match_operand:HI 2 "immediate_operand" "")))]
3360 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3367 (define_insn "ashlsi3_sh2a"
3368 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3369 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3370 (match_operand:SI 2 "arith_reg_operand" "r")))]
3373 [(set_attr "type" "arith")
3374 (set_attr "length" "4")])
3376 ;; This pattern is used by init_expmed for computing the costs of shift
3379 (define_insn_and_split "ashlsi3_std"
3380 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3381 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3382 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3383 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3385 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3386 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3394 && GET_CODE (operands[2]) == CONST_INT
3395 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3396 [(set (match_dup 3) (match_dup 2))
3398 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3399 (clobber (match_dup 4))])]
3400 "operands[4] = gen_rtx_SCRATCH (SImode);"
3401 [(set_attr "length" "*,*,*,4")
3402 (set_attr "type" "dyn_shift,arith,arith,arith")])
3404 (define_insn "ashlhi3_k"
3405 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3406 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3407 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3408 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3412 [(set_attr "type" "arith")])
3414 (define_insn "ashlsi3_n"
3415 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3416 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3417 (match_operand:SI 2 "const_int_operand" "n")))
3418 (clobber (reg:SI T_REG))]
3419 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3421 [(set (attr "length")
3422 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3424 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3426 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3428 (const_string "8")))
3429 (set_attr "type" "arith")])
3432 [(set (match_operand:SI 0 "arith_reg_dest" "")
3433 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3434 (match_operand:SI 2 "const_int_operand" "")))
3435 (clobber (reg:SI T_REG))]
3436 "TARGET_SH1 && reload_completed"
3437 [(use (reg:SI R0_REG))]
3440 gen_shifty_op (ASHIFT, operands);
3444 (define_insn "ashlsi3_media"
3445 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3446 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3447 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3452 [(set_attr "type" "arith_media")
3453 (set_attr "highpart" "ignore")])
3455 (define_expand "ashlsi3"
3456 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3457 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3458 (match_operand:SI 2 "nonmemory_operand" "")))
3459 (clobber (reg:SI T_REG))])]
3465 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3468 if (GET_CODE (operands[2]) == CONST_INT
3469 && sh_dynamicalize_shift_p (operands[2]))
3470 operands[2] = force_reg (SImode, operands[2]);
3473 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3476 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3480 (define_insn "*ashlhi3_n"
3481 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3482 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3483 (match_operand:HI 2 "const_int_operand" "n")))
3484 (clobber (reg:SI T_REG))]
3487 [(set (attr "length")
3488 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3490 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3492 (const_string "6")))
3493 (set_attr "type" "arith")])
3495 (define_expand "ashlhi3"
3496 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3497 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3498 (match_operand:SI 2 "nonmemory_operand" "")))
3499 (clobber (reg:SI T_REG))])]
3503 if (GET_CODE (operands[2]) != CONST_INT)
3505 /* It may be possible to call gen_ashlhi3 directly with more generic
3506 operands. Make sure operands[1] is a HImode register here. */
3507 if (!arith_reg_operand (operands[1], HImode))
3508 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3512 [(set (match_operand:HI 0 "arith_reg_dest" "")
3513 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3514 (match_operand:HI 2 "const_int_operand" "")))
3515 (clobber (reg:SI T_REG))]
3516 "TARGET_SH1 && reload_completed"
3517 [(use (reg:SI R0_REG))]
3520 gen_shifty_hi_op (ASHIFT, operands);
3525 ; arithmetic shift right
3528 (define_insn "ashrsi3_sh2a"
3529 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3534 [(set_attr "type" "dyn_shift")
3535 (set_attr "length" "4")])
3537 (define_insn "ashrsi3_k"
3538 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3539 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3540 (match_operand:SI 2 "const_int_operand" "M")))
3541 (clobber (reg:SI T_REG))]
3542 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3544 [(set_attr "type" "arith")])
3546 ;; We can't do HImode right shifts correctly unless we start out with an
3547 ;; explicit zero / sign extension; doing that would result in worse overall
3548 ;; code, so just let the machine independent code widen the mode.
3549 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3552 ;; ??? This should be a define expand.
3554 (define_insn "ashrsi2_16"
3555 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3556 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3560 [(set_attr "length" "4")])
3563 [(set (match_operand:SI 0 "arith_reg_dest" "")
3564 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3567 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3568 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3569 "operands[2] = gen_lowpart (HImode, operands[0]);")
3571 ;; ??? This should be a define expand.
3573 (define_insn "ashrsi2_31"
3574 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3575 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577 (clobber (reg:SI T_REG))]
3580 [(set_attr "length" "4")])
3583 [(set (match_operand:SI 0 "arith_reg_dest" "")
3584 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3586 (clobber (reg:SI T_REG))]
3591 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3592 emit_insn (gen_mov_neg_si_t (operands[0]));
3597 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3599 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3601 && peep2_reg_dead_p (2, operands[0])
3602 && peep2_reg_dead_p (2, operands[1])"
3606 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3610 (define_insn "ashlsi_c"
3611 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3612 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3614 (lt:SI (match_dup 1) (const_int 0)))]
3617 [(set_attr "type" "arith")])
3619 (define_insn "*ashlsi_c_void"
3620 [(set (reg:SI T_REG)
3621 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3622 (clobber (match_scratch:SI 1 "=0"))]
3623 "TARGET_SH1 && cse_not_expected"
3625 [(set_attr "type" "arith")])
3627 (define_insn "ashrsi3_d"
3628 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3629 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3630 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3633 [(set_attr "type" "dyn_shift")])
3635 (define_insn "ashrsi3_n"
3636 [(set (reg:SI R4_REG)
3637 (ashiftrt:SI (reg:SI R4_REG)
3638 (match_operand:SI 0 "const_int_operand" "i")))
3639 (clobber (reg:SI T_REG))
3640 (clobber (reg:SI PR_REG))
3641 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3644 [(set_attr "type" "sfunc")
3645 (set_attr "needs_delay_slot" "yes")])
3647 (define_insn "ashrsi3_media"
3648 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3649 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3650 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3655 [(set_attr "type" "arith_media")
3656 (set_attr "highpart" "ignore")])
3658 (define_expand "ashrsi3"
3659 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3660 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3661 (match_operand:SI 2 "nonmemory_operand" "")))
3662 (clobber (reg:SI T_REG))])]
3668 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3671 if (expand_ashiftrt (operands))
3677 ;; logical shift right
3679 (define_insn "lshrsi3_sh2a"
3680 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3681 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3682 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3685 [(set_attr "type" "dyn_shift")
3686 (set_attr "length" "4")])
3688 (define_insn "lshrsi3_d"
3689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694 [(set_attr "type" "dyn_shift")])
3696 ;; Only the single bit shift clobbers the T bit.
3698 (define_insn "lshrsi3_m"
3699 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3700 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3701 (match_operand:SI 2 "const_int_operand" "M")))
3702 (clobber (reg:SI T_REG))]
3703 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3705 [(set_attr "type" "arith")])
3707 (define_insn "lshrsi3_k"
3708 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3709 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3710 (match_operand:SI 2 "const_int_operand" "P27")))]
3711 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3712 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3714 [(set_attr "type" "arith")])
3716 (define_insn "lshrsi3_n"
3717 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3718 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3719 (match_operand:SI 2 "const_int_operand" "n")))
3720 (clobber (reg:SI T_REG))]
3721 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3723 [(set (attr "length")
3724 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3726 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3728 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3730 (const_string "8")))
3731 (set_attr "type" "arith")])
3734 [(set (match_operand:SI 0 "arith_reg_dest" "")
3735 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3736 (match_operand:SI 2 "const_int_operand" "")))
3737 (clobber (reg:SI T_REG))]
3738 "TARGET_SH1 && reload_completed"
3739 [(use (reg:SI R0_REG))]
3742 gen_shifty_op (LSHIFTRT, operands);
3746 (define_insn "lshrsi3_media"
3747 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3748 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3749 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3754 [(set_attr "type" "arith_media")
3755 (set_attr "highpart" "ignore")])
3757 (define_expand "lshrsi3"
3758 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3759 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3760 (match_operand:SI 2 "nonmemory_operand" "")))
3761 (clobber (reg:SI T_REG))])]
3767 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3770 if (GET_CODE (operands[2]) == CONST_INT
3771 && sh_dynamicalize_shift_p (operands[2]))
3772 operands[2] = force_reg (SImode, operands[2]);
3773 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3775 rtx count = copy_to_mode_reg (SImode, operands[2]);
3776 emit_insn (gen_negsi2 (count, count));
3777 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3780 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3784 ;; ??? This should be a define expand.
3786 (define_insn "ashldi3_k"
3787 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3788 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3790 (clobber (reg:SI T_REG))]
3792 "shll %R0\;rotcl %S0"
3793 [(set_attr "length" "4")
3794 (set_attr "type" "arith")])
3796 (define_insn "ashldi3_media"
3797 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3798 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3799 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3804 [(set_attr "type" "arith_media")])
3806 (define_insn "*ashldisi3_media"
3807 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3808 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3809 (match_operand:DI 2 "const_int_operand" "n")))]
3810 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3811 "shlli.l %1, %2, %0"
3812 [(set_attr "type" "arith_media")
3813 (set_attr "highpart" "ignore")])
3815 (define_expand "ashldi3"
3816 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3817 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3818 (match_operand:DI 2 "immediate_operand" "")))
3819 (clobber (reg:SI T_REG))])]
3825 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3828 if (GET_CODE (operands[2]) != CONST_INT
3829 || INTVAL (operands[2]) != 1)
3833 ;; ??? This should be a define expand.
3835 (define_insn "lshrdi3_k"
3836 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3837 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3839 (clobber (reg:SI T_REG))]
3841 "shlr %S0\;rotcr %R0"
3842 [(set_attr "length" "4")
3843 (set_attr "type" "arith")])
3845 (define_insn "lshrdi3_media"
3846 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3847 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3848 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3850 && (arith_reg_dest (operands[0], DImode)
3851 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3855 [(set_attr "type" "arith_media")])
3857 (define_insn "*lshrdisi3_media"
3858 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3859 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3860 (match_operand:DI 2 "const_int_operand" "n")))]
3861 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3862 "shlri.l %1, %2, %0"
3863 [(set_attr "type" "arith_media")
3864 (set_attr "highpart" "ignore")])
3866 (define_expand "lshrdi3"
3867 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3868 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3869 (match_operand:DI 2 "immediate_operand" "")))
3870 (clobber (reg:SI T_REG))])]
3876 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3879 if (GET_CODE (operands[2]) != CONST_INT
3880 || INTVAL (operands[2]) != 1)
3884 ;; ??? This should be a define expand.
3886 (define_insn "ashrdi3_k"
3887 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3888 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3890 (clobber (reg:SI T_REG))]
3892 "shar %S0\;rotcr %R0"
3893 [(set_attr "length" "4")
3894 (set_attr "type" "arith")])
3896 (define_insn "ashrdi3_media"
3897 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3898 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3899 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3901 && (arith_reg_dest (operands[0], DImode)
3902 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3906 [(set_attr "type" "arith_media")])
3908 (define_insn "*ashrdisi3_media"
3909 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3910 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3911 (match_operand:DI 2 "const_int_operand" "n")))]
3912 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3913 "shari.l %1, %2, %0"
3914 [(set_attr "type" "arith_media")
3915 (set_attr "highpart" "ignore")])
3917 (define_insn "ashrdisi3_media_high"
3918 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3920 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3921 (match_operand:DI 2 "const_int_operand" "n"))))]
3922 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3924 [(set_attr "type" "arith_media")])
3926 (define_insn "ashrdisi3_media_opaque"
3927 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3928 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3929 (match_operand:DI 2 "const_int_operand" "n")]
3933 [(set_attr "type" "arith_media")])
3935 (define_expand "ashrdi3"
3936 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3937 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3938 (match_operand:DI 2 "immediate_operand" "")))
3939 (clobber (reg:SI T_REG))])]
3945 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3948 if (GET_CODE (operands[2]) != CONST_INT
3949 || INTVAL (operands[2]) != 1)
3953 ;; combined left/right shift
3956 [(set (match_operand:SI 0 "register_operand" "")
3957 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3958 (match_operand:SI 2 "const_int_operand" ""))
3959 (match_operand:SI 3 "const_int_operand" "")))]
3960 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3961 [(use (reg:SI R0_REG))]
3962 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3966 [(set (match_operand:SI 0 "register_operand" "")
3967 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3968 (match_operand:SI 2 "const_int_operand" ""))
3969 (match_operand:SI 3 "const_int_operand" "")))
3970 (clobber (reg:SI T_REG))]
3971 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3972 [(use (reg:SI R0_REG))]
3973 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3977 [(set (match_operand:SI 0 "register_operand" "=r")
3978 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3979 (match_operand:SI 2 "const_int_operand" "n"))
3980 (match_operand:SI 3 "const_int_operand" "n")))
3981 (clobber (reg:SI T_REG))]
3982 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3984 [(set (attr "length")
3985 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3987 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3989 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3991 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3993 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3995 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3997 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
3998 (const_string "16")]
3999 (const_string "18")))
4000 (set_attr "type" "arith")])
4003 [(set (match_operand:SI 0 "register_operand" "=z")
4004 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4005 (match_operand:SI 2 "const_int_operand" "n"))
4006 (match_operand:SI 3 "const_int_operand" "n")))
4007 (clobber (reg:SI T_REG))]
4008 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4010 [(set (attr "length")
4011 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4013 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4015 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4017 (const_string "10")))
4018 (set_attr "type" "arith")])
4020 ;; shift left / and combination with a scratch register: The combine pass
4021 ;; does not accept the individual instructions, even though they are
4022 ;; cheap. But it needs a precise description so that it is usable after
4024 (define_insn "and_shl_scratch"
4025 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4029 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4030 (match_operand:SI 2 "const_int_operand" "N,n"))
4031 (match_operand:SI 3 "" "0,r"))
4032 (match_operand:SI 4 "const_int_operand" "n,n"))
4033 (match_operand:SI 5 "const_int_operand" "n,n")))
4034 (clobber (reg:SI T_REG))]
4037 [(set (attr "length")
4038 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4040 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4042 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4044 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4045 (const_string "10")]
4046 (const_string "12")))
4047 (set_attr "type" "arith")])
4050 [(set (match_operand:SI 0 "register_operand" "")
4054 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4055 (match_operand:SI 2 "const_int_operand" ""))
4056 (match_operand:SI 3 "register_operand" ""))
4057 (match_operand:SI 4 "const_int_operand" ""))
4058 (match_operand:SI 5 "const_int_operand" "")))
4059 (clobber (reg:SI T_REG))]
4061 [(use (reg:SI R0_REG))]
4064 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4066 if (INTVAL (operands[2]))
4068 gen_shifty_op (LSHIFTRT, operands);
4070 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4071 operands[2] = operands[4];
4072 gen_shifty_op (ASHIFT, operands);
4073 if (INTVAL (operands[5]))
4075 operands[2] = operands[5];
4076 gen_shifty_op (LSHIFTRT, operands);
4081 ;; signed left/right shift combination.
4083 [(set (match_operand:SI 0 "register_operand" "")
4085 (ashift:SI (match_operand:SI 1 "register_operand" "")
4086 (match_operand:SI 2 "const_int_operand" ""))
4087 (match_operand:SI 3 "const_int_operand" "")
4089 (clobber (reg:SI T_REG))]
4091 [(use (reg:SI R0_REG))]
4092 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4095 (define_insn "shl_sext_ext"
4096 [(set (match_operand:SI 0 "register_operand" "=r")
4098 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4099 (match_operand:SI 2 "const_int_operand" "n"))
4100 (match_operand:SI 3 "const_int_operand" "n")
4102 (clobber (reg:SI T_REG))]
4103 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4105 [(set (attr "length")
4106 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4108 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4110 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4112 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4114 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4116 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4118 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4120 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4121 (const_string "16")]
4122 (const_string "18")))
4123 (set_attr "type" "arith")])
4125 (define_insn "shl_sext_sub"
4126 [(set (match_operand:SI 0 "register_operand" "=z")
4128 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4129 (match_operand:SI 2 "const_int_operand" "n"))
4130 (match_operand:SI 3 "const_int_operand" "n")
4132 (clobber (reg:SI T_REG))]
4133 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4135 [(set (attr "length")
4136 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4138 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4140 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4142 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4143 (const_string "12")]
4144 (const_string "14")))
4145 (set_attr "type" "arith")])
4147 ;; These patterns are found in expansions of DImode shifts by 16, and
4148 ;; allow the xtrct instruction to be generated from C source.
4150 (define_insn "xtrct_left"
4151 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4152 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4154 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4158 [(set_attr "type" "arith")])
4160 (define_insn "xtrct_right"
4161 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4162 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4164 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4168 [(set_attr "type" "arith")])
4170 ;; -------------------------------------------------------------------------
4172 ;; -------------------------------------------------------------------------
4175 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4176 (neg:SI (plus:SI (reg:SI T_REG)
4177 (match_operand:SI 1 "arith_reg_operand" "r"))))
4179 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4183 [(set_attr "type" "arith")])
4185 (define_insn "*negdi_media"
4186 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4187 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4190 [(set_attr "type" "arith_media")])
4192 (define_expand "negdi2"
4193 [(set (match_operand:DI 0 "arith_reg_operand" "")
4194 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4200 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4201 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4203 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4204 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4206 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4207 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4209 emit_insn (gen_clrt ());
4210 emit_insn (gen_negc (low_dst, low_src));
4211 emit_insn (gen_negc (high_dst, high_src));
4216 (define_insn "negsi2"
4217 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4218 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4221 [(set_attr "type" "arith")])
4223 (define_insn "one_cmplsi2"
4224 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4225 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4228 [(set_attr "type" "arith")])
4230 (define_expand "one_cmpldi2"
4231 [(set (match_operand:DI 0 "arith_reg_dest" "")
4232 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4234 "TARGET_SHMEDIA" "")
4236 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4237 This can be used as some kind of conditional execution, which is useful
4240 [(set (match_operand:SI 0 "arith_reg_dest" "")
4241 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4242 (match_operand:SI 1 "arith_reg_operand" ""))
4246 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4247 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4251 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4252 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4253 (match_operand:SI 1 "arith_reg_operand" "0")
4254 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4256 "bf 0f\;neg %2,%0\\n0:"
4257 [(set_attr "type" "arith") ;; poor approximation
4258 (set_attr "length" "4")])
4261 ;; -------------------------------------------------------------------------
4262 ;; Zero extension instructions
4263 ;; -------------------------------------------------------------------------
4265 (define_insn "zero_extendsidi2"
4266 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4267 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4269 "addz.l %1, r63, %0"
4270 [(set_attr "type" "arith_media")
4271 (set_attr "highpart" "extend")])
4273 (define_insn "zero_extendhidi2"
4274 [(set (match_operand:DI 0 "register_operand" "=r,r")
4275 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4280 [(set_attr "type" "*,load_media")
4281 (set (attr "highpart")
4282 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4283 (const_string "user")]
4284 (const_string "ignore")))])
4287 [(set (match_operand:DI 0 "register_operand" "")
4288 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4289 "TARGET_SHMEDIA && reload_completed"
4290 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4291 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4294 if (GET_CODE (operands[1]) == TRUNCATE)
4295 operands[1] = XEXP (operands[1], 0);
4298 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4299 ;; reload the entire truncate expression.
4300 (define_insn_and_split "*loaddi_trunc"
4301 [(set (match_operand 0 "any_register_operand" "=r")
4302 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4303 "TARGET_SHMEDIA && reload_completed"
4305 "TARGET_SHMEDIA && reload_completed"
4306 [(set (match_dup 0) (match_dup 1))]
4307 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4309 (define_insn "zero_extendqidi2"
4310 [(set (match_operand:DI 0 "register_operand" "=r,r")
4311 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4316 [(set_attr "type" "arith_media,load_media")
4317 (set (attr "highpart")
4318 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4319 (const_string "user")]
4320 (const_string "ignore")))])
4322 (define_expand "zero_extendhisi2"
4323 [(set (match_operand:SI 0 "arith_reg_operand" "")
4324 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4328 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4329 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4332 (define_insn "*zero_extendhisi2_compact"
4333 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4334 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4337 [(set_attr "type" "arith")])
4339 (define_insn "*zero_extendhisi2_media"
4340 [(set (match_operand:SI 0 "register_operand" "=r,r")
4341 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4346 [(set_attr "type" "arith_media,load_media")
4347 (set (attr "highpart")
4348 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4349 (const_string "user")]
4350 (const_string "ignore")))])
4353 [(set (match_operand:SI 0 "register_operand" "")
4354 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4355 "TARGET_SHMEDIA && reload_completed"
4356 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4357 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4360 rtx op1 = operands[1];
4362 if (GET_CODE (op1) == TRUNCATE)
4363 op1 = XEXP (op1, 0);
4365 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4366 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4369 (define_expand "zero_extendqisi2"
4370 [(set (match_operand:SI 0 "arith_reg_operand" "")
4371 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4375 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4376 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4379 (define_insn "*zero_extendqisi2_compact"
4380 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4381 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4384 [(set_attr "type" "arith")])
4386 (define_insn "*zero_extendqisi2_media"
4387 [(set (match_operand:SI 0 "register_operand" "=r,r")
4388 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4393 [(set_attr "type" "arith_media,load_media")
4394 (set (attr "highpart")
4395 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4396 (const_string "user")]
4397 (const_string "ignore")))])
4399 (define_insn "zero_extendqihi2"
4400 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4401 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4404 [(set_attr "type" "arith")])
4406 ;; -------------------------------------------------------------------------
4407 ;; Sign extension instructions
4408 ;; -------------------------------------------------------------------------
4410 ;; ??? This should be a define expand.
4411 ;; ??? Or perhaps it should be dropped?
4413 ;; convert_move generates good code for SH[1-4].
4414 (define_insn "extendsidi2"
4415 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4416 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4422 [(set_attr "type" "arith_media,load_media,fpconv_media")
4423 (set (attr "highpart")
4424 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4425 (const_string "user")]
4426 (const_string "extend")))])
4428 (define_insn "extendhidi2"
4429 [(set (match_operand:DI 0 "register_operand" "=r,r")
4430 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4435 [(set_attr "type" "*,load_media")
4436 (set (attr "highpart")
4437 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4438 (const_string "user")]
4439 (const_string "ignore")))])
4442 [(set (match_operand:DI 0 "register_operand" "")
4443 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4444 "TARGET_SHMEDIA && reload_completed"
4445 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4446 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4449 if (GET_CODE (operands[1]) == TRUNCATE)
4450 operands[1] = XEXP (operands[1], 0);
4453 (define_insn "extendqidi2"
4454 [(set (match_operand:DI 0 "register_operand" "=r,r")
4455 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4460 [(set_attr "type" "*,load_media")
4461 (set (attr "highpart")
4462 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4463 (const_string "user")]
4464 (const_string "ignore")))])
4467 [(set (match_operand:DI 0 "register_operand" "")
4468 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4469 "TARGET_SHMEDIA && reload_completed"
4470 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4471 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4474 if (GET_CODE (operands[1]) == TRUNCATE)
4475 operands[1] = XEXP (operands[1], 0);
4478 (define_expand "extendhisi2"
4479 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4480 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4484 (define_insn "*extendhisi2_compact"
4485 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4486 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4491 [(set_attr "type" "arith,load")])
4493 (define_insn "*extendhisi2_media"
4494 [(set (match_operand:SI 0 "register_operand" "=r,r")
4495 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4500 [(set_attr "type" "arith_media,load_media")
4501 (set (attr "highpart")
4502 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4503 (const_string "user")]
4504 (const_string "ignore")))])
4507 [(set (match_operand:SI 0 "register_operand" "")
4508 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4509 "TARGET_SHMEDIA && reload_completed"
4510 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4511 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4514 rtx op1 = operands[1];
4515 if (GET_CODE (op1) == TRUNCATE)
4516 op1 = XEXP (op1, 0);
4518 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4519 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4522 (define_expand "extendqisi2"
4523 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4524 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4528 (define_insn "*extendqisi2_compact"
4529 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4530 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4535 [(set_attr "type" "arith,load")])
4537 (define_insn "*extendqisi2_media"
4538 [(set (match_operand:SI 0 "register_operand" "=r,r")
4539 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4544 [(set_attr "type" "arith_media,load_media")
4545 (set (attr "highpart")
4546 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4547 (const_string "user")]
4548 (const_string "ignore")))])
4551 [(set (match_operand:SI 0 "register_operand" "")
4552 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4553 "TARGET_SHMEDIA && reload_completed"
4554 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4555 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4558 rtx op1 = operands[1];
4559 if (GET_CODE (op1) == TRUNCATE)
4560 op1 = XEXP (op1, 0);
4562 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4563 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4566 (define_insn "extendqihi2"
4567 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4568 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4573 [(set_attr "type" "arith,load")])
4575 /* It would seem useful to combine the truncXi patterns into the movXi
4576 patterns, but unary operators are ignored when matching constraints,
4577 so we need separate patterns. */
4578 (define_insn "truncdisi2"
4579 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4580 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4589 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4590 (set (attr "highpart")
4591 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4592 (const_string "user")]
4593 (const_string "extend")))])
4595 (define_insn "truncdihi2"
4596 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4597 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4600 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4602 [(set_attr "type" "arith_media,store_media")
4603 (set_attr "length" "8,4")
4604 (set (attr "highpart")
4605 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4606 (const_string "user")]
4607 (const_string "extend")))])
4609 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4610 ; Because we use zero extension, we can't provide signed QImode compares
4611 ; using a simple compare or conditional banch insn.
4612 (define_insn "truncdiqi2"
4613 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4614 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4619 [(set_attr "type" "arith_media,store")
4620 (set (attr "highpart")
4621 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4622 (const_string "user")]
4623 (const_string "extend")))])
4624 ;; -------------------------------------------------------------------------
4625 ;; Move instructions
4626 ;; -------------------------------------------------------------------------
4628 ;; define push and pop so it is easy for sh.c
4629 ;; We can't use push and pop on SHcompact because the stack must always
4630 ;; be 8-byte aligned.
4632 (define_expand "push"
4633 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4634 (match_operand:SI 0 "register_operand" "r,l,x"))]
4635 "TARGET_SH1 && ! TARGET_SH5"
4638 (define_expand "pop"
4639 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4640 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4641 "TARGET_SH1 && ! TARGET_SH5"
4644 (define_expand "push_e"
4645 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4646 (match_operand:SF 0 "" ""))
4647 (use (reg:PSI FPSCR_REG))
4648 (clobber (scratch:SI))])]
4649 "TARGET_SH1 && ! TARGET_SH5"
4652 (define_insn "push_fpul"
4653 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4654 "TARGET_SH2E && ! TARGET_SH5"
4656 [(set_attr "type" "store")
4657 (set_attr "late_fp_use" "yes")
4658 (set_attr "hit_stack" "yes")])
4660 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4662 (define_expand "push_4"
4663 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4664 (match_operand:DF 0 "" ""))
4665 (use (reg:PSI FPSCR_REG))
4666 (clobber (scratch:SI))])]
4667 "TARGET_SH1 && ! TARGET_SH5"
4670 (define_expand "pop_e"
4671 [(parallel [(set (match_operand:SF 0 "" "")
4672 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4673 (use (reg:PSI FPSCR_REG))
4674 (clobber (scratch:SI))])]
4675 "TARGET_SH1 && ! TARGET_SH5"
4678 (define_insn "pop_fpul"
4679 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4680 "TARGET_SH2E && ! TARGET_SH5"
4682 [(set_attr "type" "load")
4683 (set_attr "hit_stack" "yes")])
4685 (define_expand "pop_4"
4686 [(parallel [(set (match_operand:DF 0 "" "")
4687 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4688 (use (reg:PSI FPSCR_REG))
4689 (clobber (scratch:SI))])]
4690 "TARGET_SH1 && ! TARGET_SH5"
4693 (define_expand "push_fpscr"
4698 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
4699 gen_rtx_PRE_DEC (Pmode,
4700 stack_pointer_rtx)),
4702 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4706 (define_expand "pop_fpscr"
4711 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4712 gen_rtx_MEM (PSImode,
4713 gen_rtx_POST_INC (Pmode,
4714 stack_pointer_rtx))));
4715 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4719 ;; These two patterns can happen as the result of optimization, when
4720 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4721 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4724 [(set (reg:SI T_REG) (const_int 0))]
4729 [(set (reg:SI T_REG) (const_int 1))]
4733 ;; t/r must come after r/r, lest reload will try to reload stuff like
4734 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4735 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4736 (define_insn "movsi_i"
4737 [(set (match_operand:SI 0 "general_movdst_operand"
4738 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4739 (match_operand:SI 1 "general_movsrc_operand"
4740 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4744 && (register_operand (operands[0], SImode)
4745 || register_operand (operands[1], SImode))"
4762 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4763 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4765 ;; t/r must come after r/r, lest reload will try to reload stuff like
4766 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4767 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4768 ;; will require a reload.
4769 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4770 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4771 (define_insn "movsi_ie"
4772 [(set (match_operand:SI 0 "general_movdst_operand"
4773 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4774 (match_operand:SI 1 "general_movsrc_operand"
4775 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4776 "(TARGET_SH2E || TARGET_SH2A)
4777 && (register_operand (operands[0], SImode)
4778 || register_operand (operands[1], SImode))"
4803 ! move optimized away"
4804 [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4805 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4806 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4808 (define_insn "movsi_i_lowpart"
4809 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4810 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4812 && (register_operand (operands[0], SImode)
4813 || register_operand (operands[1], SImode))"
4823 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4825 (define_insn_and_split "load_ra"
4826 [(set (match_operand:SI 0 "general_movdst_operand" "")
4827 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4830 "&& ! currently_expanding_to_rtl"
4831 [(set (match_dup 0) (match_dup 1))]
4834 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4835 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
4838 ;; The '?'s in the following constraints may not reflect the time taken
4839 ;; to perform the move. They are there to discourage the use of floating-
4840 ;; point registers for storing integer values.
4841 (define_insn "*movsi_media"
4842 [(set (match_operand:SI 0 "general_movdst_operand"
4843 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4844 (match_operand:SI 1 "general_movsrc_operand"
4845 "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4847 && (register_operand (operands[0], SImode)
4848 || sh_register_operand (operands[1], SImode)
4849 || GET_CODE (operands[1]) == TRUNCATE)"
4864 [(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")
4865 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4866 (set (attr "highpart")
4867 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4868 (const_string "user")]
4869 (const_string "ignore")))])
4871 (define_insn "*movsi_media_nofpu"
4872 [(set (match_operand:SI 0 "general_movdst_operand"
4873 "=r,r,r,r,m,*b,r,*b")
4874 (match_operand:SI 1 "general_movsrc_operand"
4875 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4877 && (register_operand (operands[0], SImode)
4878 || sh_register_operand (operands[1], SImode)
4879 || GET_CODE (operands[1]) == TRUNCATE)"
4889 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4890 (set_attr "length" "4,4,8,4,4,4,4,12")
4891 (set (attr "highpart")
4892 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4893 (const_string "user")]
4894 (const_string "ignore")))])
4896 (define_expand "movsi_const"
4897 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4898 (const:SI (sign_extend:SI
4901 (match_operand:DI 1 "immediate_operand" "s")
4904 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4909 (truncate:HI (match_dup 1))))))))]
4910 "TARGET_SHMEDIA && reload_completed
4911 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4914 if (GET_CODE (operands[1]) == LABEL_REF
4915 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4916 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4917 else if (GOTOFF_P (operands[1]))
4919 rtx unspec = XEXP (operands[1], 0);
4921 if (! UNSPEC_GOTOFF_P (unspec))
4923 unspec = XEXP (unspec, 0);
4924 if (! UNSPEC_GOTOFF_P (unspec))
4927 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4928 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4929 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4933 (define_expand "movsi_const_16bit"
4934 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4935 (const:SI (sign_extend:SI
4937 (match_operand:DI 1 "immediate_operand" "s")))))]
4938 "TARGET_SHMEDIA && flag_pic && reload_completed
4939 && GET_CODE (operands[1]) == SYMBOL_REF"
4943 [(set (match_operand:SI 0 "arith_reg_dest" "")
4944 (match_operand:SI 1 "immediate_operand" ""))]
4945 "TARGET_SHMEDIA && reload_completed
4946 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4950 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4952 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4959 [(set (match_operand:SI 0 "register_operand" "")
4960 (match_operand:SI 1 "immediate_operand" ""))]
4961 "TARGET_SHMEDIA && reload_completed
4962 && ((GET_CODE (operands[1]) == CONST_INT
4963 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4964 || GET_CODE (operands[1]) == CONST_DOUBLE)"
4965 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4967 (define_expand "movsi"
4968 [(set (match_operand:SI 0 "general_movdst_operand" "")
4969 (match_operand:SI 1 "general_movsrc_operand" ""))]
4971 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4973 (define_expand "ic_invalidate_line"
4974 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4975 (match_dup 1)] UNSPEC_ICACHE)
4976 (clobber (scratch:SI))])]
4977 "TARGET_HARD_SH4 || TARGET_SH5"
4982 emit_insn (gen_ic_invalidate_line_media (operands[0]));
4985 else if (TARGET_SHCOMPACT)
4987 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4988 operands[1] = force_reg (Pmode, operands[1]);
4989 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4992 else if (TARGET_SH4A_ARCH)
4994 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4997 operands[0] = force_reg (Pmode, operands[0]);
4998 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5002 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5003 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5004 ;; the requirement *1*00 for associative address writes. The alignment of
5005 ;; %0 implies that its least significant bit is cleared,
5006 ;; thus we clear the V bit of a matching entry if there is one.
5007 (define_insn "ic_invalidate_line_i"
5008 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5009 (match_operand:SI 1 "register_operand" "r")]
5011 (clobber (match_scratch:SI 2 "=&r"))]
5013 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5014 [(set_attr "length" "8")
5015 (set_attr "type" "cwb")])
5017 (define_insn "ic_invalidate_line_sh4a"
5018 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5021 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5022 [(set_attr "length" "16")
5023 (set_attr "type" "cwb")])
5025 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5026 ;; an add in the code that calculates the address.
5027 (define_insn "ic_invalidate_line_media"
5028 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5031 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5032 [(set_attr "length" "16")
5033 (set_attr "type" "invalidate_line_media")])
5035 (define_insn "ic_invalidate_line_compact"
5036 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5037 (match_operand:SI 1 "register_operand" "r")]
5039 (clobber (reg:SI PR_REG))]
5042 [(set_attr "type" "sfunc")
5043 (set_attr "needs_delay_slot" "yes")])
5045 (define_expand "initialize_trampoline"
5046 [(match_operand:SI 0 "" "")
5047 (match_operand:SI 1 "" "")
5048 (match_operand:SI 2 "" "")]
5054 tramp = force_reg (Pmode, operands[0]);
5055 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5057 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5058 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5060 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5064 (define_insn "initialize_trampoline_compact"
5065 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5066 (match_operand:SI 1 "register_operand" "r")
5067 (reg:SI R2_REG) (reg:SI R3_REG)]
5070 (clobber (reg:SI PR_REG))]
5073 [(set_attr "type" "sfunc")
5074 (set_attr "needs_delay_slot" "yes")])
5076 (define_insn "movqi_i"
5077 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5078 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
5080 && (arith_reg_operand (operands[0], QImode)
5081 || arith_reg_operand (operands[1], QImode))"
5089 [(set_attr "type" "move,load,store,move,move,move")])
5091 (define_insn "*movqi_media"
5092 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5093 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5095 && (arith_reg_operand (operands[0], QImode)
5096 || extend_reg_or_0_operand (operands[1], QImode))"
5102 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5103 (set (attr "highpart")
5104 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5105 (const_string "user")]
5106 (const_string "ignore")))])
5108 (define_expand "movqi"
5109 [(set (match_operand:QI 0 "general_operand" "")
5110 (match_operand:QI 1 "general_operand" ""))]
5112 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5114 (define_expand "reload_inqi"
5115 [(set (match_operand:SI 2 "" "=&r")
5116 (match_operand:QI 1 "inqhi_operand" ""))
5117 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5118 (truncate:QI (match_dup 3)))]
5122 rtx inner = XEXP (operands[1], 0);
5123 int regno = REGNO (inner);
5125 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5126 operands[1] = gen_rtx_REG (SImode, regno);
5127 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5130 /* When storing r0, we have to avoid reg+reg addressing. */
5131 (define_insn "movhi_i"
5132 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5133 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5135 && (arith_reg_operand (operands[0], HImode)
5136 || arith_reg_operand (operands[1], HImode))
5137 && (GET_CODE (operands[0]) != MEM
5138 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5139 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5140 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5150 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5152 (define_insn "*movhi_media"
5153 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5154 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5156 && (arith_reg_operand (operands[0], HImode)
5157 || arith_reg_or_0_operand (operands[1], HImode))"
5164 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5165 (set (attr "highpart")
5166 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5167 (const_string "user")]
5168 (const_string "ignore")))])
5171 [(set (match_operand:HI 0 "register_operand" "")
5172 (match_operand:HI 1 "immediate_operand" ""))]
5173 "TARGET_SHMEDIA && reload_completed
5174 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5175 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5177 (define_expand "movhi"
5178 [(set (match_operand:HI 0 "general_movdst_operand" "")
5179 (match_operand:HI 1 "general_movsrc_operand" ""))]
5181 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5183 (define_expand "reload_inhi"
5184 [(set (match_operand:SI 2 "" "=&r")
5185 (match_operand:HI 1 "inqhi_operand" ""))
5186 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5187 (truncate:HI (match_dup 3)))]
5191 rtx inner = XEXP (operands[1], 0);
5192 int regno = REGNO (inner);
5194 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5195 operands[1] = gen_rtx_REG (SImode, regno);
5196 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5199 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5200 ;; compiled with -m2 -ml -O3 -funroll-loops
5201 (define_insn "*movdi_i"
5202 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5203 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5205 && (arith_reg_operand (operands[0], DImode)
5206 || arith_reg_operand (operands[1], DImode))"
5207 "* return output_movedouble (insn, operands, DImode);"
5208 [(set_attr "length" "4")
5209 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5211 ;; If the output is a register and the input is memory or a register, we have
5212 ;; to be careful and see which word needs to be loaded first.
5215 [(set (match_operand:DI 0 "general_movdst_operand" "")
5216 (match_operand:DI 1 "general_movsrc_operand" ""))]
5217 "TARGET_SH1 && reload_completed"
5218 [(set (match_dup 2) (match_dup 3))
5219 (set (match_dup 4) (match_dup 5))]
5224 if ((GET_CODE (operands[0]) == MEM
5225 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5226 || (GET_CODE (operands[1]) == MEM
5227 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5230 switch (GET_CODE (operands[0]))
5233 regno = REGNO (operands[0]);
5236 regno = subreg_regno (operands[0]);
5246 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5248 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5249 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5250 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5251 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5255 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5256 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5257 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5258 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5261 if (operands[2] == 0 || operands[3] == 0
5262 || operands[4] == 0 || operands[5] == 0)
5266 ;; The '?'s in the following constraints may not reflect the time taken
5267 ;; to perform the move. They are there to discourage the use of floating-
5268 ;; point registers for storing integer values.
5269 (define_insn "*movdi_media"
5270 [(set (match_operand:DI 0 "general_movdst_operand"
5271 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5272 (match_operand:DI 1 "general_movsrc_operand"
5273 "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5275 && (register_operand (operands[0], DImode)
5276 || sh_register_operand (operands[1], DImode))"
5291 [(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")
5292 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5294 (define_insn "*movdi_media_nofpu"
5295 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5296 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5298 && (register_operand (operands[0], DImode)
5299 || sh_register_operand (operands[1], DImode))"
5309 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5310 (set_attr "length" "4,4,16,4,4,4,4,*")])
5312 (define_insn "*movdi_media_I16"
5313 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5314 (match_operand:DI 1 "const_int_operand" "I16"))]
5315 "TARGET_SHMEDIA && reload_completed"
5317 [(set_attr "type" "arith_media")
5318 (set_attr "length" "4")])
5321 [(set (match_operand:DI 0 "arith_reg_dest" "")
5322 (match_operand:DI 1 "immediate_operand" ""))]
5323 "TARGET_SHMEDIA && reload_completed
5324 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5325 [(set (match_dup 0) (match_dup 1))]
5330 if (TARGET_SHMEDIA64)
5331 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5333 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5335 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5341 (define_expand "movdi_const"
5342 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5343 (const:DI (sign_extend:DI
5346 (match_operand:DI 1 "immediate_operand" "s")
5349 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5357 (const_int 32)))))))))
5359 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5367 (const_int 16)))))))))
5369 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5375 (match_dup 1))))))))]
5376 "TARGET_SHMEDIA64 && reload_completed
5377 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5380 sh_mark_label (operands[1], 4);
5383 (define_expand "movdi_const_32bit"
5384 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5385 (const:DI (sign_extend:DI
5388 (match_operand:DI 1 "immediate_operand" "s")
5391 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5397 (match_dup 1))))))))]
5398 "TARGET_SHMEDIA32 && reload_completed
5399 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5402 sh_mark_label (operands[1], 2);
5405 (define_expand "movdi_const_16bit"
5406 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5407 (const:DI (sign_extend:DI
5409 (match_operand:DI 1 "immediate_operand" "s")))))]
5410 "TARGET_SHMEDIA && flag_pic && reload_completed
5411 && GET_CODE (operands[1]) == SYMBOL_REF"
5415 [(set (match_operand:DI 0 "ext_dest_operand" "")
5416 (match_operand:DI 1 "immediate_operand" ""))]
5417 "TARGET_SHMEDIA && reload_completed
5418 && GET_CODE (operands[1]) == CONST_INT
5419 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5420 [(set (match_dup 0) (match_dup 2))
5424 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5425 unsigned HOST_WIDE_INT low = val;
5426 unsigned HOST_WIDE_INT high = val;
5427 unsigned HOST_WIDE_INT sign;
5428 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5430 /* Sign-extend the 16 least-significant bits. */
5435 /* Arithmetic shift right the word by 16 bits. */
5437 if (GET_CODE (operands[0]) == SUBREG
5438 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5447 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5453 /* If we can't generate the constant with a two-insn movi / shori
5454 sequence, try some other strategies. */
5455 if (! CONST_OK_FOR_I16 (high))
5457 /* Try constant load / left shift. We know VAL != 0. */
5458 val2 = val ^ (val-1);
5461 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5463 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5464 || (! CONST_OK_FOR_I16 (high >> 16)
5465 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5467 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5468 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5469 GEN_INT (trailing_zeroes));
5473 /* Try constant load / right shift. */
5474 val2 = (val >> 15) + 1;
5475 if (val2 == (val2 & -val2))
5477 int shift = 49 - exact_log2 (val2);
5479 val2 = trunc_int_for_mode (val << shift, DImode);
5480 if (CONST_OK_FOR_I16 (val2))
5482 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5488 val2 = val & 0xffff;
5489 if ((val >> 16 & 0xffff) == val2
5490 && (val >> 32 & 0xffff) == val2
5491 && (val >> 48 & 0xffff) == val2)
5493 val2 = (HOST_WIDE_INT) val >> 48;
5494 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5495 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5498 /* Try movi / mshflo.l */
5499 val2 = (HOST_WIDE_INT) val >> 32;
5500 if (val2 == ((unsigned HOST_WIDE_INT)
5501 trunc_int_for_mode (val, SImode)))
5503 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5507 /* Try movi / mshflo.l w/ r63. */
5508 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5509 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5511 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5517 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5520 operands[2] = GEN_INT (val2);
5524 [(set (match_operand:DI 0 "ext_dest_operand" "")
5525 (match_operand:DI 1 "immediate_operand" ""))]
5526 "TARGET_SHMEDIA && reload_completed
5527 && GET_CODE (operands[1]) == CONST_DOUBLE"
5528 [(set (match_dup 0) (match_dup 2))
5530 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5531 (zero_extend:DI (truncate:HI (match_dup 1)))))]
5534 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5535 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5536 unsigned HOST_WIDE_INT val = low;
5537 unsigned HOST_WIDE_INT sign;
5539 /* Sign-extend the 16 least-significant bits. */
5543 operands[1] = GEN_INT (val);
5545 /* Arithmetic shift right the double-word by 16 bits. */
5547 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5550 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5554 /* This will only be true if high is a sign-extension of low, i.e.,
5555 it must be either 0 or (unsigned)-1, and be zero iff the
5556 most-significant bit of low is set. */
5557 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5558 operands[2] = GEN_INT (low);
5560 operands[2] = immed_double_const (low, high, DImode);
5563 (define_insn "shori_media"
5564 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5565 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5569 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5570 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5574 [(set_attr "type" "arith_media,*")])
5576 (define_insn "*shori_media_si"
5577 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5578 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5582 (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5586 (define_expand "movdi"
5587 [(set (match_operand:DI 0 "general_movdst_operand" "")
5588 (match_operand:DI 1 "general_movsrc_operand" ""))]
5590 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5592 (define_insn "movdf_media"
5593 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5594 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5596 && (register_operand (operands[0], DFmode)
5597 || sh_register_operand (operands[1], DFmode))"
5608 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5610 (define_insn "movdf_media_nofpu"
5611 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5612 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5614 && (register_operand (operands[0], DFmode)
5615 || sh_register_operand (operands[1], DFmode))"
5621 [(set_attr "type" "arith_media,*,load_media,store_media")])
5624 [(set (match_operand:DF 0 "arith_reg_dest" "")
5625 (match_operand:DF 1 "immediate_operand" ""))]
5626 "TARGET_SHMEDIA && reload_completed"
5627 [(set (match_dup 3) (match_dup 2))]
5630 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5632 REAL_VALUE_TYPE value;
5634 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5635 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5637 if (HOST_BITS_PER_WIDE_INT >= 64)
5638 operands[2] = immed_double_const ((unsigned long) values[endian]
5639 | ((HOST_WIDE_INT) values[1 - endian]
5643 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5644 operands[2] = immed_double_const (values[endian], values[1 - endian],
5648 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5651 ;; ??? This should be a define expand.
5653 (define_insn "movdf_k"
5654 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5655 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5657 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5658 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5659 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5660 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5661 && (arith_reg_operand (operands[0], DFmode)
5662 || arith_reg_operand (operands[1], DFmode))"
5663 "* return output_movedouble (insn, operands, DFmode);"
5664 [(set_attr "length" "4")
5665 (set_attr "type" "move,pcload,load,store")])
5667 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5668 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5669 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5670 ;; the d/m/c/X alternative, which is split later into single-precision
5671 ;; instructions. And when not optimizing, no splits are done before fixing
5672 ;; up pcloads, so we need usable length information for that.
5673 (define_insn "movdf_i4"
5674 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5675 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5676 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5677 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5678 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5679 && (arith_reg_operand (operands[0], DFmode)
5680 || arith_reg_operand (operands[1], DFmode))"
5692 [(set_attr_alternative "length"
5693 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5695 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5696 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5697 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5699 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5700 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5701 ;; increment or decrement r15 explicitly.
5703 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5704 (const_int 10) (const_int 8))
5706 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5707 (const_int 10) (const_int 8))])
5708 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5709 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5710 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5711 (const_string "double")
5712 (const_string "none")))])
5714 ;; Moving DFmode between fp/general registers through memory
5715 ;; (the top of the stack) is faster than moving through fpul even for
5716 ;; little endian. Because the type of an instruction is important for its
5717 ;; scheduling, it is beneficial to split these operations, rather than
5718 ;; emitting them in one single chunk, even if this will expose a stack
5719 ;; use that will prevent scheduling of other stack accesses beyond this
5722 [(set (match_operand:DF 0 "register_operand" "")
5723 (match_operand:DF 1 "register_operand" ""))
5724 (use (match_operand:PSI 2 "fpscr_operand" ""))
5725 (clobber (match_scratch:SI 3 "=X"))]
5726 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5727 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5733 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5735 emit_move_insn (stack_pointer_rtx,
5736 plus_constant (stack_pointer_rtx, -8));
5737 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5740 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5741 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5742 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5743 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5744 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5745 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5747 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5748 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5749 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5750 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5752 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5756 ;; local-alloc sometimes allocates scratch registers even when not required,
5757 ;; so we must be prepared to handle these.
5759 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5761 [(set (match_operand:DF 0 "general_movdst_operand" "")
5762 (match_operand:DF 1 "general_movsrc_operand" ""))
5763 (use (match_operand:PSI 2 "fpscr_operand" ""))
5764 (clobber (match_scratch:SI 3 ""))]
5765 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5767 && true_regnum (operands[0]) < 16
5768 && true_regnum (operands[1]) < 16"
5769 [(set (match_dup 0) (match_dup 1))]
5772 /* If this was a reg <-> mem operation with base + index reg addressing,
5773 we have to handle this in a special way. */
5774 rtx mem = operands[0];
5776 if (! memory_operand (mem, DFmode))
5781 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5782 mem = SUBREG_REG (mem);
5783 if (GET_CODE (mem) == MEM)
5785 rtx addr = XEXP (mem, 0);
5786 if (GET_CODE (addr) == PLUS
5787 && GET_CODE (XEXP (addr, 0)) == REG
5788 && GET_CODE (XEXP (addr, 1)) == REG)
5791 rtx reg0 = gen_rtx_REG (Pmode, 0);
5792 rtx regop = operands[store_p], word0 ,word1;
5794 if (GET_CODE (regop) == SUBREG)
5795 alter_subreg (®op);
5796 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5800 mem = copy_rtx (mem);
5801 PUT_MODE (mem, SImode);
5802 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5803 alter_subreg (&word0);
5804 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5805 alter_subreg (&word1);
5806 if (store_p || ! refers_to_regno_p (REGNO (word0),
5807 REGNO (word0) + 1, addr, 0))
5810 ? gen_movsi_ie (mem, word0)
5811 : gen_movsi_ie (word0, mem));
5812 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5813 mem = copy_rtx (mem);
5815 ? gen_movsi_ie (mem, word1)
5816 : gen_movsi_ie (word1, mem));
5817 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5821 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5822 emit_insn (gen_movsi_ie (word1, mem));
5823 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5824 mem = copy_rtx (mem);
5825 emit_insn (gen_movsi_ie (word0, mem));
5832 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5834 [(set (match_operand:DF 0 "register_operand" "")
5835 (match_operand:DF 1 "memory_operand" ""))
5836 (use (match_operand:PSI 2 "fpscr_operand" ""))
5837 (clobber (reg:SI R0_REG))]
5838 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5839 [(parallel [(set (match_dup 0) (match_dup 1))
5841 (clobber (scratch:SI))])]
5844 (define_expand "reload_indf"
5845 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5846 (match_operand:DF 1 "immediate_operand" "FQ"))
5847 (use (reg:PSI FPSCR_REG))
5848 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5852 (define_expand "reload_outdf"
5853 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5854 (match_operand:DF 1 "register_operand" "af,r"))
5855 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5859 ;; Simplify no-op moves.
5861 [(set (match_operand:SF 0 "register_operand" "")
5862 (match_operand:SF 1 "register_operand" ""))
5863 (use (match_operand:PSI 2 "fpscr_operand" ""))
5864 (clobber (match_scratch:SI 3 ""))]
5865 "TARGET_SH2E && reload_completed
5866 && true_regnum (operands[0]) == true_regnum (operands[1])"
5867 [(set (match_dup 0) (match_dup 0))]
5870 ;; fmovd substitute post-reload splits
5872 [(set (match_operand:DF 0 "register_operand" "")
5873 (match_operand:DF 1 "register_operand" ""))
5874 (use (match_operand:PSI 2 "fpscr_operand" ""))
5875 (clobber (match_scratch:SI 3 ""))]
5876 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5877 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5878 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5882 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5883 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5884 gen_rtx_REG (SFmode, src), operands[2]));
5885 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5886 gen_rtx_REG (SFmode, src + 1), operands[2]));
5891 [(set (match_operand:DF 0 "register_operand" "")
5892 (mem:DF (match_operand:SI 1 "register_operand" "")))
5893 (use (match_operand:PSI 2 "fpscr_operand" ""))
5894 (clobber (match_scratch:SI 3 ""))]
5895 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5896 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5897 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5901 int regno = true_regnum (operands[0]);
5903 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5905 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5906 regno + !! TARGET_LITTLE_ENDIAN),
5907 mem2, operands[2]));
5908 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5909 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5910 regno + ! TARGET_LITTLE_ENDIAN),
5911 gen_rtx_MEM (SFmode, operands[1]),
5917 [(set (match_operand:DF 0 "register_operand" "")
5918 (match_operand:DF 1 "memory_operand" ""))
5919 (use (match_operand:PSI 2 "fpscr_operand" ""))
5920 (clobber (match_scratch:SI 3 ""))]
5921 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5922 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5926 int regno = true_regnum (operands[0]);
5927 rtx addr, insn, adjust = NULL_RTX;
5928 rtx mem2 = copy_rtx (operands[1]);
5929 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5930 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5932 PUT_MODE (mem2, SFmode);
5933 operands[1] = copy_rtx (mem2);
5934 addr = XEXP (mem2, 0);
5935 if (GET_CODE (addr) != POST_INC)
5937 /* If we have to modify the stack pointer, the value that we have
5938 read with post-increment might be modified by an interrupt,
5939 so write it back. */
5940 if (REGNO (addr) == STACK_POINTER_REGNUM)
5941 adjust = gen_push_e (reg0);
5943 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5944 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5946 addr = XEXP (addr, 0);
5947 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5948 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5949 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5953 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5958 [(set (match_operand:DF 0 "memory_operand" "")
5959 (match_operand:DF 1 "register_operand" ""))
5960 (use (match_operand:PSI 2 "fpscr_operand" ""))
5961 (clobber (match_scratch:SI 3 ""))]
5962 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5963 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5967 int regno = true_regnum (operands[1]);
5968 rtx insn, addr, adjust = NULL_RTX;
5970 operands[0] = copy_rtx (operands[0]);
5971 PUT_MODE (operands[0], SFmode);
5972 insn = emit_insn (gen_movsf_ie (operands[0],
5973 gen_rtx_REG (SFmode,
5974 regno + ! TARGET_LITTLE_ENDIAN),
5976 operands[0] = copy_rtx (operands[0]);
5977 addr = XEXP (operands[0], 0);
5978 if (GET_CODE (addr) != PRE_DEC)
5980 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5981 emit_insn_before (adjust, insn);
5982 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5984 addr = XEXP (addr, 0);
5986 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5987 insn = emit_insn (gen_movsf_ie (operands[0],
5988 gen_rtx_REG (SFmode,
5989 regno + !! TARGET_LITTLE_ENDIAN),
5991 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5995 ;; If the output is a register and the input is memory or a register, we have
5996 ;; to be careful and see which word needs to be loaded first.
5999 [(set (match_operand:DF 0 "general_movdst_operand" "")
6000 (match_operand:DF 1 "general_movsrc_operand" ""))]
6001 "TARGET_SH1 && reload_completed"
6002 [(set (match_dup 2) (match_dup 3))
6003 (set (match_dup 4) (match_dup 5))]
6008 if ((GET_CODE (operands[0]) == MEM
6009 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6010 || (GET_CODE (operands[1]) == MEM
6011 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6014 switch (GET_CODE (operands[0]))
6017 regno = REGNO (operands[0]);
6020 regno = subreg_regno (operands[0]);
6030 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6032 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6033 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6034 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6035 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6039 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6040 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6041 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6042 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6045 if (operands[2] == 0 || operands[3] == 0
6046 || operands[4] == 0 || operands[5] == 0)
6050 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6051 ;; used only once, let combine add in the index again.
6054 [(set (match_operand:SI 0 "register_operand" "")
6055 (match_operand:SI 1 "" ""))
6056 (clobber (match_operand 2 "register_operand" ""))]
6057 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6058 && ALLOW_INDEXED_ADDRESS"
6059 [(use (reg:SI R0_REG))]
6062 rtx addr, reg, const_int;
6064 if (GET_CODE (operands[1]) != MEM)
6066 addr = XEXP (operands[1], 0);
6067 if (GET_CODE (addr) != PLUS)
6069 reg = XEXP (addr, 0);
6070 const_int = XEXP (addr, 1);
6071 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6072 && GET_CODE (const_int) == CONST_INT))
6074 emit_move_insn (operands[2], const_int);
6075 emit_move_insn (operands[0],
6076 change_address (operands[1], VOIDmode,
6077 gen_rtx_PLUS (SImode, reg, operands[2])));
6082 [(set (match_operand:SI 1 "" "")
6083 (match_operand:SI 0 "register_operand" ""))
6084 (clobber (match_operand 2 "register_operand" ""))]
6085 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6086 && ALLOW_INDEXED_ADDRESS"
6087 [(use (reg:SI R0_REG))]
6090 rtx addr, reg, const_int;
6092 if (GET_CODE (operands[1]) != MEM)
6094 addr = XEXP (operands[1], 0);
6095 if (GET_CODE (addr) != PLUS)
6097 reg = XEXP (addr, 0);
6098 const_int = XEXP (addr, 1);
6099 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6100 && GET_CODE (const_int) == CONST_INT))
6102 emit_move_insn (operands[2], const_int);
6103 emit_move_insn (change_address (operands[1], VOIDmode,
6104 gen_rtx_PLUS (SImode, reg, operands[2])),
6109 (define_expand "movdf"
6110 [(set (match_operand:DF 0 "general_movdst_operand" "")
6111 (match_operand:DF 1 "general_movsrc_operand" ""))]
6115 if (prepare_move_operands (operands, DFmode)) DONE;
6118 if (TARGET_SHMEDIA_FPU)
6119 emit_insn (gen_movdf_media (operands[0], operands[1]));
6121 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6124 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6126 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6131 ;;This is incompatible with the way gcc uses subregs.
6132 ;;(define_insn "movv2sf_i"
6133 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6134 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6135 ;; "TARGET_SHMEDIA_FPU
6136 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6137 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6141 ;; fst%M0.p %m0, %1"
6142 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6144 (define_insn_and_split "movv2sf_i"
6145 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6146 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6147 "TARGET_SHMEDIA_FPU"
6149 "TARGET_SHMEDIA_FPU && reload_completed"
6150 [(set (match_dup 0) (match_dup 1))]
6153 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6154 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6157 (define_expand "movv2sf"
6158 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6159 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6160 "TARGET_SHMEDIA_FPU"
6163 if (prepare_move_operands (operands, V2SFmode))
6167 (define_expand "addv2sf3"
6168 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6169 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6170 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6171 "TARGET_SHMEDIA_FPU"
6174 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6178 (define_expand "subv2sf3"
6179 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6180 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6181 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6182 "TARGET_SHMEDIA_FPU"
6185 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6189 (define_expand "mulv2sf3"
6190 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6191 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6192 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6193 "TARGET_SHMEDIA_FPU"
6196 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6200 (define_expand "divv2sf3"
6201 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6202 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6203 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6204 "TARGET_SHMEDIA_FPU"
6207 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6211 (define_insn_and_split "*movv4sf_i"
6212 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
6213 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
6214 "TARGET_SHMEDIA_FPU"
6216 "&& reload_completed"
6222 for (i = 0; i < 4/2; i++)
6226 if (GET_CODE (operands[0]) == MEM)
6227 x = gen_rtx_MEM (V2SFmode,
6228 plus_constant (XEXP (operands[0], 0),
6229 i * GET_MODE_SIZE (V2SFmode)));
6231 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6233 if (GET_CODE (operands[1]) == MEM)
6234 y = gen_rtx_MEM (V2SFmode,
6235 plus_constant (XEXP (operands[1], 0),
6236 i * GET_MODE_SIZE (V2SFmode)));
6238 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6240 emit_insn (gen_movv2sf_i (x, y));
6245 [(set_attr "length" "8")])
6247 (define_expand "movv4sf"
6248 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6249 (match_operand:V4SF 1 "general_operand" ""))]
6250 "TARGET_SHMEDIA_FPU"
6253 if (prepare_move_operands (operands, V4SFmode))
6257 (define_insn_and_split "*movv16sf_i"
6258 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6259 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6260 "TARGET_SHMEDIA_FPU"
6262 "&& reload_completed"
6268 for (i = 0; i < 16/2; i++)
6272 if (GET_CODE (operands[0]) == MEM)
6273 x = gen_rtx_MEM (V2SFmode,
6274 plus_constant (XEXP (operands[0], 0),
6275 i * GET_MODE_SIZE (V2SFmode)));
6278 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6282 if (GET_CODE (operands[1]) == MEM)
6283 y = gen_rtx_MEM (V2SFmode,
6284 plus_constant (XEXP (operands[1], 0),
6285 i * GET_MODE_SIZE (V2SFmode)));
6288 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6292 emit_insn (gen_movv2sf_i (x, y));
6297 [(set_attr "length" "32")])
6299 (define_expand "movv16sf"
6300 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6301 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6302 "TARGET_SHMEDIA_FPU"
6305 if (prepare_move_operands (operands, V16SFmode))
6309 (define_insn "movsf_media"
6310 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6311 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6313 && (register_operand (operands[0], SFmode)
6314 || sh_register_operand (operands[1], SFmode))"
6325 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6326 (set (attr "highpart")
6327 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6328 (const_string "user")]
6329 (const_string "ignore")))])
6331 (define_insn "movsf_media_nofpu"
6332 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6333 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6335 && (register_operand (operands[0], SFmode)
6336 || sh_register_operand (operands[1], SFmode))"
6342 [(set_attr "type" "arith_media,*,load_media,store_media")
6343 (set (attr "highpart")
6344 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6345 (const_string "user")]
6346 (const_string "ignore")))])
6349 [(set (match_operand:SF 0 "arith_reg_dest" "")
6350 (match_operand:SF 1 "immediate_operand" ""))]
6351 "TARGET_SHMEDIA && reload_completed
6352 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6353 [(set (match_dup 3) (match_dup 2))]
6357 REAL_VALUE_TYPE value;
6359 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6360 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6361 operands[2] = GEN_INT (values);
6363 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6366 (define_insn "movsf_i"
6367 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6368 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6371 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6372 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6373 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6374 && (arith_reg_operand (operands[0], SFmode)
6375 || arith_reg_operand (operands[1], SFmode))"
6384 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6386 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6387 ;; update_flow_info would not know where to put REG_EQUAL notes
6388 ;; when the destination changes mode.
6389 (define_insn "movsf_ie"
6390 [(set (match_operand:SF 0 "general_movdst_operand"
6391 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6392 (match_operand:SF 1 "general_movsrc_operand"
6393 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6394 (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"))
6395 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6398 && (arith_reg_operand (operands[0], SFmode)
6399 || arith_reg_operand (operands[1], SFmode)
6400 || arith_reg_operand (operands[3], SImode)
6401 || (fpul_operand (operands[0], SFmode)
6402 && memory_operand (operands[1], SFmode)
6403 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6404 || (fpul_operand (operands[1], SFmode)
6405 && memory_operand (operands[0], SFmode)
6406 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6426 ! move optimized away"
6427 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6428 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6429 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6430 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6431 (const_string "single")
6432 (const_string "none")))])
6435 [(set (match_operand:SF 0 "register_operand" "")
6436 (match_operand:SF 1 "register_operand" ""))
6437 (use (match_operand:PSI 2 "fpscr_operand" ""))
6438 (clobber (reg:SI FPUL_REG))]
6440 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6442 (clobber (scratch:SI))])
6443 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6445 (clobber (scratch:SI))])]
6448 (define_expand "movsf"
6449 [(set (match_operand:SF 0 "general_movdst_operand" "")
6450 (match_operand:SF 1 "general_movsrc_operand" ""))]
6454 if (prepare_move_operands (operands, SFmode))
6458 if (TARGET_SHMEDIA_FPU)
6459 emit_insn (gen_movsf_media (operands[0], operands[1]));
6461 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6466 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6471 (define_insn "mov_nop"
6472 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6475 [(set_attr "length" "0")
6476 (set_attr "type" "nil")])
6478 (define_expand "reload_insf"
6479 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6480 (match_operand:SF 1 "immediate_operand" "FQ"))
6481 (use (reg:PSI FPSCR_REG))
6482 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6486 (define_expand "reload_insi"
6487 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6488 (match_operand:SI 1 "immediate_operand" "i"))
6489 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6493 (define_expand "ptabs"
6494 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6498 if (!TARGET_PT_FIXED)
6500 rtx eq = operands[1];
6502 /* ??? For canonical RTL we really should remove any CONST from EQ
6503 before wrapping it in the AND, and finally wrap the EQ into a
6504 const if is constant. However, for reload we must expose the
6505 input register or symbolic constant, and we can't have
6506 different insn structures outside of the operands for different
6507 alternatives of the same pattern. */
6508 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6511 = (gen_rtx_IF_THEN_ELSE
6514 gen_rtx_MEM (PDImode, operands[1]),
6515 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6516 PDImode, operands[1])));
6520 ;; expanded by ptabs expander.
6521 (define_insn "*extendsipdi_media"
6522 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6523 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6527 (mem:PDI (match_dup 1))
6528 (sign_extend:PDI (match_dup 1))))]
6529 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6533 [(set_attr "type" "ptabs_media,pt_media")
6534 (set_attr "length" "4,*")])
6536 (define_insn "*truncdipdi_media"
6537 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6538 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6542 (mem:PDI (match_dup 1))
6543 (truncate:PDI (match_dup 1))))]
6544 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6548 [(set_attr "type" "ptabs_media,pt_media")
6549 (set_attr "length" "4,*")])
6551 (define_insn "*movsi_y"
6552 [(set (match_operand:SI 0 "register_operand" "=y,y")
6553 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6554 (clobber (match_scratch:SI 2 "=&z,r"))]
6556 && (reload_in_progress || reload_completed)"
6558 [(set_attr "length" "4")
6559 (set_attr "type" "pcload,move")])
6562 [(set (match_operand:SI 0 "register_operand" "")
6563 (match_operand:SI 1 "immediate_operand" ""))
6564 (clobber (match_operand:SI 2 "register_operand" ""))]
6566 [(set (match_dup 2) (match_dup 1))
6567 (set (match_dup 0) (match_dup 2))]
6571 [(set (match_operand:SI 0 "register_operand" "")
6572 (match_operand:SI 1 "memory_operand" ""))
6573 (clobber (reg:SI R0_REG))]
6575 [(set (match_dup 0) (match_dup 1))]
6578 ;; ------------------------------------------------------------------------
6579 ;; Define the real conditional branch instructions.
6580 ;; ------------------------------------------------------------------------
6582 (define_insn "branch_true"
6583 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6584 (label_ref (match_operand 0 "" ""))
6587 "* return output_branch (1, insn, operands);"
6588 [(set_attr "type" "cbranch")])
6590 (define_insn "branch_false"
6591 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6592 (label_ref (match_operand 0 "" ""))
6595 "* return output_branch (0, insn, operands);"
6596 [(set_attr "type" "cbranch")])
6598 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6599 ;; which destination is too far away.
6600 ;; The const_int_operand is distinct for each branch target; it avoids
6601 ;; unwanted matches with redundant_insn.
6602 (define_insn "block_branch_redirect"
6603 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6606 [(set_attr "length" "0")])
6608 ;; This one has the additional purpose to record a possible scratch register
6609 ;; for the following branch.
6610 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6611 ;; because the insn then might be deemed dead and deleted. And we can't
6612 ;; make the use in the jump insn explicit because that would disable
6613 ;; delay slot scheduling from the target.
6614 (define_insn "indirect_jump_scratch"
6615 [(set (match_operand:SI 0 "register_operand" "=r")
6616 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6617 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6620 [(set_attr "length" "0")])
6622 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6623 ;; being pulled into the delay slot of a condbranch that has been made to
6624 ;; jump around the unconditional jump because it was out of range.
6625 (define_insn "stuff_delay_slot"
6627 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6628 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6631 [(set_attr "length" "0")
6632 (set_attr "cond_delay_slot" "yes")])
6634 ;; Conditional branch insns
6636 (define_expand "beq_media"
6638 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6639 (match_operand:DI 2 "arith_operand" "r,I06"))
6640 (match_operand 0 "" "")
6643 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6645 (define_insn "*beq_media_i"
6647 (if_then_else (match_operator 3 "equality_comparison_operator"
6648 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6649 (match_operand:DI 2 "arith_operand" "r,I06")])
6650 (match_operand 0 "target_operand" "b,b")
6655 b%o3i%' %1, %2, %0%>"
6656 [(set_attr "type" "cbranch_media")])
6658 (define_insn "*beq_media_i32"
6660 (if_then_else (match_operator 3 "equality_comparison_operator"
6661 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6662 (match_operand:SI 2 "arith_operand" "r,I06")])
6663 (match_operand 0 "target_operand" "b,b")
6668 b%o3i%' %1, %2, %0%>"
6669 [(set_attr "type" "cbranch_media")])
6671 (define_expand "bne_media"
6673 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6674 (match_operand:DI 2 "arith_operand" "r,I06"))
6675 (match_operand 0 "" "")
6678 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6680 (define_expand "bgt_media"
6682 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6683 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6684 (match_operand 0 "" "")
6687 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6689 (define_expand "bge_media"
6691 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6692 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6693 (match_operand 0 "" "")
6696 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6698 (define_expand "bgtu_media"
6700 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6701 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6702 (match_operand 0 "" "")
6705 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6707 (define_expand "bgeu_media"
6709 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6710 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6711 (match_operand 0 "" "")
6714 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6716 (define_insn "*bgt_media_i"
6718 (if_then_else (match_operator 3 "greater_comparison_operator"
6719 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6720 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6721 (match_operand 0 "target_operand" "b")
6724 "b%o3%' %N1, %N2, %0%>"
6725 [(set_attr "type" "cbranch_media")])
6727 (define_insn "*bgt_media_i32"
6729 (if_then_else (match_operator 3 "greater_comparison_operator"
6730 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6731 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6732 (match_operand 0 "target_operand" "b")
6735 "b%o3%' %N1, %N2, %0%>"
6736 [(set_attr "type" "cbranch_media")])
6738 ;; These are only needed to make invert_jump() happy - otherwise, jump
6739 ;; optimization will be silently disabled.
6740 (define_insn "*blt_media_i"
6742 (if_then_else (match_operator 3 "less_comparison_operator"
6743 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6744 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6745 (match_operand 0 "target_operand" "b")
6748 "b%o3%' %N2, %N1, %0%>"
6749 [(set_attr "type" "cbranch_media")])
6751 (define_insn "*blt_media_i32"
6753 (if_then_else (match_operator 3 "less_comparison_operator"
6754 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6755 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6756 (match_operand 0 "target_operand" "b")
6759 "b%o3%' %N2, %N1, %0%>"
6760 [(set_attr "type" "cbranch_media")])
6762 (define_expand "beq"
6764 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6765 (label_ref (match_operand 0 "" ""))
6772 enum machine_mode mode = GET_MODE (sh_compare_op0);
6774 if (mode != DImode && mode != SImode)
6776 rtx tmp = gen_reg_rtx (DImode);
6778 emit_insn (gen_seq (tmp));
6779 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6783 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6784 if (CONSTANT_P (sh_compare_op1)
6785 && (GET_CODE (sh_compare_op1) != CONST_INT
6786 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6787 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6788 emit_jump_insn (gen_beq_media (operands[0],
6789 sh_compare_op0, sh_compare_op1));
6793 from_compare (operands, EQ);
6796 (define_expand "bne"
6798 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6799 (label_ref (match_operand 0 "" ""))
6806 enum machine_mode mode = GET_MODE (sh_compare_op0);
6808 if (mode != DImode && mode != SImode)
6810 rtx tmp = gen_reg_rtx (DImode);
6812 emit_insn (gen_seq (tmp));
6813 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6817 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6818 if (CONSTANT_P (sh_compare_op1)
6819 && (GET_CODE (sh_compare_op1) != CONST_INT
6820 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6821 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6822 emit_jump_insn (gen_bne_media (operands[0],
6823 sh_compare_op0, sh_compare_op1));
6827 from_compare (operands, EQ);
6830 (define_expand "bgt"
6832 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6833 (label_ref (match_operand 0 "" ""))
6840 enum machine_mode mode = GET_MODE (sh_compare_op0);
6842 if (mode != DImode && mode != SImode)
6844 rtx tmp = gen_reg_rtx (DImode);
6846 emit_insn (gen_sgt (tmp));
6847 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6851 if (sh_compare_op0 != const0_rtx)
6852 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6853 if (sh_compare_op1 != const0_rtx)
6854 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6855 emit_jump_insn (gen_bgt_media (operands[0],
6856 sh_compare_op0, sh_compare_op1));
6860 from_compare (operands, GT);
6863 (define_expand "blt"
6865 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6866 (label_ref (match_operand 0 "" ""))
6873 enum machine_mode mode = GET_MODE (sh_compare_op0);
6875 if (mode != DImode && mode != SImode)
6877 rtx tmp = gen_reg_rtx (DImode);
6879 emit_insn (gen_slt (tmp));
6880 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6884 if (sh_compare_op0 != const0_rtx)
6885 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6886 if (sh_compare_op1 != const0_rtx)
6887 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6888 emit_jump_insn (gen_bgt_media (operands[0],
6889 sh_compare_op1, sh_compare_op0));
6893 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6895 rtx tmp = sh_compare_op0;
6896 sh_compare_op0 = sh_compare_op1;
6897 sh_compare_op1 = tmp;
6898 emit_insn (gen_bgt (operands[0]));
6901 from_compare (operands, GE);
6904 (define_expand "ble"
6906 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6907 (label_ref (match_operand 0 "" ""))
6914 enum machine_mode mode = GET_MODE (sh_compare_op0);
6916 if (mode != DImode && mode != SImode)
6918 rtx tmp = gen_reg_rtx (DImode);
6920 emit_insn (gen_sle (tmp));
6921 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6925 if (sh_compare_op0 != const0_rtx)
6926 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6927 if (sh_compare_op1 != const0_rtx)
6928 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6929 emit_jump_insn (gen_bge_media (operands[0],
6930 sh_compare_op1, sh_compare_op0));
6936 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6938 rtx tmp = sh_compare_op0;
6939 sh_compare_op0 = sh_compare_op1;
6940 sh_compare_op1 = tmp;
6941 emit_insn (gen_bge (operands[0]));
6944 from_compare (operands, GT);
6947 (define_expand "bge"
6949 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6950 (label_ref (match_operand 0 "" ""))
6957 enum machine_mode mode = GET_MODE (sh_compare_op0);
6959 if (mode != DImode && mode != SImode)
6961 rtx tmp = gen_reg_rtx (DImode);
6963 emit_insn (gen_sge (tmp));
6964 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6968 if (sh_compare_op0 != const0_rtx)
6969 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6970 if (sh_compare_op1 != const0_rtx)
6971 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6972 emit_jump_insn (gen_bge_media (operands[0],
6973 sh_compare_op0, sh_compare_op1));
6979 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6981 rtx tmp = sh_compare_op0;
6982 sh_compare_op0 = sh_compare_op1;
6983 sh_compare_op1 = tmp;
6984 emit_insn (gen_ble (operands[0]));
6987 from_compare (operands, GE);
6990 (define_expand "bgtu"
6992 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6993 (label_ref (match_operand 0 "" ""))
7000 enum machine_mode mode = GET_MODE (sh_compare_op0);
7002 if (sh_compare_op0 != const0_rtx)
7003 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7004 if (sh_compare_op1 != const0_rtx)
7005 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7006 emit_jump_insn (gen_bgtu_media (operands[0],
7007 sh_compare_op0, sh_compare_op1));
7011 from_compare (operands, GTU);
7014 (define_expand "bltu"
7016 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7017 (label_ref (match_operand 0 "" ""))
7024 enum machine_mode mode = GET_MODE (sh_compare_op0);
7026 if (sh_compare_op0 != const0_rtx)
7027 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7028 if (sh_compare_op1 != const0_rtx)
7029 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030 emit_jump_insn (gen_bgtu_media (operands[0],
7031 sh_compare_op1, sh_compare_op0));
7035 from_compare (operands, GEU);
7038 (define_expand "bgeu"
7040 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7041 (label_ref (match_operand 0 "" ""))
7048 enum machine_mode mode = GET_MODE (sh_compare_op0);
7050 if (sh_compare_op0 != const0_rtx)
7051 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7052 if (sh_compare_op1 != const0_rtx)
7053 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7054 emit_jump_insn (gen_bgeu_media (operands[0],
7055 sh_compare_op0, sh_compare_op1));
7059 from_compare (operands, GEU);
7062 (define_expand "bleu"
7064 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7065 (label_ref (match_operand 0 "" ""))
7072 enum machine_mode mode = GET_MODE (sh_compare_op0);
7074 if (sh_compare_op0 != const0_rtx)
7075 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7076 if (sh_compare_op1 != const0_rtx)
7077 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7078 emit_jump_insn (gen_bgeu_media (operands[0],
7079 sh_compare_op1, sh_compare_op0));
7083 from_compare (operands, GTU);
7086 (define_expand "bunordered"
7087 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7089 (if_then_else (ne (match_dup 1) (const_int 0))
7090 (match_operand 0 "" "")
7095 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7096 operands[1] = gen_reg_rtx (DImode);
7097 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7098 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7101 ;; combiner splitter for test-and-branch on single bit in register. This
7102 ;; is endian dependent because the non-paradoxical subreg looks different
7107 (match_operator 3 "equality_comparison_operator"
7108 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7109 "extend_reg_operand" "")
7113 "const_int_operand" "")) 0)
7115 (match_operand 0 "target_operand" "")
7117 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7118 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7119 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7120 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7124 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7125 operands[6] = (GET_CODE (operands[3]) == EQ
7126 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7127 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7130 ;; ------------------------------------------------------------------------
7131 ;; Jump and linkage insns
7132 ;; ------------------------------------------------------------------------
7134 (define_insn "jump_compact"
7136 (label_ref (match_operand 0 "" "")))]
7140 /* The length is 16 if the delay slot is unfilled. */
7141 if (get_attr_length(insn) > 4)
7142 return output_far_jump(insn, operands[0]);
7144 return \"bra %l0%#\";
7146 [(set_attr "type" "jump")
7147 (set_attr "needs_delay_slot" "yes")])
7149 ;; ??? It would be much saner to explicitly use the scratch register
7150 ;; in the jump insn, and have indirect_jump_scratch only set it,
7151 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7152 ;; from the target then, as it uses simplejump_p.
7153 ;;(define_insn "jump_compact_far"
7155 ;; (label_ref (match_operand 0 "" "")))
7156 ;; (use (match_operand 1 "register_operand" "r")]
7158 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7159 ;; [(set_attr "type" "jump")
7160 ;; (set_attr "needs_delay_slot" "yes")])
7162 (define_insn "jump_media"
7164 (match_operand 0 "target_operand" "b"))]
7167 [(set_attr "type" "jump_media")])
7169 (define_expand "jump"
7171 (label_ref (match_operand 0 "" "")))]
7176 emit_jump_insn (gen_jump_compact (operands[0]));
7177 else if (TARGET_SHMEDIA)
7179 if (reload_in_progress || reload_completed)
7181 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7187 (define_insn "force_mode_for_call"
7188 [(use (reg:PSI FPSCR_REG))]
7191 [(set_attr "length" "0")
7192 (set (attr "fp_mode")
7193 (if_then_else (eq_attr "fpu_single" "yes")
7194 (const_string "single") (const_string "double")))])
7196 (define_insn "calli"
7197 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7198 (match_operand 1 "" ""))
7199 (use (reg:PSI FPSCR_REG))
7200 (clobber (reg:SI PR_REG))]
7203 [(set_attr "type" "call")
7204 (set (attr "fp_mode")
7205 (if_then_else (eq_attr "fpu_single" "yes")
7206 (const_string "single") (const_string "double")))
7207 (set_attr "needs_delay_slot" "yes")
7208 (set_attr "fp_set" "unknown")])
7210 ;; This is a pc-rel call, using bsrf, for use with PIC.
7212 (define_insn "calli_pcrel"
7213 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7214 (match_operand 1 "" ""))
7215 (use (reg:PSI FPSCR_REG))
7216 (use (reg:SI PIC_REG))
7217 (use (match_operand 2 "" ""))
7218 (clobber (reg:SI PR_REG))]
7221 [(set_attr "type" "call")
7222 (set (attr "fp_mode")
7223 (if_then_else (eq_attr "fpu_single" "yes")
7224 (const_string "single") (const_string "double")))
7225 (set_attr "needs_delay_slot" "yes")
7226 (set_attr "fp_set" "unknown")])
7228 (define_insn_and_split "call_pcrel"
7229 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7230 (match_operand 1 "" ""))
7231 (use (reg:PSI FPSCR_REG))
7232 (use (reg:SI PIC_REG))
7233 (clobber (reg:SI PR_REG))
7234 (clobber (match_scratch:SI 2 "=r"))]
7241 rtx lab = PATTERN (gen_call_site ());
7243 if (SYMBOL_REF_LOCAL_P (operands[0]))
7244 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7246 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7247 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7250 [(set_attr "type" "call")
7251 (set (attr "fp_mode")
7252 (if_then_else (eq_attr "fpu_single" "yes")
7253 (const_string "single") (const_string "double")))
7254 (set_attr "needs_delay_slot" "yes")
7255 (set_attr "fp_set" "unknown")])
7257 (define_insn "call_compact"
7258 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7259 (match_operand 1 "" ""))
7260 (match_operand 2 "immediate_operand" "n")
7261 (use (reg:SI R0_REG))
7262 (use (reg:SI R1_REG))
7263 (use (reg:PSI FPSCR_REG))
7264 (clobber (reg:SI PR_REG))]
7265 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7267 [(set_attr "type" "call")
7268 (set (attr "fp_mode")
7269 (if_then_else (eq_attr "fpu_single" "yes")
7270 (const_string "single") (const_string "double")))
7271 (set_attr "needs_delay_slot" "yes")])
7273 (define_insn "call_compact_rettramp"
7274 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7275 (match_operand 1 "" ""))
7276 (match_operand 2 "immediate_operand" "n")
7277 (use (reg:SI R0_REG))
7278 (use (reg:SI R1_REG))
7279 (use (reg:PSI FPSCR_REG))
7280 (clobber (reg:SI R10_REG))
7281 (clobber (reg:SI PR_REG))]
7282 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7284 [(set_attr "type" "call")
7285 (set (attr "fp_mode")
7286 (if_then_else (eq_attr "fpu_single" "yes")
7287 (const_string "single") (const_string "double")))
7288 (set_attr "needs_delay_slot" "yes")])
7290 (define_insn "call_media"
7291 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7292 (match_operand 1 "" ""))
7293 (clobber (reg:DI PR_MEDIA_REG))]
7296 [(set_attr "type" "jump_media")])
7298 (define_insn "call_valuei"
7299 [(set (match_operand 0 "" "=rf")
7300 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7301 (match_operand 2 "" "")))
7302 (use (reg:PSI FPSCR_REG))
7303 (clobber (reg:SI PR_REG))]
7306 [(set_attr "type" "call")
7307 (set (attr "fp_mode")
7308 (if_then_else (eq_attr "fpu_single" "yes")
7309 (const_string "single") (const_string "double")))
7310 (set_attr "needs_delay_slot" "yes")
7311 (set_attr "fp_set" "unknown")])
7313 (define_insn "call_valuei_pcrel"
7314 [(set (match_operand 0 "" "=rf")
7315 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7316 (match_operand 2 "" "")))
7317 (use (reg:PSI FPSCR_REG))
7318 (use (reg:SI PIC_REG))
7319 (use (match_operand 3 "" ""))
7320 (clobber (reg:SI PR_REG))]
7323 [(set_attr "type" "call")
7324 (set (attr "fp_mode")
7325 (if_then_else (eq_attr "fpu_single" "yes")
7326 (const_string "single") (const_string "double")))
7327 (set_attr "needs_delay_slot" "yes")
7328 (set_attr "fp_set" "unknown")])
7330 (define_insn_and_split "call_value_pcrel"
7331 [(set (match_operand 0 "" "=rf")
7332 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7333 (match_operand 2 "" "")))
7334 (use (reg:PSI FPSCR_REG))
7335 (use (reg:SI PIC_REG))
7336 (clobber (reg:SI PR_REG))
7337 (clobber (match_scratch:SI 3 "=r"))]
7344 rtx lab = PATTERN (gen_call_site ());
7346 if (SYMBOL_REF_LOCAL_P (operands[1]))
7347 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7349 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7350 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7354 [(set_attr "type" "call")
7355 (set (attr "fp_mode")
7356 (if_then_else (eq_attr "fpu_single" "yes")
7357 (const_string "single") (const_string "double")))
7358 (set_attr "needs_delay_slot" "yes")
7359 (set_attr "fp_set" "unknown")])
7361 (define_insn "call_value_compact"
7362 [(set (match_operand 0 "" "=rf")
7363 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7364 (match_operand 2 "" "")))
7365 (match_operand 3 "immediate_operand" "n")
7366 (use (reg:SI R0_REG))
7367 (use (reg:SI R1_REG))
7368 (use (reg:PSI FPSCR_REG))
7369 (clobber (reg:SI PR_REG))]
7370 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7372 [(set_attr "type" "call")
7373 (set (attr "fp_mode")
7374 (if_then_else (eq_attr "fpu_single" "yes")
7375 (const_string "single") (const_string "double")))
7376 (set_attr "needs_delay_slot" "yes")])
7378 (define_insn "call_value_compact_rettramp"
7379 [(set (match_operand 0 "" "=rf")
7380 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7381 (match_operand 2 "" "")))
7382 (match_operand 3 "immediate_operand" "n")
7383 (use (reg:SI R0_REG))
7384 (use (reg:SI R1_REG))
7385 (use (reg:PSI FPSCR_REG))
7386 (clobber (reg:SI R10_REG))
7387 (clobber (reg:SI PR_REG))]
7388 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7390 [(set_attr "type" "call")
7391 (set (attr "fp_mode")
7392 (if_then_else (eq_attr "fpu_single" "yes")
7393 (const_string "single") (const_string "double")))
7394 (set_attr "needs_delay_slot" "yes")])
7396 (define_insn "call_value_media"
7397 [(set (match_operand 0 "" "=rf")
7398 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7399 (match_operand 2 "" "")))
7400 (clobber (reg:DI PR_MEDIA_REG))]
7403 [(set_attr "type" "jump_media")])
7405 (define_expand "call"
7406 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7407 (match_operand 1 "" ""))
7408 (match_operand 2 "" "")
7409 (use (reg:PSI FPSCR_REG))
7410 (clobber (reg:SI PR_REG))])]
7416 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7417 emit_call_insn (gen_call_media (operands[0], operands[1]));
7420 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7422 rtx cookie_rtx = operands[2];
7423 long cookie = INTVAL (cookie_rtx);
7424 rtx func = XEXP (operands[0], 0);
7429 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7431 rtx reg = gen_reg_rtx (Pmode);
7433 emit_insn (gen_symGOTPLT2reg (reg, func));
7437 func = legitimize_pic_address (func, Pmode, 0);
7440 r0 = gen_rtx_REG (SImode, R0_REG);
7441 r1 = gen_rtx_REG (SImode, R1_REG);
7443 /* Since such a call function may use all call-clobbered
7444 registers, we force a mode switch earlier, so that we don't
7445 run out of registers when adjusting fpscr for the call. */
7446 emit_insn (gen_force_mode_for_call ());
7449 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7451 operands[0] = force_reg (SImode, operands[0]);
7453 emit_move_insn (r0, func);
7454 emit_move_insn (r1, cookie_rtx);
7456 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7457 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7460 emit_call_insn (gen_call_compact (operands[0], operands[1],
7465 else if (TARGET_SHCOMPACT && flag_pic
7466 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7467 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7469 rtx reg = gen_reg_rtx (Pmode);
7471 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7472 XEXP (operands[0], 0) = reg;
7474 if (flag_pic && TARGET_SH2
7475 && GET_CODE (operands[0]) == MEM
7476 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7478 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7483 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7484 operands[1] = operands[2];
7487 emit_call_insn (gen_calli (operands[0], operands[1]));
7491 (define_insn "call_pop_compact"
7492 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7493 (match_operand 1 "" ""))
7494 (match_operand 2 "immediate_operand" "n")
7495 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7496 (match_operand 3 "immediate_operand" "n")))
7497 (use (reg:SI R0_REG))
7498 (use (reg:SI R1_REG))
7499 (use (reg:PSI FPSCR_REG))
7500 (clobber (reg:SI PR_REG))]
7501 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7503 [(set_attr "type" "call")
7504 (set (attr "fp_mode")
7505 (if_then_else (eq_attr "fpu_single" "yes")
7506 (const_string "single") (const_string "double")))
7507 (set_attr "needs_delay_slot" "yes")])
7509 (define_insn "call_pop_compact_rettramp"
7510 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7511 (match_operand 1 "" ""))
7512 (match_operand 2 "immediate_operand" "n")
7513 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514 (match_operand 3 "immediate_operand" "n")))
7515 (use (reg:SI R0_REG))
7516 (use (reg:SI R1_REG))
7517 (use (reg:PSI FPSCR_REG))
7518 (clobber (reg:SI R10_REG))
7519 (clobber (reg:SI PR_REG))]
7520 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")])
7528 (define_expand "call_pop"
7529 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7530 (match_operand 1 "" ""))
7531 (match_operand 2 "" "")
7532 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533 (match_operand 3 "" "")))])]
7542 gcc_assert (operands[2] && INTVAL (operands[2]));
7543 cookie_rtx = operands[2];
7544 cookie = INTVAL (cookie_rtx);
7545 func = XEXP (operands[0], 0);
7549 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7551 rtx reg = gen_reg_rtx (Pmode);
7552 emit_insn (gen_symGOTPLT2reg (reg, func));
7556 func = legitimize_pic_address (func, Pmode, 0);
7559 r0 = gen_rtx_REG (SImode, R0_REG);
7560 r1 = gen_rtx_REG (SImode, R1_REG);
7562 /* Since such a call function may use all call-clobbered
7563 registers, we force a mode switch earlier, so that we don't
7564 run out of registers when adjusting fpscr for the call. */
7565 emit_insn (gen_force_mode_for_call ());
7567 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7569 operands[0] = force_reg (SImode, operands[0]);
7571 emit_move_insn (r0, func);
7572 emit_move_insn (r1, cookie_rtx);
7574 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7575 emit_call_insn (gen_call_pop_compact_rettramp
7576 (operands[0], operands[1], operands[2], operands[3]));
7578 emit_call_insn (gen_call_pop_compact
7579 (operands[0], operands[1], operands[2], operands[3]));
7584 (define_expand "call_value"
7585 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7586 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7587 (match_operand 2 "" "")))
7588 (match_operand 3 "" "")
7589 (use (reg:PSI FPSCR_REG))
7590 (clobber (reg:SI PR_REG))])]
7596 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7597 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7601 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7603 rtx cookie_rtx = operands[3];
7604 long cookie = INTVAL (cookie_rtx);
7605 rtx func = XEXP (operands[1], 0);
7610 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7612 rtx reg = gen_reg_rtx (Pmode);
7614 emit_insn (gen_symGOTPLT2reg (reg, func));
7618 func = legitimize_pic_address (func, Pmode, 0);
7621 r0 = gen_rtx_REG (SImode, R0_REG);
7622 r1 = gen_rtx_REG (SImode, R1_REG);
7624 /* Since such a call function may use all call-clobbered
7625 registers, we force a mode switch earlier, so that we don't
7626 run out of registers when adjusting fpscr for the call. */
7627 emit_insn (gen_force_mode_for_call ());
7630 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7632 operands[1] = force_reg (SImode, operands[1]);
7634 emit_move_insn (r0, func);
7635 emit_move_insn (r1, cookie_rtx);
7637 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7638 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7643 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7644 operands[2], operands[3]));
7648 else if (TARGET_SHCOMPACT && flag_pic
7649 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7650 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7652 rtx reg = gen_reg_rtx (Pmode);
7654 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7655 XEXP (operands[1], 0) = reg;
7657 if (flag_pic && TARGET_SH2
7658 && GET_CODE (operands[1]) == MEM
7659 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7661 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7666 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7668 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7672 (define_insn "sibcalli"
7673 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7674 (match_operand 1 "" ""))
7675 (use (reg:PSI FPSCR_REG))
7679 [(set_attr "needs_delay_slot" "yes")
7680 (set (attr "fp_mode")
7681 (if_then_else (eq_attr "fpu_single" "yes")
7682 (const_string "single") (const_string "double")))
7683 (set_attr "type" "jump_ind")])
7685 (define_insn "sibcalli_pcrel"
7686 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7687 (match_operand 1 "" ""))
7688 (use (match_operand 2 "" ""))
7689 (use (reg:PSI FPSCR_REG))
7693 [(set_attr "needs_delay_slot" "yes")
7694 (set (attr "fp_mode")
7695 (if_then_else (eq_attr "fpu_single" "yes")
7696 (const_string "single") (const_string "double")))
7697 (set_attr "type" "jump_ind")])
7699 ;; This uses an unspec to describe that the symbol_ref is very close.
7700 (define_insn "sibcalli_thunk"
7701 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7703 (match_operand 1 "" ""))
7704 (use (reg:PSI FPSCR_REG))
7708 [(set_attr "needs_delay_slot" "yes")
7709 (set (attr "fp_mode")
7710 (if_then_else (eq_attr "fpu_single" "yes")
7711 (const_string "single") (const_string "double")))
7712 (set_attr "type" "jump")
7713 (set_attr "length" "2")])
7715 (define_insn_and_split "sibcall_pcrel"
7716 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7717 (match_operand 1 "" ""))
7718 (use (reg:PSI FPSCR_REG))
7719 (clobber (match_scratch:SI 2 "=k"))
7727 rtx lab = PATTERN (gen_call_site ());
7730 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7731 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7733 SIBLING_CALL_P (call_insn) = 1;
7736 [(set_attr "needs_delay_slot" "yes")
7737 (set (attr "fp_mode")
7738 (if_then_else (eq_attr "fpu_single" "yes")
7739 (const_string "single") (const_string "double")))
7740 (set_attr "type" "jump_ind")])
7742 (define_insn "sibcall_compact"
7743 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7744 (match_operand 1 "" ""))
7746 (use (match_operand:SI 2 "register_operand" "z,x"))
7747 (use (reg:SI R1_REG))
7748 (use (reg:PSI FPSCR_REG))
7749 ;; We want to make sure the `x' above will only match MACH_REG
7750 ;; because sibcall_epilogue may clobber MACL_REG.
7751 (clobber (reg:SI MACL_REG))]
7755 jmp @%0\\n sts %2, r0"
7756 [(set_attr "needs_delay_slot" "yes,no")
7757 (set_attr "length" "2,4")
7758 (set (attr "fp_mode") (const_string "single"))
7759 (set_attr "type" "jump_ind")])
7761 (define_insn "sibcall_media"
7762 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7763 (match_operand 1 "" ""))
7764 (use (reg:SI PR_MEDIA_REG))
7768 [(set_attr "type" "jump_media")])
7770 (define_expand "sibcall"
7772 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7773 (match_operand 1 "" ""))
7774 (match_operand 2 "" "")
7775 (use (reg:PSI FPSCR_REG))
7782 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7783 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7786 else if (TARGET_SHCOMPACT && operands[2]
7787 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7789 rtx cookie_rtx = operands[2];
7790 long cookie = INTVAL (cookie_rtx);
7791 rtx func = XEXP (operands[0], 0);
7796 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7798 rtx reg = gen_reg_rtx (Pmode);
7800 emit_insn (gen_symGOT2reg (reg, func));
7804 func = legitimize_pic_address (func, Pmode, 0);
7807 /* FIXME: if we could tell whether all argument registers are
7808 already taken, we could decide whether to force the use of
7809 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7810 simple way to tell. We could use the CALL_COOKIE, but we
7811 can't currently tell a register used for regular argument
7812 passing from one that is unused. If we leave it up to reload
7813 to decide which register to use, it seems to always choose
7814 R0_REG, which leaves no available registers in SIBCALL_REGS
7815 to hold the address of the trampoline. */
7816 mach = gen_rtx_REG (SImode, MACH_REG);
7817 r1 = gen_rtx_REG (SImode, R1_REG);
7819 /* Since such a call function may use all call-clobbered
7820 registers, we force a mode switch earlier, so that we don't
7821 run out of registers when adjusting fpscr for the call. */
7822 emit_insn (gen_force_mode_for_call ());
7825 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7827 operands[0] = force_reg (SImode, operands[0]);
7829 /* We don't need a return trampoline, since the callee will
7830 return directly to the upper caller. */
7831 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7833 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7834 cookie_rtx = GEN_INT (cookie);
7837 emit_move_insn (mach, func);
7838 emit_move_insn (r1, cookie_rtx);
7840 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7843 else if (TARGET_SHCOMPACT && flag_pic
7844 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7845 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7847 rtx reg = gen_reg_rtx (Pmode);
7849 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7850 XEXP (operands[0], 0) = reg;
7852 if (flag_pic && TARGET_SH2
7853 && GET_CODE (operands[0]) == MEM
7854 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7855 /* The PLT needs the PIC register, but the epilogue would have
7856 to restore it, so we can only use PC-relative PIC calls for
7857 static functions. */
7858 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7860 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7864 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7866 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7870 (define_expand "sibcall_value"
7871 [(set (match_operand 0 "" "")
7872 (call (match_operand 1 "" "")
7873 (match_operand 2 "" "")))
7874 (match_operand 3 "" "")]
7878 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7882 (define_insn "call_value_pop_compact"
7883 [(set (match_operand 0 "" "=rf")
7884 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7885 (match_operand 2 "" "")))
7886 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7887 (match_operand 4 "immediate_operand" "n")))
7888 (match_operand 3 "immediate_operand" "n")
7889 (use (reg:SI R0_REG))
7890 (use (reg:SI R1_REG))
7891 (use (reg:PSI FPSCR_REG))
7892 (clobber (reg:SI PR_REG))]
7893 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7895 [(set_attr "type" "call")
7896 (set (attr "fp_mode")
7897 (if_then_else (eq_attr "fpu_single" "yes")
7898 (const_string "single") (const_string "double")))
7899 (set_attr "needs_delay_slot" "yes")])
7901 (define_insn "call_value_pop_compact_rettramp"
7902 [(set (match_operand 0 "" "=rf")
7903 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7904 (match_operand 2 "" "")))
7905 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7906 (match_operand 4 "immediate_operand" "n")))
7907 (match_operand 3 "immediate_operand" "n")
7908 (use (reg:SI R0_REG))
7909 (use (reg:SI R1_REG))
7910 (use (reg:PSI FPSCR_REG))
7911 (clobber (reg:SI R10_REG))
7912 (clobber (reg:SI PR_REG))]
7913 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7915 [(set_attr "type" "call")
7916 (set (attr "fp_mode")
7917 (if_then_else (eq_attr "fpu_single" "yes")
7918 (const_string "single") (const_string "double")))
7919 (set_attr "needs_delay_slot" "yes")])
7921 (define_expand "call_value_pop"
7922 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7923 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7924 (match_operand 2 "" "")))
7925 (match_operand 3 "" "")
7926 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7927 (match_operand 4 "" "")))])]
7936 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7937 cookie_rtx = operands[3];
7938 cookie = INTVAL (cookie_rtx);
7939 func = XEXP (operands[1], 0);
7943 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7945 rtx reg = gen_reg_rtx (Pmode);
7947 emit_insn (gen_symGOTPLT2reg (reg, func));
7951 func = legitimize_pic_address (func, Pmode, 0);
7954 r0 = gen_rtx_REG (SImode, R0_REG);
7955 r1 = gen_rtx_REG (SImode, R1_REG);
7957 /* Since such a call function may use all call-clobbered
7958 registers, we force a mode switch earlier, so that we don't
7959 run out of registers when adjusting fpscr for the call. */
7960 emit_insn (gen_force_mode_for_call ());
7962 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7964 operands[1] = force_reg (SImode, operands[1]);
7966 emit_move_insn (r0, func);
7967 emit_move_insn (r1, cookie_rtx);
7969 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7970 emit_call_insn (gen_call_value_pop_compact_rettramp
7971 (operands[0], operands[1], operands[2],
7972 operands[3], operands[4]));
7974 emit_call_insn (gen_call_value_pop_compact
7975 (operands[0], operands[1], operands[2],
7976 operands[3], operands[4]));
7981 (define_expand "sibcall_epilogue"
7986 sh_expand_epilogue (1);
7987 if (TARGET_SHCOMPACT)
7991 /* If epilogue clobbers r0, preserve it in macl. */
7992 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7993 if ((set = single_set (insn))
7994 && GET_CODE (SET_DEST (set)) == REG
7995 && REGNO (SET_DEST (set)) == R0_REG)
7997 rtx r0 = gen_rtx_REG (SImode, R0_REG);
7998 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8001 /* We can't tell at this point whether the sibcall is a
8002 sibcall_compact and, if it is, whether it uses r0 or
8003 mach as operand 2, so let the instructions that
8004 preserve r0 be optimized away if r0 turns out to be
8006 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8007 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8009 i = emit_move_insn (r0, tmp);
8010 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8018 (define_insn "indirect_jump_compact"
8020 (match_operand:SI 0 "arith_reg_operand" "r"))]
8023 [(set_attr "needs_delay_slot" "yes")
8024 (set_attr "type" "jump_ind")])
8026 (define_expand "indirect_jump"
8028 (match_operand 0 "register_operand" ""))]
8032 if (GET_MODE (operands[0]) != Pmode)
8033 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8036 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8037 ;; which can be present in structured code from indirect jumps which can not
8038 ;; be present in structured code. This allows -fprofile-arcs to work.
8040 ;; For SH1 processors.
8041 (define_insn "casesi_jump_1"
8043 (match_operand:SI 0 "register_operand" "r"))
8044 (use (label_ref (match_operand 1 "" "")))]
8047 [(set_attr "needs_delay_slot" "yes")
8048 (set_attr "type" "jump_ind")])
8050 ;; For all later processors.
8051 (define_insn "casesi_jump_2"
8052 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8053 (label_ref (match_operand 1 "" ""))))
8054 (use (label_ref (match_operand 2 "" "")))]
8056 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8058 [(set_attr "needs_delay_slot" "yes")
8059 (set_attr "type" "jump_ind")])
8061 (define_insn "casesi_jump_media"
8062 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8063 (use (label_ref (match_operand 1 "" "")))]
8066 [(set_attr "type" "jump_media")])
8068 ;; Call subroutine returning any type.
8069 ;; ??? This probably doesn't work.
8071 (define_expand "untyped_call"
8072 [(parallel [(call (match_operand 0 "" "")
8074 (match_operand 1 "" "")
8075 (match_operand 2 "" "")])]
8076 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8081 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8083 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8085 rtx set = XVECEXP (operands[2], 0, i);
8086 emit_move_insn (SET_DEST (set), SET_SRC (set));
8089 /* The optimizer does not know that the call sets the function value
8090 registers we stored in the result block. We avoid problems by
8091 claiming that all hard registers are used and clobbered at this
8093 emit_insn (gen_blockage ());
8098 ;; ------------------------------------------------------------------------
8100 ;; ------------------------------------------------------------------------
8103 [(set (reg:SI T_REG)
8104 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8105 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8108 [(set_attr "type" "arith")])
8115 ;; Load address of a label. This is only generated by the casesi expand,
8116 ;; and by machine_dependent_reorg (fixing up fp moves).
8117 ;; This must use unspec, because this only works for labels that are
8121 [(set (reg:SI R0_REG)
8122 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8125 [(set_attr "in_delay_slot" "no")
8126 (set_attr "type" "arith")])
8128 ;; machine_dependent_reorg will make this a `mova'.
8129 (define_insn "mova_const"
8130 [(set (reg:SI R0_REG)
8131 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8134 [(set_attr "in_delay_slot" "no")
8135 (set_attr "type" "arith")])
8137 (define_expand "GOTaddr2picreg"
8138 [(set (reg:SI R0_REG)
8139 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8141 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8142 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8145 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8146 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8150 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8151 rtx pic = operands[0];
8152 rtx lab = PATTERN (gen_call_site ());
8155 equiv = operands[1];
8156 operands[1] = gen_rtx_MINUS (Pmode,
8160 gen_rtx_MINUS (Pmode,
8161 gen_rtx_CONST (Pmode,
8164 operands[1] = gen_sym2PIC (operands[1]);
8165 PUT_MODE (operands[1], Pmode);
8167 if (Pmode == SImode)
8169 emit_insn (gen_movsi_const (pic, operands[1]));
8170 emit_insn (gen_ptrel_si (tr, pic, lab));
8174 emit_insn (gen_movdi_const (pic, operands[1]));
8175 emit_insn (gen_ptrel_di (tr, pic, lab));
8178 insn = emit_move_insn (operands[0], tr);
8180 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8189 [(set (match_operand 0 "target_reg_operand" "=b")
8190 (const (unspec [(match_operand 1 "" "Csy")]
8191 UNSPEC_DATALABEL)))]
8192 "TARGET_SHMEDIA && flag_pic
8193 && EXTRA_CONSTRAINT_Csy (operands[1])"
8194 "ptb/u datalabel %1, %0"
8195 [(set_attr "type" "ptabs_media")
8196 (set_attr "length" "*")])
8198 (define_insn "ptrel_si"
8199 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8200 (plus:SI (match_operand:SI 1 "register_operand" "r")
8202 (match_operand:SI 2 "" "")]
8204 "%O2: ptrel/u %1, %0"
8205 [(set_attr "type" "ptabs_media")])
8207 (define_insn "ptrel_di"
8208 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8209 (plus:DI (match_operand:DI 1 "register_operand" "r")
8211 (match_operand:DI 2 "" "")]
8213 "%O2: ptrel/u %1, %0"
8214 [(set_attr "type" "ptabs_media")])
8216 (define_expand "builtin_setjmp_receiver"
8217 [(match_operand 0 "" "")]
8221 emit_insn (gen_GOTaddr2picreg ());
8225 (define_expand "call_site"
8226 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8230 static HOST_WIDE_INT i = 0;
8231 operands[0] = GEN_INT (i);
8235 (define_expand "sym_label2reg"
8236 [(set (match_operand:SI 0 "" "")
8239 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8242 (match_operand:SI 2 "" "")
8246 (define_expand "symGOT_load"
8247 [(set (match_dup 2) (match_operand 1 "" ""))
8248 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8249 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8255 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8256 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8260 rtx reg = operands[2];
8262 if (Pmode == DImode)
8265 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8267 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8272 emit_insn (gen_movsi_const (reg, operands[1]));
8274 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8278 emit_move_insn (operands[2], operands[1]);
8280 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8282 gen_rtx_REG (Pmode, PIC_REG)));
8284 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
8286 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8293 (define_expand "sym2GOT"
8294 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8298 (define_expand "symGOT2reg"
8299 [(match_operand 0 "" "") (match_operand 1 "" "")]
8305 gotsym = gen_sym2GOT (operands[1]);
8306 PUT_MODE (gotsym, Pmode);
8307 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8309 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8314 (define_expand "sym2GOTPLT"
8315 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8319 (define_expand "symGOTPLT2reg"
8320 [(match_operand 0 "" "") (match_operand 1 "" "")]
8324 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8328 (define_expand "sym2GOTOFF"
8329 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8333 (define_expand "symGOTOFF2reg"
8334 [(match_operand 0 "" "") (match_operand 1 "" "")]
8338 rtx gotoffsym, insn;
8339 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8341 gotoffsym = gen_sym2GOTOFF (operands[1]);
8342 PUT_MODE (gotoffsym, Pmode);
8343 emit_move_insn (t, gotoffsym);
8344 insn = emit_move_insn (operands[0],
8345 gen_rtx_PLUS (Pmode, t,
8346 gen_rtx_REG (Pmode, PIC_REG)));
8348 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8354 (define_expand "symPLT_label2reg"
8355 [(set (match_operand:SI 0 "" "")
8358 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8362 (match_operand:SI 2 "" "")
8364 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8365 ;; Even though the PIC register is not really used by the call
8366 ;; sequence in which this is expanded, the PLT code assumes the PIC
8367 ;; register is set, so we must not skip its initialization. Since
8368 ;; we only use this expand as part of calling sequences, and never
8369 ;; to take the address of a function, this is the best point to
8370 ;; insert the (use). Using the PLT to take the address of a
8371 ;; function would be wrong, not only because the PLT entry could
8372 ;; then be called from a function that doesn't initialize the PIC
8373 ;; register to the proper GOT, but also because pointers to the
8374 ;; same function might not compare equal, should they be set by
8375 ;; different shared libraries.
8376 (use (reg:SI PIC_REG))]
8380 (define_expand "sym2PIC"
8381 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8385 ;; TLS code generation.
8386 ;; ??? this should be a define_insn_and_split
8387 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8388 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8391 (define_insn "tls_global_dynamic"
8392 [(set (match_operand:SI 0 "register_operand" "=&z")
8393 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8396 (use (reg:PSI FPSCR_REG))
8397 (use (reg:SI PIC_REG))
8398 (clobber (reg:SI PR_REG))
8399 (clobber (scratch:SI))]
8405 \\tmova\\t2f,r0\\n\\
8406 \\tmov.l\\t2f,r1\\n\\
8409 \\tadd\\tr12,r4\\n\\
8413 1:\\t.long\\t%a1@TLSGD\\n\\
8414 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8417 [(set_attr "type" "tls_load")
8418 (set_attr "length" "26")])
8420 (define_insn "tls_local_dynamic"
8421 [(set (match_operand:SI 0 "register_operand" "=&z")
8422 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8425 (use (reg:PSI FPSCR_REG))
8426 (use (reg:SI PIC_REG))
8427 (clobber (reg:SI PR_REG))
8428 (clobber (scratch:SI))]
8434 \\tmova\\t2f,r0\\n\\
8435 \\tmov.l\\t2f,r1\\n\\
8438 \\tadd\\tr12,r4\\n\\
8442 1:\\t.long\\t%a1@TLSLDM\\n\\
8443 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8446 [(set_attr "type" "tls_load")
8447 (set_attr "length" "26")])
8449 (define_expand "sym2DTPOFF"
8450 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8454 (define_expand "symDTPOFF2reg"
8455 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8459 rtx dtpoffsym, insn;
8460 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8462 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8463 PUT_MODE (dtpoffsym, Pmode);
8464 emit_move_insn (t, dtpoffsym);
8465 insn = emit_move_insn (operands[0],
8466 gen_rtx_PLUS (Pmode, t, operands[2]));
8470 (define_expand "sym2GOTTPOFF"
8471 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8475 (define_insn "tls_initial_exec"
8476 [(set (match_operand:SI 0 "register_operand" "=&r")
8477 (unspec:SI [(match_operand:SI 1 "" "")]
8479 (use (reg:SI GBR_REG))
8480 (use (reg:SI PIC_REG))
8481 (clobber (reg:SI R0_REG))]
8487 \\tstc\\tgbr,%0\\n\\
8488 \\tmov.l\\t@(r0,r12),r0\\n\\
8492 1:\\t.long\\t%a1\\n\\
8495 [(set_attr "type" "tls_load")
8496 (set_attr "length" "16")])
8498 (define_expand "sym2TPOFF"
8499 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8503 (define_expand "symTPOFF2reg"
8504 [(match_operand 0 "" "") (match_operand 1 "" "")]
8510 tpoffsym = gen_sym2TPOFF (operands[1]);
8511 PUT_MODE (tpoffsym, Pmode);
8512 insn = emit_move_insn (operands[0], tpoffsym);
8516 (define_insn "load_gbr"
8517 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8518 (use (reg:SI GBR_REG))]
8521 [(set_attr "type" "tls_load")])
8523 ;; case instruction for switch statements.
8525 ;; Operand 0 is index
8526 ;; operand 1 is the minimum bound
8527 ;; operand 2 is the maximum bound - minimum bound + 1
8528 ;; operand 3 is CODE_LABEL for the table;
8529 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8531 (define_expand "casesi"
8532 [(match_operand:SI 0 "arith_reg_operand" "")
8533 (match_operand:SI 1 "arith_reg_operand" "")
8534 (match_operand:SI 2 "arith_reg_operand" "")
8535 (match_operand 3 "" "") (match_operand 4 "" "")]
8539 rtx reg = gen_reg_rtx (SImode);
8540 rtx reg2 = gen_reg_rtx (SImode);
8543 rtx reg = gen_reg_rtx (DImode);
8544 rtx reg2 = gen_reg_rtx (DImode);
8545 rtx reg3 = gen_reg_rtx (Pmode);
8546 rtx reg4 = gen_reg_rtx (Pmode);
8547 rtx reg5 = gen_reg_rtx (Pmode);
8550 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8551 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8552 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8554 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8555 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8556 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8557 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8558 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8559 (Pmode, operands[3])));
8560 /* Messy: can we subreg to clean this up? */
8561 if (Pmode == DImode)
8562 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8564 load = gen_casesi_load_media (reg4,
8565 gen_rtx_SUBREG (DImode, reg3, 0),
8567 PUT_MODE (SET_SRC (load), Pmode);
8569 /* ??? The following add could be eliminated if we used ptrel. */
8570 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8571 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8575 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8576 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8577 /* If optimizing, casesi_worker depends on the mode of the instruction
8578 before label it 'uses' - operands[3]. */
8579 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8581 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8583 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8585 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8586 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8587 operands[3], but to lab. We will fix this up in
8588 machine_dependent_reorg. */
8593 (define_expand "casesi_0"
8594 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8595 (set (match_dup 4) (minus:SI (match_dup 4)
8596 (match_operand:SI 1 "arith_operand" "")))
8598 (gtu:SI (match_dup 4)
8599 (match_operand:SI 2 "arith_reg_operand" "")))
8601 (if_then_else (ne (reg:SI T_REG)
8603 (label_ref (match_operand 3 "" ""))
8608 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8609 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8610 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8612 (define_insn "casesi_worker_0"
8613 [(set (match_operand:SI 0 "register_operand" "=r,r")
8614 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8615 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8616 (clobber (match_scratch:SI 3 "=X,1"))
8617 (clobber (match_scratch:SI 4 "=&z,z"))]
8622 [(set (match_operand:SI 0 "register_operand" "")
8623 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8624 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8625 (clobber (match_scratch:SI 3 ""))
8626 (clobber (match_scratch:SI 4 ""))]
8627 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8628 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8629 (parallel [(set (match_dup 0)
8630 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8631 (label_ref (match_dup 2))] UNSPEC_CASESI))
8632 (clobber (match_dup 3))])
8633 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8634 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8637 [(set (match_operand:SI 0 "register_operand" "")
8638 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8639 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8640 (clobber (match_scratch:SI 3 ""))
8641 (clobber (match_scratch:SI 4 ""))]
8642 "TARGET_SH2 && reload_completed"
8643 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8644 (parallel [(set (match_dup 0)
8645 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8646 (label_ref (match_dup 2))] UNSPEC_CASESI))
8647 (clobber (match_dup 3))])]
8648 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8650 (define_insn "casesi_worker_1"
8651 [(set (match_operand:SI 0 "register_operand" "=r,r")
8652 (unspec:SI [(reg:SI R0_REG)
8653 (match_operand:SI 1 "register_operand" "0,r")
8654 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8655 (clobber (match_scratch:SI 3 "=X,1"))]
8659 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8661 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8663 switch (GET_MODE (diff_vec))
8666 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8668 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8670 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8671 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8672 return \"mov.b @(r0,%1),%0\";
8677 [(set_attr "length" "4")])
8679 (define_insn "casesi_worker_2"
8680 [(set (match_operand:SI 0 "register_operand" "=r,r")
8681 (unspec:SI [(reg:SI R0_REG)
8682 (match_operand:SI 1 "register_operand" "0,r")
8683 (label_ref (match_operand 2 "" ""))
8684 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8685 (clobber (match_operand:SI 4 "" "=X,1"))]
8686 "TARGET_SH2 && reload_completed && flag_pic"
8689 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8692 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8694 switch (GET_MODE (diff_vec))
8697 output_asm_insn (\"shll2 %1\", operands);
8698 load = \"mov.l @(r0,%1),%0\"; break;
8700 output_asm_insn (\"add %1,%1\", operands);
8701 load = \"mov.w @(r0,%1),%0\"; break;
8703 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8704 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8706 load = \"mov.b @(r0,%1),%0\";
8711 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8714 [(set_attr "length" "8")])
8716 (define_insn "casesi_shift_media"
8717 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8718 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8719 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8724 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8726 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8728 switch (GET_MODE (diff_vec))
8731 return \"shlli %1, 2, %0\";
8733 return \"shlli %1, 1, %0\";
8735 if (rtx_equal_p (operands[0], operands[1]))
8737 return \"add %1, r63, %0\";
8742 [(set_attr "type" "arith_media")])
8744 (define_insn "casesi_load_media"
8745 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8746 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8747 (match_operand:DI 2 "arith_reg_operand" "r")
8748 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8752 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8754 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8756 switch (GET_MODE (diff_vec))
8759 return \"ldx.l %1, %2, %0\";
8762 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8763 return \"ldx.uw %1, %2, %0\";
8765 return \"ldx.w %1, %2, %0\";
8767 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8768 return \"ldx.ub %1, %2, %0\";
8769 return \"ldx.b %1, %2, %0\";
8774 [(set_attr "type" "load_media")])
8776 (define_expand "return"
8778 "reload_completed && ! sh_need_epilogue ()"
8783 emit_jump_insn (gen_return_media ());
8787 if (TARGET_SHCOMPACT
8788 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8790 emit_jump_insn (gen_shcompact_return_tramp ());
8795 (define_insn "*return_i"
8797 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8798 && (current_function_args_info.call_cookie
8799 & CALL_COOKIE_RET_TRAMP (1)))
8800 && reload_completed"
8802 [(set_attr "type" "return")
8803 (set_attr "needs_delay_slot" "yes")])
8805 (define_expand "shcompact_return_tramp"
8808 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8811 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8813 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8814 emit_jump_insn (gen_shcompact_return_tramp_i ());
8818 (define_insn "shcompact_return_tramp_i"
8819 [(parallel [(return) (use (reg:SI R0_REG))])]
8821 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8823 [(set_attr "type" "jump_ind")
8824 (set_attr "needs_delay_slot" "yes")])
8826 (define_insn "return_media_i"
8827 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8828 "TARGET_SHMEDIA && reload_completed"
8830 [(set_attr "type" "jump_media")])
8832 (define_insn "return_media_rte"
8834 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8836 [(set_attr "type" "jump_media")])
8838 (define_expand "return_media"
8840 "TARGET_SHMEDIA && reload_completed"
8843 int tr_regno = sh_media_register_for_return ();
8846 if (current_function_interrupt)
8848 emit_jump_insn (gen_return_media_rte ());
8853 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8855 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8857 tr = gen_rtx_REG (Pmode, tr_regno);
8858 emit_move_insn (tr, r18);
8861 tr = gen_rtx_REG (Pmode, tr_regno);
8863 emit_jump_insn (gen_return_media_i (tr));
8867 (define_insn "shcompact_preserve_incoming_args"
8868 [(set (match_operand:SI 0 "register_operand" "+r")
8869 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8872 [(set_attr "length" "0")])
8874 (define_insn "shcompact_incoming_args"
8875 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8876 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8877 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8878 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8879 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8880 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8881 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8882 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8883 (set (mem:BLK (reg:SI MACL_REG))
8884 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8885 (use (reg:SI R0_REG))
8886 (clobber (reg:SI R0_REG))
8887 (clobber (reg:SI MACL_REG))
8888 (clobber (reg:SI MACH_REG))
8889 (clobber (reg:SI PR_REG))]
8892 [(set_attr "needs_delay_slot" "yes")])
8894 (define_insn "shmedia_save_restore_regs_compact"
8895 [(set (reg:SI SP_REG)
8896 (plus:SI (reg:SI SP_REG)
8897 (match_operand:SI 0 "immediate_operand" "i")))
8898 (use (reg:SI R0_REG))
8899 (clobber (reg:SI PR_REG))]
8901 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8902 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8904 [(set_attr "needs_delay_slot" "yes")])
8906 (define_expand "prologue"
8909 "sh_expand_prologue (); DONE;")
8911 (define_expand "epilogue"
8916 sh_expand_epilogue (0);
8917 emit_jump_insn (gen_return ());
8921 (define_expand "eh_return"
8922 [(use (match_operand 0 "register_operand" ""))]
8925 rtx ra = operands[0];
8927 if (TARGET_SHMEDIA64)
8928 emit_insn (gen_eh_set_ra_di (ra));
8930 emit_insn (gen_eh_set_ra_si (ra));
8935 ;; Clobber the return address on the stack. We can't expand this
8936 ;; until we know where it will be put in the stack frame.
8938 (define_insn "eh_set_ra_si"
8939 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8940 (clobber (match_scratch:SI 1 "=&r"))]
8941 "! TARGET_SHMEDIA64"
8944 (define_insn "eh_set_ra_di"
8945 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8946 (clobber (match_scratch:DI 1 "=&r"))]
8951 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8952 (clobber (match_scratch 1 ""))]
8957 sh_set_return_address (operands[0], operands[1]);
8961 (define_insn "blockage"
8962 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8965 [(set_attr "length" "0")])
8967 ;; ------------------------------------------------------------------------
8969 ;; ------------------------------------------------------------------------
8972 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8973 (eq:SI (reg:SI T_REG) (const_int 1)))]
8976 [(set_attr "type" "arith")])
8978 (define_expand "seq"
8979 [(set (match_operand:SI 0 "arith_reg_dest" "")
8986 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8987 if (sh_compare_op1 != const0_rtx)
8988 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8989 ? GET_MODE (sh_compare_op0)
8990 : GET_MODE (sh_compare_op1),
8992 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8994 if (GET_MODE (operands[0]) != SImode)
8995 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
8997 switch (GET_MODE (sh_compare_op0))
9000 emit_insn (gen_cmpsieqsi_media (operands[0],
9001 sh_compare_op0, sh_compare_op1));
9005 emit_insn (gen_cmpsieqdi_media (operands[0],
9006 sh_compare_op0, sh_compare_op1));
9010 if (! TARGET_SHMEDIA_FPU)
9012 emit_insn (gen_cmpsieqsf_media (operands[0],
9013 sh_compare_op0, sh_compare_op1));
9017 if (! TARGET_SHMEDIA_FPU)
9019 emit_insn (gen_cmpsieqdf_media (operands[0],
9020 sh_compare_op0, sh_compare_op1));
9029 if (GET_MODE (operands[0]) != DImode)
9030 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9032 switch (GET_MODE (sh_compare_op0))
9035 emit_insn (gen_cmpeqsi_media (operands[0],
9036 sh_compare_op0, sh_compare_op1));
9040 emit_insn (gen_cmpeqdi_media (operands[0],
9041 sh_compare_op0, sh_compare_op1));
9045 if (! TARGET_SHMEDIA_FPU)
9047 emit_insn (gen_cmpeqsf_media (operands[0],
9048 sh_compare_op0, sh_compare_op1));
9052 if (! TARGET_SHMEDIA_FPU)
9054 emit_insn (gen_cmpeqdf_media (operands[0],
9055 sh_compare_op0, sh_compare_op1));
9063 if (sh_expand_t_scc (EQ, operands[0]))
9065 if (! currently_expanding_to_rtl)
9067 operands[1] = prepare_scc_operands (EQ);
9070 (define_expand "slt"
9071 [(set (match_operand:SI 0 "arith_reg_operand" "")
9078 if (GET_MODE (operands[0]) != DImode)
9079 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9080 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9081 if (sh_compare_op1 != const0_rtx)
9082 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9083 ? GET_MODE (sh_compare_op0)
9084 : GET_MODE (sh_compare_op1),
9087 switch (GET_MODE (sh_compare_op0))
9090 emit_insn (gen_cmpgtsi_media (operands[0],
9091 sh_compare_op1, sh_compare_op0));
9095 emit_insn (gen_cmpgtdi_media (operands[0],
9096 sh_compare_op1, sh_compare_op0));
9100 if (! TARGET_SHMEDIA_FPU)
9102 emit_insn (gen_cmpgtsf_media (operands[0],
9103 sh_compare_op1, sh_compare_op0));
9107 if (! TARGET_SHMEDIA_FPU)
9109 emit_insn (gen_cmpgtdf_media (operands[0],
9110 sh_compare_op1, sh_compare_op0));
9118 if (! currently_expanding_to_rtl)
9120 operands[1] = prepare_scc_operands (LT);
9123 (define_expand "sle"
9124 [(match_operand:SI 0 "arith_reg_operand" "")]
9128 rtx tmp = sh_compare_op0;
9132 if (GET_MODE (operands[0]) != DImode)
9133 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9134 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9135 if (sh_compare_op1 != const0_rtx)
9136 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9137 ? GET_MODE (sh_compare_op0)
9138 : GET_MODE (sh_compare_op1),
9141 switch (GET_MODE (sh_compare_op0))
9145 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9147 emit_insn (gen_cmpgtsi_media (tmp,
9148 sh_compare_op0, sh_compare_op1));
9149 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9155 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9157 emit_insn (gen_cmpgtdi_media (tmp,
9158 sh_compare_op0, sh_compare_op1));
9159 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9164 if (! TARGET_SHMEDIA_FPU)
9166 emit_insn (gen_cmpgesf_media (operands[0],
9167 sh_compare_op1, sh_compare_op0));
9171 if (! TARGET_SHMEDIA_FPU)
9173 emit_insn (gen_cmpgedf_media (operands[0],
9174 sh_compare_op1, sh_compare_op0));
9183 sh_compare_op0 = sh_compare_op1;
9184 sh_compare_op1 = tmp;
9185 emit_insn (gen_sge (operands[0]));
9189 (define_expand "sgt"
9190 [(set (match_operand:SI 0 "arith_reg_operand" "")
9197 if (GET_MODE (operands[0]) != DImode)
9198 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9199 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9200 if (sh_compare_op1 != const0_rtx)
9201 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9202 ? GET_MODE (sh_compare_op0)
9203 : GET_MODE (sh_compare_op1),
9206 switch (GET_MODE (sh_compare_op0))
9209 emit_insn (gen_cmpgtsi_media (operands[0],
9210 sh_compare_op0, sh_compare_op1));
9214 emit_insn (gen_cmpgtdi_media (operands[0],
9215 sh_compare_op0, sh_compare_op1));
9219 if (! TARGET_SHMEDIA_FPU)
9221 emit_insn (gen_cmpgtsf_media (operands[0],
9222 sh_compare_op0, sh_compare_op1));
9226 if (! TARGET_SHMEDIA_FPU)
9228 emit_insn (gen_cmpgtdf_media (operands[0],
9229 sh_compare_op0, sh_compare_op1));
9237 if (! currently_expanding_to_rtl)
9239 operands[1] = prepare_scc_operands (GT);
9242 (define_expand "sge"
9243 [(set (match_operand:SI 0 "arith_reg_operand" "")
9250 enum machine_mode mode = GET_MODE (sh_compare_op0);
9252 if ((mode) == VOIDmode)
9253 mode = GET_MODE (sh_compare_op1);
9254 if (GET_MODE (operands[0]) != DImode)
9255 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9256 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9257 if (sh_compare_op1 != const0_rtx)
9258 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9264 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9266 emit_insn (gen_cmpgtsi_media (tmp,
9267 sh_compare_op1, sh_compare_op0));
9268 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9274 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9276 emit_insn (gen_cmpgtdi_media (tmp,
9277 sh_compare_op1, sh_compare_op0));
9278 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9283 if (! TARGET_SHMEDIA_FPU)
9285 emit_insn (gen_cmpgesf_media (operands[0],
9286 sh_compare_op0, sh_compare_op1));
9290 if (! TARGET_SHMEDIA_FPU)
9292 emit_insn (gen_cmpgedf_media (operands[0],
9293 sh_compare_op0, sh_compare_op1));
9302 if (! currently_expanding_to_rtl)
9304 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9308 rtx lab = gen_label_rtx ();
9309 prepare_scc_operands (EQ);
9310 emit_jump_insn (gen_branch_true (lab));
9311 prepare_scc_operands (GT);
9313 emit_insn (gen_movt (operands[0]));
9316 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9319 operands[1] = prepare_scc_operands (GE);
9322 (define_expand "sgtu"
9323 [(set (match_operand:SI 0 "arith_reg_operand" "")
9330 if (GET_MODE (operands[0]) != DImode)
9331 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9332 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9333 if (sh_compare_op1 != const0_rtx)
9334 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9335 ? GET_MODE (sh_compare_op0)
9336 : GET_MODE (sh_compare_op1),
9339 emit_insn (gen_cmpgtudi_media (operands[0],
9340 sh_compare_op0, sh_compare_op1));
9343 if (! currently_expanding_to_rtl)
9345 operands[1] = prepare_scc_operands (GTU);
9348 (define_expand "sltu"
9349 [(set (match_operand:SI 0 "arith_reg_operand" "")
9356 if (GET_MODE (operands[0]) != DImode)
9357 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9358 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9359 if (sh_compare_op1 != const0_rtx)
9360 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9361 ? GET_MODE (sh_compare_op0)
9362 : GET_MODE (sh_compare_op1),
9365 emit_insn (gen_cmpgtudi_media (operands[0],
9366 sh_compare_op1, sh_compare_op0));
9369 if (! currently_expanding_to_rtl)
9371 operands[1] = prepare_scc_operands (LTU);
9374 (define_expand "sleu"
9375 [(set (match_operand:SI 0 "arith_reg_operand" "")
9384 if (GET_MODE (operands[0]) != DImode)
9385 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9386 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9387 if (sh_compare_op1 != const0_rtx)
9388 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9389 ? GET_MODE (sh_compare_op0)
9390 : GET_MODE (sh_compare_op1),
9393 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9395 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9396 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9400 if (! currently_expanding_to_rtl)
9402 operands[1] = prepare_scc_operands (LEU);
9405 (define_expand "sgeu"
9406 [(set (match_operand:SI 0 "arith_reg_operand" "")
9415 if (GET_MODE (operands[0]) != DImode)
9416 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9417 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9418 if (sh_compare_op1 != const0_rtx)
9419 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9420 ? GET_MODE (sh_compare_op0)
9421 : GET_MODE (sh_compare_op1),
9424 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9426 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9427 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9432 if (! currently_expanding_to_rtl)
9434 operands[1] = prepare_scc_operands (GEU);
9437 ;; sne moves the complement of the T reg to DEST like this:
9441 ;; This is better than xoring compare result with 1 because it does
9442 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9445 (define_expand "sne"
9446 [(set (match_dup 2) (const_int -1))
9447 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9448 (neg:SI (plus:SI (match_dup 1)
9451 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9460 if (GET_MODE (operands[0]) != DImode)
9461 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9463 if (! TARGET_SHMEDIA_FPU
9464 && GET_MODE (sh_compare_op0) != DImode
9465 && GET_MODE (sh_compare_op0) != SImode)
9468 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9469 if (sh_compare_op1 != const0_rtx)
9470 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9471 ? GET_MODE (sh_compare_op0)
9472 : GET_MODE (sh_compare_op1),
9475 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9477 emit_insn (gen_seq (tmp));
9478 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9483 if (sh_expand_t_scc (NE, operands[0]))
9485 if (! currently_expanding_to_rtl)
9487 operands[1] = prepare_scc_operands (EQ);
9488 operands[2] = gen_reg_rtx (SImode);
9491 (define_expand "sunordered"
9492 [(set (match_operand:DI 0 "arith_reg_operand" "")
9493 (unordered:DI (match_dup 1) (match_dup 2)))]
9494 "TARGET_SHMEDIA_FPU"
9497 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9498 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9501 ;; Use the same trick for FP sle / sge
9503 ;; Apart from the constant use and the T setting, this is like movt,
9504 ;; except that it uses the logically negated value of T, i.e.
9505 ;; operand[0] := T ? 0 : 1.
9506 (define_expand "movnegt"
9507 [(set (match_dup 2) (const_int -1))
9508 (parallel [(set (match_operand 0 "" "")
9509 (neg:SI (plus:SI (match_dup 1)
9512 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9515 "operands[2] = gen_reg_rtx (SImode);")
9517 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9518 ;; This prevents a regression that occurred when we switched from xor to
9522 [(set (match_operand:SI 0 "arith_reg_dest" "")
9523 (plus:SI (reg:SI T_REG)
9526 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9527 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9530 ;; -------------------------------------------------------------------------
9531 ;; Instructions to cope with inline literal tables
9532 ;; -------------------------------------------------------------------------
9534 ; 2 byte integer in line
9536 (define_insn "consttable_2"
9537 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9538 (match_operand 1 "" "")]
9543 if (operands[1] != const0_rtx)
9544 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9547 [(set_attr "length" "2")
9548 (set_attr "in_delay_slot" "no")])
9550 ; 4 byte integer in line
9552 (define_insn "consttable_4"
9553 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9554 (match_operand 1 "" "")]
9559 if (operands[1] != const0_rtx)
9560 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9563 [(set_attr "length" "4")
9564 (set_attr "in_delay_slot" "no")])
9566 ; 8 byte integer in line
9568 (define_insn "consttable_8"
9569 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9570 (match_operand 1 "" "")]
9575 if (operands[1] != const0_rtx)
9576 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9579 [(set_attr "length" "8")
9580 (set_attr "in_delay_slot" "no")])
9582 ; 4 byte floating point
9584 (define_insn "consttable_sf"
9585 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9586 (match_operand 1 "" "")]
9591 if (operands[1] != const0_rtx)
9594 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9595 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9599 [(set_attr "length" "4")
9600 (set_attr "in_delay_slot" "no")])
9602 ; 8 byte floating point
9604 (define_insn "consttable_df"
9605 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9606 (match_operand 1 "" "")]
9611 if (operands[1] != const0_rtx)
9614 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9615 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9619 [(set_attr "length" "8")
9620 (set_attr "in_delay_slot" "no")])
9622 ;; Alignment is needed for some constant tables; it may also be added for
9623 ;; Instructions at the start of loops, or after unconditional branches.
9624 ;; ??? We would get more accurate lengths if we did instruction
9625 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9626 ;; here is too conservative.
9628 ; align to a two byte boundary
9630 (define_expand "align_2"
9631 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9635 ; align to a four byte boundary
9636 ;; align_4 and align_log are instructions for the starts of loops, or
9637 ;; after unconditional branches, which may take up extra room.
9639 (define_expand "align_4"
9640 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9644 ; align to a cache line boundary
9646 (define_insn "align_log"
9647 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9650 [(set_attr "length" "0")
9651 (set_attr "in_delay_slot" "no")])
9653 ; emitted at the end of the literal table, used to emit the
9654 ; 32bit branch labels if needed.
9656 (define_insn "consttable_end"
9657 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9659 "* return output_jump_label_table ();"
9660 [(set_attr "in_delay_slot" "no")])
9662 ; emitted at the end of the window in the literal table.
9664 (define_insn "consttable_window_end"
9665 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9668 [(set_attr "length" "0")
9669 (set_attr "in_delay_slot" "no")])
9671 ;; -------------------------------------------------------------------------
9673 ;; -------------------------------------------------------------------------
9675 ;; String/block move insn.
9677 (define_expand "movmemsi"
9678 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9679 (mem:BLK (match_operand:BLK 1 "" "")))
9680 (use (match_operand:SI 2 "nonmemory_operand" ""))
9681 (use (match_operand:SI 3 "immediate_operand" ""))
9682 (clobber (reg:SI PR_REG))
9683 (clobber (reg:SI R4_REG))
9684 (clobber (reg:SI R5_REG))
9685 (clobber (reg:SI R0_REG))])]
9686 "TARGET_SH1 && ! TARGET_SH5"
9689 if(expand_block_move (operands))
9694 (define_insn "block_move_real"
9695 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9696 (mem:BLK (reg:SI R5_REG)))
9697 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9698 (clobber (reg:SI PR_REG))
9699 (clobber (reg:SI R0_REG))])]
9700 "TARGET_SH1 && ! TARGET_HARD_SH4"
9702 [(set_attr "type" "sfunc")
9703 (set_attr "needs_delay_slot" "yes")])
9705 (define_insn "block_lump_real"
9706 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9707 (mem:BLK (reg:SI R5_REG)))
9708 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9709 (use (reg:SI R6_REG))
9710 (clobber (reg:SI PR_REG))
9711 (clobber (reg:SI T_REG))
9712 (clobber (reg:SI R4_REG))
9713 (clobber (reg:SI R5_REG))
9714 (clobber (reg:SI R6_REG))
9715 (clobber (reg:SI R0_REG))])]
9716 "TARGET_SH1 && ! TARGET_HARD_SH4"
9718 [(set_attr "type" "sfunc")
9719 (set_attr "needs_delay_slot" "yes")])
9721 (define_insn "block_move_real_i4"
9722 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9723 (mem:BLK (reg:SI R5_REG)))
9724 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9725 (clobber (reg:SI PR_REG))
9726 (clobber (reg:SI R0_REG))
9727 (clobber (reg:SI R1_REG))
9728 (clobber (reg:SI R2_REG))])]
9731 [(set_attr "type" "sfunc")
9732 (set_attr "needs_delay_slot" "yes")])
9734 (define_insn "block_lump_real_i4"
9735 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9736 (mem:BLK (reg:SI R5_REG)))
9737 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9738 (use (reg:SI R6_REG))
9739 (clobber (reg:SI PR_REG))
9740 (clobber (reg:SI T_REG))
9741 (clobber (reg:SI R4_REG))
9742 (clobber (reg:SI R5_REG))
9743 (clobber (reg:SI R6_REG))
9744 (clobber (reg:SI R0_REG))
9745 (clobber (reg:SI R1_REG))
9746 (clobber (reg:SI R2_REG))
9747 (clobber (reg:SI R3_REG))])]
9750 [(set_attr "type" "sfunc")
9751 (set_attr "needs_delay_slot" "yes")])
9753 ;; -------------------------------------------------------------------------
9754 ;; Floating point instructions.
9755 ;; -------------------------------------------------------------------------
9757 ;; ??? All patterns should have a type attribute.
9759 (define_expand "fpu_switch0"
9760 [(set (match_operand:SI 0 "" "") (match_dup 2))
9761 (set (match_dup 1) (mem:PSI (match_dup 0)))]
9762 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9765 operands[1] = get_fpscr_rtx ();
9766 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9768 operands[2] = legitimize_pic_address (operands[2], SImode,
9769 no_new_pseudos ? operands[0] : 0);
9772 (define_expand "fpu_switch1"
9773 [(set (match_operand:SI 0 "" "") (match_dup 2))
9774 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
9775 (set (match_dup 1) (mem:PSI (match_dup 3)))]
9776 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9779 operands[1] = get_fpscr_rtx ();
9780 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9782 operands[2] = legitimize_pic_address (operands[2], SImode,
9783 no_new_pseudos ? operands[0] : 0);
9784 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9787 (define_expand "movpsi"
9788 [(set (match_operand:PSI 0 "register_operand" "")
9789 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9790 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9793 ;; The c / m alternative is a fake to guide reload to load directly into
9794 ;; fpscr, since reload doesn't know how to use post-increment.
9795 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9796 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9797 ;; predicate after reload.
9798 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9799 ;; like a mac -> gpr move.
9800 (define_insn "fpu_switch"
9801 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9802 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9804 && (! reload_completed
9805 || true_regnum (operands[0]) != FPSCR_REG
9806 || GET_CODE (operands[1]) != MEM
9807 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9809 ! precision stays the same
9818 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9819 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9822 [(set (reg:PSI FPSCR_REG)
9823 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9824 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9825 [(set (match_dup 0) (match_dup 0))]
9828 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9829 gen_rtx_MEM (PSImode,
9830 gen_rtx_POST_INC (Pmode,
9832 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9836 [(set (reg:PSI FPSCR_REG)
9837 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9838 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9839 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
9842 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9843 gen_rtx_MEM (PSImode,
9844 gen_rtx_POST_INC (Pmode,
9846 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9849 ;; ??? This uses the fp unit, but has no type indicating that.
9850 ;; If we did that, this would either give a bogus latency or introduce
9851 ;; a bogus FIFO constraint.
9852 ;; Since this insn is currently only used for prologues/epilogues,
9853 ;; it is probably best to claim no function unit, which matches the
9855 (define_insn "toggle_sz"
9856 [(set (reg:PSI FPSCR_REG)
9857 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9858 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9860 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9862 ;; There's no way we can use it today, since optimize mode switching
9863 ;; doesn't enable us to know from which mode we're switching to the
9864 ;; mode it requests, to tell whether we can use a relative mode switch
9865 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9867 (define_insn "toggle_pr"
9868 [(set (reg:PSI FPSCR_REG)
9869 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9870 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9872 [(set_attr "type" "fp")])
9874 (define_expand "addsf3"
9875 [(set (match_operand:SF 0 "arith_reg_operand" "")
9876 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9877 (match_operand:SF 2 "arith_reg_operand" "")))]
9878 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9883 expand_sf_binop (&gen_addsf3_i, operands);
9888 (define_insn "*addsf3_media"
9889 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9890 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9891 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9892 "TARGET_SHMEDIA_FPU"
9894 [(set_attr "type" "fparith_media")])
9896 (define_insn_and_split "unary_sf_op"
9897 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9902 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9903 (match_operator:SF 2 "unary_float_operator"
9904 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9905 (parallel [(match_operand 4
9906 "const_int_operand" "n")]))]))
9907 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9908 "TARGET_SHMEDIA_FPU"
9910 "TARGET_SHMEDIA_FPU && reload_completed"
9911 [(set (match_dup 5) (match_dup 6))]
9914 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9915 rtx op1 = gen_rtx_REG (SFmode,
9916 (true_regnum (operands[1])
9917 + (INTVAL (operands[4]) ^ endian)));
9919 operands[7] = gen_rtx_REG (SFmode,
9920 (true_regnum (operands[0])
9921 + (INTVAL (operands[3]) ^ endian)));
9922 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9924 [(set_attr "type" "fparith_media")])
9926 (define_insn_and_split "binary_sf_op"
9927 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9932 (parallel [(match_operand 7 "const_int_operand" "n")]))
9933 (match_operator:SF 3 "binary_float_operator"
9934 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9935 (parallel [(match_operand 5
9936 "const_int_operand" "n")]))
9937 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9938 (parallel [(match_operand 6
9939 "const_int_operand" "n")]))]))
9940 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9941 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9943 "&& reload_completed"
9944 [(set (match_dup 8) (match_dup 9))]
9947 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9948 rtx op1 = gen_rtx_REG (SFmode,
9949 (true_regnum (operands[1])
9950 + (INTVAL (operands[5]) ^ endian)));
9951 rtx op2 = gen_rtx_REG (SFmode,
9952 (true_regnum (operands[2])
9953 + (INTVAL (operands[6]) ^ endian)));
9955 operands[8] = gen_rtx_REG (SFmode,
9956 (true_regnum (operands[0])
9957 + (INTVAL (operands[4]) ^ endian)));
9958 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9960 [(set_attr "type" "fparith_media")])
9962 (define_insn "addsf3_i"
9963 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9964 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9965 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9966 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9969 [(set_attr "type" "fp")
9970 (set_attr "fp_mode" "single")])
9972 (define_expand "subsf3"
9973 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9974 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9975 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9976 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9981 expand_sf_binop (&gen_subsf3_i, operands);
9986 (define_insn "*subsf3_media"
9987 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9988 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9989 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9990 "TARGET_SHMEDIA_FPU"
9992 [(set_attr "type" "fparith_media")])
9994 (define_insn "subsf3_i"
9995 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9996 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9997 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9998 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10001 [(set_attr "type" "fp")
10002 (set_attr "fp_mode" "single")])
10004 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10005 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
10006 ;; mixed-precision SH4 targets. To allow it to be still generated for the
10007 ;; SH3E, we use a separate insn for SH3E mulsf3.
10009 (define_expand "mulsf3"
10010 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10011 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10012 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10013 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10016 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10017 expand_sf_binop (&gen_mulsf3_i4, operands);
10018 else if (TARGET_SH2E)
10019 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10020 if (! TARGET_SHMEDIA)
10024 (define_insn "*mulsf3_media"
10025 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10026 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10027 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10028 "TARGET_SHMEDIA_FPU"
10029 "fmul.s %1, %2, %0"
10030 [(set_attr "type" "fparith_media")])
10032 (define_insn "mulsf3_i4"
10033 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10034 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10035 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10036 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10039 [(set_attr "type" "fp")
10040 (set_attr "fp_mode" "single")])
10042 (define_insn "mulsf3_ie"
10043 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10044 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10045 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10046 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10048 [(set_attr "type" "fp")])
10050 (define_insn "mac_media"
10051 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10052 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10053 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10054 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10055 "TARGET_SHMEDIA_FPU"
10056 "fmac.s %1, %2, %0"
10057 [(set_attr "type" "fparith_media")])
10059 (define_insn "*macsf3"
10060 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10061 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10062 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10063 (match_operand:SF 3 "arith_reg_operand" "0")))
10064 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10065 "TARGET_SH2E && ! TARGET_SH4"
10067 [(set_attr "type" "fp")
10068 (set_attr "fp_mode" "single")])
10070 (define_expand "divsf3"
10071 [(set (match_operand:SF 0 "arith_reg_operand" "")
10072 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10073 (match_operand:SF 2 "arith_reg_operand" "")))]
10074 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10079 expand_sf_binop (&gen_divsf3_i, operands);
10084 (define_insn "*divsf3_media"
10085 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10086 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10087 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10088 "TARGET_SHMEDIA_FPU"
10089 "fdiv.s %1, %2, %0"
10090 [(set_attr "type" "fdiv_media")])
10092 (define_insn "divsf3_i"
10093 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10094 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10095 (match_operand:SF 2 "arith_reg_operand" "f")))
10096 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10099 [(set_attr "type" "fdiv")
10100 (set_attr "fp_mode" "single")])
10102 (define_insn "floatdisf2"
10103 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10104 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10105 "TARGET_SHMEDIA_FPU"
10107 [(set_attr "type" "fpconv_media")])
10109 (define_expand "floatsisf2"
10110 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10111 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10112 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10115 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10117 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10122 (define_insn "*floatsisf2_media"
10123 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10124 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10125 "TARGET_SHMEDIA_FPU"
10127 [(set_attr "type" "fpconv_media")])
10129 (define_insn "floatsisf2_i4"
10130 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10131 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10132 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10133 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10135 [(set_attr "type" "fp")
10136 (set_attr "fp_mode" "single")])
10138 (define_insn "*floatsisf2_ie"
10139 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10140 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10141 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10143 [(set_attr "type" "fp")])
10145 (define_insn "fix_truncsfdi2"
10146 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10147 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10148 "TARGET_SHMEDIA_FPU"
10150 [(set_attr "type" "fpconv_media")])
10152 (define_expand "fix_truncsfsi2"
10153 [(set (match_operand:SI 0 "fpul_operand" "=y")
10154 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10155 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10158 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10160 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10165 (define_insn "*fix_truncsfsi2_media"
10166 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10167 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10168 "TARGET_SHMEDIA_FPU"
10170 [(set_attr "type" "fpconv_media")])
10172 (define_insn "fix_truncsfsi2_i4"
10173 [(set (match_operand:SI 0 "fpul_operand" "=y")
10174 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10175 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10176 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10178 [(set_attr "type" "ftrc_s")
10179 (set_attr "fp_mode" "single")])
10181 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10182 ;; fix_truncsfsi2_i4.
10183 ;; (define_insn "fix_truncsfsi2_i4_2"
10184 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10185 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10186 ;; (use (reg:PSI FPSCR_REG))
10187 ;; (clobber (reg:SI FPUL_REG))]
10190 ;; [(set_attr "length" "4")
10191 ;; (set_attr "fp_mode" "single")])
10194 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10195 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10196 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10197 ;; (clobber (reg:SI FPUL_REG))]
10199 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10200 ;; (use (match_dup 2))])
10201 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10203 (define_insn "*fixsfsi"
10204 [(set (match_operand:SI 0 "fpul_operand" "=y")
10205 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10206 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10208 [(set_attr "type" "fp")])
10210 (define_insn "cmpgtsf_t"
10211 [(set (reg:SI T_REG)
10212 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10213 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10214 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10216 [(set_attr "type" "fp")
10217 (set_attr "fp_mode" "single")])
10219 (define_insn "cmpeqsf_t"
10220 [(set (reg:SI T_REG)
10221 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10222 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10223 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10225 [(set_attr "type" "fp")
10226 (set_attr "fp_mode" "single")])
10228 (define_insn "ieee_ccmpeqsf_t"
10229 [(set (reg:SI T_REG)
10230 (ior:SI (reg:SI T_REG)
10231 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10232 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10233 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10234 "* return output_ieee_ccmpeq (insn, operands);"
10235 [(set_attr "length" "4")])
10238 (define_insn "cmpgtsf_t_i4"
10239 [(set (reg:SI T_REG)
10240 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10241 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10242 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10243 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10245 [(set_attr "type" "fp")
10246 (set_attr "fp_mode" "single")])
10248 (define_insn "cmpeqsf_t_i4"
10249 [(set (reg:SI T_REG)
10250 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10251 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10252 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10253 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10255 [(set_attr "type" "fp")
10256 (set_attr "fp_mode" "single")])
10258 (define_insn "*ieee_ccmpeqsf_t_4"
10259 [(set (reg:SI T_REG)
10260 (ior:SI (reg:SI T_REG)
10261 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10262 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10263 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10264 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10265 "* return output_ieee_ccmpeq (insn, operands);"
10266 [(set_attr "length" "4")
10267 (set_attr "fp_mode" "single")])
10269 (define_insn "cmpeqsf_media"
10270 [(set (match_operand:DI 0 "register_operand" "=r")
10271 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10272 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10273 "TARGET_SHMEDIA_FPU"
10274 "fcmpeq.s %1, %2, %0"
10275 [(set_attr "type" "fcmp_media")])
10277 (define_insn "cmpsieqsf_media"
10278 [(set (match_operand:SI 0 "register_operand" "=r")
10279 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10280 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10281 "TARGET_SHMEDIA_FPU"
10282 "fcmpeq.s %1, %2, %0"
10283 [(set_attr "type" "fcmp_media")])
10285 (define_insn "cmpgtsf_media"
10286 [(set (match_operand:DI 0 "register_operand" "=r")
10287 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10288 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10289 "TARGET_SHMEDIA_FPU"
10290 "fcmpgt.s %1, %2, %0"
10291 [(set_attr "type" "fcmp_media")])
10293 (define_insn "cmpgesf_media"
10294 [(set (match_operand:DI 0 "register_operand" "=r")
10295 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10296 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10297 "TARGET_SHMEDIA_FPU"
10298 "fcmpge.s %1, %2, %0"
10299 [(set_attr "type" "fcmp_media")])
10301 (define_insn "cmpunsf_media"
10302 [(set (match_operand:DI 0 "register_operand" "=r")
10303 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10304 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10305 "TARGET_SHMEDIA_FPU"
10306 "fcmpun.s %1, %2, %0"
10307 [(set_attr "type" "fcmp_media")])
10309 (define_expand "cmpsf"
10310 [(set (reg:SI T_REG)
10311 (compare (match_operand:SF 0 "arith_operand" "")
10312 (match_operand:SF 1 "arith_operand" "")))]
10313 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10316 sh_compare_op0 = operands[0];
10317 sh_compare_op1 = operands[1];
10321 (define_expand "negsf2"
10322 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10323 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10324 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10329 expand_sf_unop (&gen_negsf2_i, operands);
10334 (define_insn "*negsf2_media"
10335 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10336 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10337 "TARGET_SHMEDIA_FPU"
10339 [(set_attr "type" "fmove_media")])
10341 (define_insn "negsf2_i"
10342 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10343 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10344 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10347 [(set_attr "type" "fmove")
10348 (set_attr "fp_mode" "single")])
10350 (define_expand "sqrtsf2"
10351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10352 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10353 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10358 expand_sf_unop (&gen_sqrtsf2_i, operands);
10363 (define_insn "*sqrtsf2_media"
10364 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10365 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10366 "TARGET_SHMEDIA_FPU"
10368 [(set_attr "type" "fdiv_media")])
10370 (define_insn "sqrtsf2_i"
10371 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10372 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10373 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10376 [(set_attr "type" "fdiv")
10377 (set_attr "fp_mode" "single")])
10379 (define_insn "rsqrtsf2"
10380 [(set (match_operand:SF 0 "register_operand" "=f")
10381 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10382 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10383 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10384 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10385 && operands[1] == CONST1_RTX (SFmode)"
10387 [(set_attr "type" "fsrra")
10388 (set_attr "fp_mode" "single")])
10390 (define_insn "fsca"
10391 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10393 (unspec:SF [(mult:SF
10394 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10395 (match_operand:SF 2 "immediate_operand" "i"))
10397 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10399 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10400 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10401 && operands[2] == sh_fsca_int2sf ()"
10403 [(set_attr "type" "fsca")
10404 (set_attr "fp_mode" "single")])
10406 (define_expand "sinsf2"
10407 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10408 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10410 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10413 rtx scaled = gen_reg_rtx (SFmode);
10414 rtx truncated = gen_reg_rtx (SImode);
10415 rtx fsca = gen_reg_rtx (V2SFmode);
10416 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10418 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10419 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10420 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10421 get_fpscr_rtx ()));
10422 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10426 (define_expand "cossf2"
10427 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10428 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10430 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10433 rtx scaled = gen_reg_rtx (SFmode);
10434 rtx truncated = gen_reg_rtx (SImode);
10435 rtx fsca = gen_reg_rtx (V2SFmode);
10436 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10438 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10439 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10440 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10441 get_fpscr_rtx ()));
10442 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10446 (define_expand "sindf2"
10447 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10448 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10450 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10453 rtx scaled = gen_reg_rtx (DFmode);
10454 rtx truncated = gen_reg_rtx (SImode);
10455 rtx fsca = gen_reg_rtx (V2SFmode);
10456 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10457 rtx sfresult = gen_reg_rtx (SFmode);
10459 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10460 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10461 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10462 get_fpscr_rtx ()));
10463 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10464 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10468 (define_expand "cosdf2"
10469 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10470 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10472 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10475 rtx scaled = gen_reg_rtx (DFmode);
10476 rtx truncated = gen_reg_rtx (SImode);
10477 rtx fsca = gen_reg_rtx (V2SFmode);
10478 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10479 rtx sfresult = gen_reg_rtx (SFmode);
10481 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10482 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10483 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10484 get_fpscr_rtx ()));
10485 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10486 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10490 (define_expand "abssf2"
10491 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10492 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10493 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10498 expand_sf_unop (&gen_abssf2_i, operands);
10503 (define_insn "*abssf2_media"
10504 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10505 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10506 "TARGET_SHMEDIA_FPU"
10508 [(set_attr "type" "fmove_media")])
10510 (define_insn "abssf2_i"
10511 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10512 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10513 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10516 [(set_attr "type" "fmove")
10517 (set_attr "fp_mode" "single")])
10519 (define_expand "adddf3"
10520 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10521 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10522 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10523 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10526 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10528 expand_df_binop (&gen_adddf3_i, operands);
10533 (define_insn "*adddf3_media"
10534 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10535 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10536 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10537 "TARGET_SHMEDIA_FPU"
10538 "fadd.d %1, %2, %0"
10539 [(set_attr "type" "dfparith_media")])
10541 (define_insn "adddf3_i"
10542 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10543 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10544 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10545 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10546 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10548 [(set_attr "type" "dfp_arith")
10549 (set_attr "fp_mode" "double")])
10551 (define_expand "subdf3"
10552 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10553 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10554 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10555 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10558 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10560 expand_df_binop (&gen_subdf3_i, operands);
10565 (define_insn "*subdf3_media"
10566 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10567 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10568 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10569 "TARGET_SHMEDIA_FPU"
10570 "fsub.d %1, %2, %0"
10571 [(set_attr "type" "dfparith_media")])
10573 (define_insn "subdf3_i"
10574 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10575 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10576 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10577 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10578 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10580 [(set_attr "type" "dfp_arith")
10581 (set_attr "fp_mode" "double")])
10583 (define_expand "muldf3"
10584 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10585 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10586 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10587 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10590 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10592 expand_df_binop (&gen_muldf3_i, operands);
10597 (define_insn "*muldf3_media"
10598 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10599 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10600 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10601 "TARGET_SHMEDIA_FPU"
10602 "fmul.d %1, %2, %0"
10603 [(set_attr "type" "dfmul_media")])
10605 (define_insn "muldf3_i"
10606 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10607 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10608 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10609 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10610 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10612 [(set_attr "type" "dfp_arith")
10613 (set_attr "fp_mode" "double")])
10615 (define_expand "divdf3"
10616 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10617 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10618 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10619 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10622 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10624 expand_df_binop (&gen_divdf3_i, operands);
10629 (define_insn "*divdf3_media"
10630 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10631 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10632 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10633 "TARGET_SHMEDIA_FPU"
10634 "fdiv.d %1, %2, %0"
10635 [(set_attr "type" "dfdiv_media")])
10637 (define_insn "divdf3_i"
10638 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10639 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10640 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10641 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10642 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10644 [(set_attr "type" "dfdiv")
10645 (set_attr "fp_mode" "double")])
10647 (define_insn "floatdidf2"
10648 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10649 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10650 "TARGET_SHMEDIA_FPU"
10652 [(set_attr "type" "dfpconv_media")])
10654 (define_expand "floatsidf2"
10655 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10656 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10657 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10660 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10662 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10663 get_fpscr_rtx ()));
10668 (define_insn "*floatsidf2_media"
10669 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10670 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10671 "TARGET_SHMEDIA_FPU"
10673 [(set_attr "type" "dfpconv_media")])
10675 (define_insn "floatsidf2_i"
10676 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10677 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10678 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10679 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10681 [(set_attr "type" "dfp_conv")
10682 (set_attr "fp_mode" "double")])
10684 (define_insn "fix_truncdfdi2"
10685 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10686 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10687 "TARGET_SHMEDIA_FPU"
10689 [(set_attr "type" "dfpconv_media")])
10691 (define_expand "fix_truncdfsi2"
10692 [(set (match_operand:SI 0 "fpul_operand" "")
10693 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10694 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10697 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10699 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10700 get_fpscr_rtx ()));
10705 (define_insn "*fix_truncdfsi2_media"
10706 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10707 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10708 "TARGET_SHMEDIA_FPU"
10710 [(set_attr "type" "dfpconv_media")])
10712 (define_insn "fix_truncdfsi2_i"
10713 [(set (match_operand:SI 0 "fpul_operand" "=y")
10714 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10715 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10716 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10718 [(set_attr "type" "dfp_conv")
10719 (set_attr "dfp_comp" "no")
10720 (set_attr "fp_mode" "double")])
10722 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10723 ;; fix_truncdfsi2_i.
10724 ;; (define_insn "fix_truncdfsi2_i4"
10725 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10726 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10727 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10728 ;; (clobber (reg:SI FPUL_REG))]
10731 ;; [(set_attr "length" "4")
10732 ;; (set_attr "fp_mode" "double")])
10735 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10736 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10737 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10738 ;; (clobber (reg:SI FPUL_REG))]
10740 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10741 ;; (use (match_dup 2))])
10742 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10744 (define_insn "cmpgtdf_t"
10745 [(set (reg:SI T_REG)
10746 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10747 (match_operand:DF 1 "arith_reg_operand" "f")))
10748 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10749 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10751 [(set_attr "type" "dfp_cmp")
10752 (set_attr "fp_mode" "double")])
10754 (define_insn "cmpeqdf_t"
10755 [(set (reg:SI T_REG)
10756 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10757 (match_operand:DF 1 "arith_reg_operand" "f")))
10758 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10759 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10761 [(set_attr "type" "dfp_cmp")
10762 (set_attr "fp_mode" "double")])
10764 (define_insn "*ieee_ccmpeqdf_t"
10765 [(set (reg:SI T_REG)
10766 (ior:SI (reg:SI T_REG)
10767 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10768 (match_operand:DF 1 "arith_reg_operand" "f"))))
10769 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10770 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10771 "* return output_ieee_ccmpeq (insn, operands);"
10772 [(set_attr "length" "4")
10773 (set_attr "fp_mode" "double")])
10775 (define_insn "cmpeqdf_media"
10776 [(set (match_operand:DI 0 "register_operand" "=r")
10777 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10778 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10779 "TARGET_SHMEDIA_FPU"
10780 "fcmpeq.d %1,%2,%0"
10781 [(set_attr "type" "fcmp_media")])
10783 (define_insn "cmpsieqdf_media"
10784 [(set (match_operand:SI 0 "register_operand" "=r")
10785 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10786 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10787 "TARGET_SHMEDIA_FPU"
10788 "fcmpeq.d %1,%2,%0"
10789 [(set_attr "type" "fcmp_media")])
10791 (define_insn "cmpgtdf_media"
10792 [(set (match_operand:DI 0 "register_operand" "=r")
10793 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10794 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10795 "TARGET_SHMEDIA_FPU"
10796 "fcmpgt.d %1,%2,%0"
10797 [(set_attr "type" "fcmp_media")])
10799 (define_insn "cmpgedf_media"
10800 [(set (match_operand:DI 0 "register_operand" "=r")
10801 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10802 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10803 "TARGET_SHMEDIA_FPU"
10804 "fcmpge.d %1,%2,%0"
10805 [(set_attr "type" "fcmp_media")])
10807 (define_insn "cmpundf_media"
10808 [(set (match_operand:DI 0 "register_operand" "=r")
10809 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10810 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10811 "TARGET_SHMEDIA_FPU"
10812 "fcmpun.d %1,%2,%0"
10813 [(set_attr "type" "fcmp_media")])
10815 (define_expand "cmpdf"
10816 [(set (reg:SI T_REG)
10817 (compare (match_operand:DF 0 "arith_operand" "")
10818 (match_operand:DF 1 "arith_operand" "")))]
10819 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10822 sh_compare_op0 = operands[0];
10823 sh_compare_op1 = operands[1];
10827 (define_expand "negdf2"
10828 [(set (match_operand:DF 0 "arith_reg_operand" "")
10829 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10830 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10833 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10835 expand_df_unop (&gen_negdf2_i, operands);
10840 (define_insn "*negdf2_media"
10841 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10843 "TARGET_SHMEDIA_FPU"
10845 [(set_attr "type" "fmove_media")])
10847 (define_insn "negdf2_i"
10848 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10849 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10850 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10851 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10853 [(set_attr "type" "fmove")
10854 (set_attr "fp_mode" "double")])
10856 (define_expand "sqrtdf2"
10857 [(set (match_operand:DF 0 "arith_reg_operand" "")
10858 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10859 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10862 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10864 expand_df_unop (&gen_sqrtdf2_i, operands);
10869 (define_insn "*sqrtdf2_media"
10870 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10871 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872 "TARGET_SHMEDIA_FPU"
10874 [(set_attr "type" "dfdiv_media")])
10876 (define_insn "sqrtdf2_i"
10877 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10878 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10879 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10882 [(set_attr "type" "dfdiv")
10883 (set_attr "fp_mode" "double")])
10885 (define_expand "absdf2"
10886 [(set (match_operand:DF 0 "arith_reg_operand" "")
10887 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10888 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10891 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10893 expand_df_unop (&gen_absdf2_i, operands);
10898 (define_insn "*absdf2_media"
10899 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10900 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10901 "TARGET_SHMEDIA_FPU"
10903 [(set_attr "type" "fmove_media")])
10905 (define_insn "absdf2_i"
10906 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10907 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10908 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10909 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10911 [(set_attr "type" "fmove")
10912 (set_attr "fp_mode" "double")])
10914 (define_expand "extendsfdf2"
10915 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10916 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10917 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10920 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10922 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10923 get_fpscr_rtx ()));
10928 (define_insn "*extendsfdf2_media"
10929 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10930 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10931 "TARGET_SHMEDIA_FPU"
10933 [(set_attr "type" "dfpconv_media")])
10935 (define_insn "extendsfdf2_i4"
10936 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10937 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10938 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10939 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10941 [(set_attr "type" "fp")
10942 (set_attr "fp_mode" "double")])
10944 (define_expand "truncdfsf2"
10945 [(set (match_operand:SF 0 "fpul_operand" "")
10946 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10947 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10950 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10952 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10953 get_fpscr_rtx ()));
10958 (define_insn "*truncdfsf2_media"
10959 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10960 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10961 "TARGET_SHMEDIA_FPU"
10963 [(set_attr "type" "dfpconv_media")])
10965 (define_insn "truncdfsf2_i4"
10966 [(set (match_operand:SF 0 "fpul_operand" "=y")
10967 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10968 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10969 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10971 [(set_attr "type" "fp")
10972 (set_attr "fp_mode" "double")])
10974 ;; Bit field extract patterns. These give better code for packed bitfields,
10975 ;; because they allow auto-increment addresses to be generated.
10977 (define_expand "insv"
10978 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10979 (match_operand:SI 1 "immediate_operand" "")
10980 (match_operand:SI 2 "immediate_operand" ""))
10981 (match_operand:SI 3 "general_operand" ""))]
10982 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10985 rtx addr_target, orig_address, shift_reg, qi_val;
10986 HOST_WIDE_INT bitsize, size, v = 0;
10987 rtx x = operands[3];
10989 /* ??? expmed doesn't care for non-register predicates. */
10990 if (! memory_operand (operands[0], VOIDmode)
10991 || ! immediate_operand (operands[1], VOIDmode)
10992 || ! immediate_operand (operands[2], VOIDmode)
10993 || ! general_operand (x, VOIDmode))
10995 /* If this isn't a 16 / 24 / 32 bit field, or if
10996 it doesn't start on a byte boundary, then fail. */
10997 bitsize = INTVAL (operands[1]);
10998 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10999 || (INTVAL (operands[2]) % 8) != 0)
11002 size = bitsize / 8;
11003 orig_address = XEXP (operands[0], 0);
11004 shift_reg = gen_reg_rtx (SImode);
11005 if (GET_CODE (x) == CONST_INT)
11008 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11012 emit_insn (gen_movsi (shift_reg, operands[3]));
11013 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11015 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11017 operands[0] = replace_equiv_address (operands[0], addr_target);
11018 emit_insn (gen_movqi (operands[0], qi_val));
11022 if (GET_CODE (x) == CONST_INT)
11024 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11027 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11028 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11030 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11031 emit_insn (gen_movqi (operands[0], qi_val));
11037 (define_insn "movua"
11038 [(set (match_operand:SI 0 "register_operand" "=z")
11039 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11040 (const_int 32) (const_int 0)))]
11043 [(set_attr "type" "movua")])
11045 ;; We shouldn't need this, but cse replaces increments with references
11046 ;; to other regs before flow has a chance to create post_inc
11047 ;; addressing modes, and only postreload's cse_move2add brings the
11048 ;; increments back to a usable form.
11050 [(set (match_operand:SI 0 "register_operand" "")
11051 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11052 (const_int 32) (const_int 0)))
11053 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11054 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11055 [(set (match_operand:SI 0 "register_operand" "")
11056 (sign_extract:SI (mem:SI (post_inc:SI
11057 (match_operand:SI 1 "register_operand" "")))
11058 (const_int 32) (const_int 0)))]
11061 (define_expand "extv"
11062 [(set (match_operand:SI 0 "register_operand" "")
11063 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11064 (match_operand 2 "const_int_operand" "")
11065 (match_operand 3 "const_int_operand" "")))]
11068 if (TARGET_SH4A_ARCH
11069 && INTVAL (operands[2]) == 32
11070 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11071 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11073 emit_insn (gen_movua (operands[0],
11074 adjust_address (operands[1], SImode, 0)));
11081 (define_expand "extzv"
11082 [(set (match_operand:SI 0 "register_operand" "")
11083 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11084 (match_operand 2 "const_int_operand" "")
11085 (match_operand 3 "const_int_operand" "")))]
11088 if (TARGET_SH4A_ARCH
11089 && INTVAL (operands[2]) == 32
11090 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11091 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11093 emit_insn (gen_movua (operands[0],
11094 adjust_address (operands[1], SImode, 0)));
11102 ;; -------------------------------------------------------------------------
11104 ;; -------------------------------------------------------------------------
11106 ;; This matches cases where a stack pointer increment at the start of the
11107 ;; epilogue combines with a stack slot read loading the return value.
11110 [(set (match_operand:SI 0 "arith_reg_operand" "")
11111 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11112 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11113 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11116 ;; See the comment on the dt combiner pattern above.
11119 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11120 (plus:SI (match_dup 0)
11122 (set (reg:SI T_REG)
11123 (eq:SI (match_dup 0)
11128 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11129 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11130 ;; reload when the constant is too large for a reg+offset address.
11132 ;; ??? We would get much better code if this was done in reload. This would
11133 ;; require modifying find_reloads_address to recognize that if the constant
11134 ;; is out-of-range for an immediate add, then we get better code by reloading
11135 ;; the constant into a register than by reloading the sum into a register,
11136 ;; since the former is one instruction shorter if the address does not need
11137 ;; to be offsettable. Unfortunately this does not work, because there is
11138 ;; only one register, r0, that can be used as an index register. This register
11139 ;; is also the function return value register. So, if we try to force reload
11140 ;; to use double-reg addresses, then we end up with some instructions that
11141 ;; need to use r0 twice. The only way to fix this is to change the calling
11142 ;; convention so that r0 is not used to return values.
11145 [(set (match_operand:SI 0 "register_operand" "=r")
11146 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11147 (set (mem:SI (match_dup 0))
11148 (match_operand:SI 2 "general_movsrc_operand" ""))]
11149 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11150 "mov.l %2,@(%0,%1)")
11153 [(set (match_operand:SI 0 "register_operand" "=r")
11154 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11155 (set (match_operand:SI 2 "general_movdst_operand" "")
11156 (mem:SI (match_dup 0)))]
11157 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11158 "mov.l @(%0,%1),%2")
11161 [(set (match_operand:SI 0 "register_operand" "=r")
11162 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11163 (set (mem:HI (match_dup 0))
11164 (match_operand:HI 2 "general_movsrc_operand" ""))]
11165 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11166 "mov.w %2,@(%0,%1)")
11169 [(set (match_operand:SI 0 "register_operand" "=r")
11170 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11171 (set (match_operand:HI 2 "general_movdst_operand" "")
11172 (mem:HI (match_dup 0)))]
11173 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11174 "mov.w @(%0,%1),%2")
11177 [(set (match_operand:SI 0 "register_operand" "=r")
11178 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11179 (set (mem:QI (match_dup 0))
11180 (match_operand:QI 2 "general_movsrc_operand" ""))]
11181 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11182 "mov.b %2,@(%0,%1)")
11185 [(set (match_operand:SI 0 "register_operand" "=r")
11186 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11187 (set (match_operand:QI 2 "general_movdst_operand" "")
11188 (mem:QI (match_dup 0)))]
11189 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11190 "mov.b @(%0,%1),%2")
11193 [(set (match_operand:SI 0 "register_operand" "=r")
11194 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11195 (set (mem:SF (match_dup 0))
11196 (match_operand:SF 2 "general_movsrc_operand" ""))]
11197 "TARGET_SH1 && REGNO (operands[0]) == 0
11198 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11199 || (GET_CODE (operands[2]) == SUBREG
11200 && REGNO (SUBREG_REG (operands[2])) < 16))
11201 && reg_unused_after (operands[0], insn)"
11202 "mov.l %2,@(%0,%1)")
11205 [(set (match_operand:SI 0 "register_operand" "=r")
11206 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11207 (set (match_operand:SF 2 "general_movdst_operand" "")
11209 (mem:SF (match_dup 0)))]
11210 "TARGET_SH1 && REGNO (operands[0]) == 0
11211 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11212 || (GET_CODE (operands[2]) == SUBREG
11213 && REGNO (SUBREG_REG (operands[2])) < 16))
11214 && reg_unused_after (operands[0], insn)"
11215 "mov.l @(%0,%1),%2")
11218 [(set (match_operand:SI 0 "register_operand" "=r")
11219 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11220 (set (mem:SF (match_dup 0))
11221 (match_operand:SF 2 "general_movsrc_operand" ""))]
11222 "TARGET_SH2E && REGNO (operands[0]) == 0
11223 && ((GET_CODE (operands[2]) == REG
11224 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11225 || (GET_CODE (operands[2]) == SUBREG
11226 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11227 && reg_unused_after (operands[0], insn)"
11228 "fmov{.s|} %2,@(%0,%1)")
11231 [(set (match_operand:SI 0 "register_operand" "=r")
11232 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11233 (set (match_operand:SF 2 "general_movdst_operand" "")
11235 (mem:SF (match_dup 0)))]
11236 "TARGET_SH2E && REGNO (operands[0]) == 0
11237 && ((GET_CODE (operands[2]) == REG
11238 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11239 || (GET_CODE (operands[2]) == SUBREG
11240 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11241 && reg_unused_after (operands[0], insn)"
11242 "fmov{.s|} @(%0,%1),%2")
11244 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11245 (define_insn "sp_switch_1"
11252 xoperands[0] = sp_switch;
11253 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
11254 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
11255 return \"mov r0,r15\";
11257 [(set_attr "length" "10")])
11259 ;; Switch back to the original stack for interrupt functions with the
11260 ;; sp_switch attribute. */
11261 (define_insn "sp_switch_2"
11264 "mov.l @r15+,r15\;mov.l @r15+,r0"
11265 [(set_attr "length" "4")])
11267 ;; Integer vector moves
11269 (define_expand "movv8qi"
11270 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11271 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11273 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11275 (define_insn "movv8qi_i"
11276 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11277 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11279 && (register_operand (operands[0], V8QImode)
11280 || sh_register_operand (operands[1], V8QImode))"
11287 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11288 (set_attr "length" "4,4,16,4,4")])
11291 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11292 (subreg:V8QI (const_int 0) 0))]
11294 [(set (match_dup 0)
11295 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11296 (const_int 0) (const_int 0) (const_int 0)
11297 (const_int 0) (const_int 0)]))])
11300 [(set (match_operand 0 "arith_reg_dest" "")
11301 (match_operand 1 "sh_rep_vec" ""))]
11302 "TARGET_SHMEDIA && reload_completed
11303 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11304 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11305 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11306 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11307 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11308 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11309 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11310 [(set (match_dup 0) (match_dup 1))
11314 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11315 rtx elt1 = XVECEXP (operands[1], 0, 1);
11318 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11322 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11323 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11325 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11326 operands[1] = XVECEXP (operands[1], 0, 0);
11329 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11331 = GEN_INT (TARGET_LITTLE_ENDIAN
11332 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11333 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11336 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11338 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11344 [(set (match_operand 0 "arith_reg_dest" "")
11345 (match_operand 1 "sh_const_vec" ""))]
11346 "TARGET_SHMEDIA && reload_completed
11347 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11348 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11349 [(set (match_dup 0) (match_dup 1))]
11352 rtx v = operands[1];
11353 enum machine_mode new_mode
11354 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11356 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11358 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11361 (define_expand "movv2hi"
11362 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11363 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11365 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11367 (define_insn "movv2hi_i"
11368 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11369 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11371 && (register_operand (operands[0], V2HImode)
11372 || sh_register_operand (operands[1], V2HImode))"
11379 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11380 (set_attr "length" "4,4,16,4,4")
11381 (set (attr "highpart")
11382 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11383 (const_string "user")]
11384 (const_string "ignore")))])
11386 (define_expand "movv4hi"
11387 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11388 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11390 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11392 (define_insn "movv4hi_i"
11393 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11394 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11396 && (register_operand (operands[0], V4HImode)
11397 || sh_register_operand (operands[1], V4HImode))"
11404 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11405 (set_attr "length" "4,4,16,4,4")
11406 (set_attr "highpart" "depend")])
11408 (define_expand "movv2si"
11409 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11410 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11412 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11414 (define_insn "movv2si_i"
11415 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11416 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11418 && (register_operand (operands[0], V2SImode)
11419 || sh_register_operand (operands[1], V2SImode))"
11426 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11427 (set_attr "length" "4,4,16,4,4")
11428 (set_attr "highpart" "depend")])
11430 ;; Multimedia Intrinsics
11432 (define_insn "absv2si2"
11433 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11434 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11437 [(set_attr "type" "mcmp_media")
11438 (set_attr "highpart" "depend")])
11440 (define_insn "absv4hi2"
11441 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11442 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11445 [(set_attr "type" "mcmp_media")
11446 (set_attr "highpart" "depend")])
11448 (define_insn "addv2si3"
11449 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11450 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11451 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11453 "madd.l %1, %2, %0"
11454 [(set_attr "type" "arith_media")
11455 (set_attr "highpart" "depend")])
11457 (define_insn "addv4hi3"
11458 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11459 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11460 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11462 "madd.w %1, %2, %0"
11463 [(set_attr "type" "arith_media")
11464 (set_attr "highpart" "depend")])
11466 (define_insn_and_split "addv2hi3"
11467 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11468 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11469 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11476 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11477 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11478 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11479 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11480 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11482 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11483 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11486 [(set_attr "highpart" "must_split")])
11488 (define_insn "ssaddv2si3"
11489 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11490 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11491 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11493 "madds.l %1, %2, %0"
11494 [(set_attr "type" "mcmp_media")
11495 (set_attr "highpart" "depend")])
11497 (define_insn "usaddv8qi3"
11498 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11499 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11500 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11502 "madds.ub %1, %2, %0"
11503 [(set_attr "type" "mcmp_media")
11504 (set_attr "highpart" "depend")])
11506 (define_insn "ssaddv4hi3"
11507 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11508 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11509 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11511 "madds.w %1, %2, %0"
11512 [(set_attr "type" "mcmp_media")
11513 (set_attr "highpart" "depend")])
11515 (define_insn "negcmpeqv8qi"
11516 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11517 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11518 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11520 "mcmpeq.b %N1, %N2, %0"
11521 [(set_attr "type" "mcmp_media")
11522 (set_attr "highpart" "depend")])
11524 (define_insn "negcmpeqv2si"
11525 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11526 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11527 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11529 "mcmpeq.l %N1, %N2, %0"
11530 [(set_attr "type" "mcmp_media")
11531 (set_attr "highpart" "depend")])
11533 (define_insn "negcmpeqv4hi"
11534 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11535 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11536 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11538 "mcmpeq.w %N1, %N2, %0"
11539 [(set_attr "type" "mcmp_media")
11540 (set_attr "highpart" "depend")])
11542 (define_insn "negcmpgtuv8qi"
11543 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11544 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11545 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11547 "mcmpgt.ub %N1, %N2, %0"
11548 [(set_attr "type" "mcmp_media")
11549 (set_attr "highpart" "depend")])
11551 (define_insn "negcmpgtv2si"
11552 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11553 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11554 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11556 "mcmpgt.l %N1, %N2, %0"
11557 [(set_attr "type" "mcmp_media")
11558 (set_attr "highpart" "depend")])
11560 (define_insn "negcmpgtv4hi"
11561 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11562 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11563 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11565 "mcmpgt.w %N1, %N2, %0"
11566 [(set_attr "type" "mcmp_media")
11567 (set_attr "highpart" "depend")])
11569 (define_insn "mcmv"
11570 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11571 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11572 (match_operand:DI 2 "arith_reg_operand" "r"))
11573 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11574 (not:DI (match_dup 2)))))]
11577 [(set_attr "type" "arith_media")
11578 (set_attr "highpart" "depend")])
11580 (define_insn "mcnvs_lw"
11581 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11583 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11584 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11586 "mcnvs.lw %N1, %N2, %0"
11587 [(set_attr "type" "mcmp_media")])
11589 (define_insn "mcnvs_wb"
11590 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11592 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11593 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11595 "mcnvs.wb %N1, %N2, %0"
11596 [(set_attr "type" "mcmp_media")])
11598 (define_insn "mcnvs_wub"
11599 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11601 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11602 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11604 "mcnvs.wub %N1, %N2, %0"
11605 [(set_attr "type" "mcmp_media")])
11607 (define_insn "mextr_rl"
11608 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11609 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11610 (match_operand:HI 3 "mextr_bit_offset" "i"))
11611 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11612 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11613 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11616 static char templ[16];
11618 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11619 (int) INTVAL (operands[3]) >> 3);
11622 [(set_attr "type" "arith_media")])
11624 (define_insn "*mextr_lr"
11625 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11626 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11627 (match_operand:HI 3 "mextr_bit_offset" "i"))
11628 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11629 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11630 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11633 static char templ[16];
11635 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11636 (int) INTVAL (operands[4]) >> 3);
11639 [(set_attr "type" "arith_media")])
11641 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11642 ; vector then varies depending on endianness.
11643 (define_expand "mextr1"
11644 [(match_operand:DI 0 "arith_reg_dest" "")
11645 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11646 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11650 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11651 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11655 (define_expand "mextr2"
11656 [(match_operand:DI 0 "arith_reg_dest" "")
11657 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11658 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11662 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11663 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11667 (define_expand "mextr3"
11668 [(match_operand:DI 0 "arith_reg_dest" "")
11669 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11670 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11674 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11675 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11679 (define_expand "mextr4"
11680 [(match_operand:DI 0 "arith_reg_dest" "")
11681 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11682 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11686 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11687 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11691 (define_expand "mextr5"
11692 [(match_operand:DI 0 "arith_reg_dest" "")
11693 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11694 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11698 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11699 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11703 (define_expand "mextr6"
11704 [(match_operand:DI 0 "arith_reg_dest" "")
11705 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11706 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11710 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11711 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11715 (define_expand "mextr7"
11716 [(match_operand:DI 0 "arith_reg_dest" "")
11717 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11718 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11722 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11723 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11727 (define_expand "mmacfx_wl"
11728 [(match_operand:V2SI 0 "arith_reg_dest" "")
11729 (match_operand:V2HI 1 "extend_reg_operand" "")
11730 (match_operand:V2HI 2 "extend_reg_operand" "")
11731 (match_operand:V2SI 3 "arith_reg_operand" "")]
11735 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11736 operands[1], operands[2]));
11740 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11742 (define_insn "mmacfx_wl_i"
11743 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11745 (match_operand:V2SI 1 "arith_reg_operand" "0")
11750 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11751 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11754 "mmacfx.wl %2, %3, %0"
11755 [(set_attr "type" "mac_media")
11756 (set_attr "highpart" "depend")])
11758 (define_expand "mmacnfx_wl"
11759 [(match_operand:V2SI 0 "arith_reg_dest" "")
11760 (match_operand:V2HI 1 "extend_reg_operand" "")
11761 (match_operand:V2HI 2 "extend_reg_operand" "")
11762 (match_operand:V2SI 3 "arith_reg_operand" "")]
11766 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11767 operands[1], operands[2]));
11771 (define_insn "mmacnfx_wl_i"
11772 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11774 (match_operand:V2SI 1 "arith_reg_operand" "0")
11779 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11780 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11783 "mmacnfx.wl %2, %3, %0"
11784 [(set_attr "type" "mac_media")
11785 (set_attr "highpart" "depend")])
11787 (define_insn "mulv2si3"
11788 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11789 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11790 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11792 "mmul.l %1, %2, %0"
11793 [(set_attr "type" "d2mpy_media")
11794 (set_attr "highpart" "depend")])
11796 (define_insn "mulv4hi3"
11797 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11798 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11799 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11801 "mmul.w %1, %2, %0"
11802 [(set_attr "type" "dmpy_media")
11803 (set_attr "highpart" "depend")])
11805 (define_insn "mmulfx_l"
11806 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11810 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11811 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11814 "mmulfx.l %1, %2, %0"
11815 [(set_attr "type" "d2mpy_media")
11816 (set_attr "highpart" "depend")])
11818 (define_insn "mmulfx_w"
11819 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11823 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11824 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11827 "mmulfx.w %1, %2, %0"
11828 [(set_attr "type" "dmpy_media")
11829 (set_attr "highpart" "depend")])
11831 (define_insn "mmulfxrp_w"
11832 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11837 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11838 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11842 "mmulfxrp.w %1, %2, %0"
11843 [(set_attr "type" "dmpy_media")
11844 (set_attr "highpart" "depend")])
11847 (define_expand "mmulhi_wl"
11848 [(match_operand:V2SI 0 "arith_reg_dest" "")
11849 (match_operand:V4HI 1 "arith_reg_operand" "")
11850 (match_operand:V4HI 2 "arith_reg_operand" "")]
11854 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11855 (operands[0], operands[1], operands[2]));
11859 (define_expand "mmullo_wl"
11860 [(match_operand:V2SI 0 "arith_reg_dest" "")
11861 (match_operand:V4HI 1 "arith_reg_operand" "")
11862 (match_operand:V4HI 2 "arith_reg_operand" "")]
11866 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11867 (operands[0], operands[1], operands[2]));
11871 (define_insn "mmul23_wl"
11872 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11875 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11876 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11877 (parallel [(const_int 2) (const_int 3)])))]
11879 "* return (TARGET_LITTLE_ENDIAN
11880 ? \"mmulhi.wl %1, %2, %0\"
11881 : \"mmullo.wl %1, %2, %0\");"
11882 [(set_attr "type" "dmpy_media")
11883 (set (attr "highpart")
11884 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11885 (const_string "user")))])
11887 (define_insn "mmul01_wl"
11888 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11891 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11892 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11893 (parallel [(const_int 0) (const_int 1)])))]
11895 "* return (TARGET_LITTLE_ENDIAN
11896 ? \"mmullo.wl %1, %2, %0\"
11897 : \"mmulhi.wl %1, %2, %0\");"
11898 [(set_attr "type" "dmpy_media")
11899 (set (attr "highpart")
11900 (cond [(eq_attr "endian" "little") (const_string "ignore")]
11901 (const_string "user")))])
11904 (define_expand "mmulsum_wq"
11905 [(match_operand:DI 0 "arith_reg_dest" "")
11906 (match_operand:V4HI 1 "arith_reg_operand" "")
11907 (match_operand:V4HI 2 "arith_reg_operand" "")
11908 (match_operand:DI 3 "arith_reg_operand" "")]
11912 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11913 operands[1], operands[2]));
11917 (define_insn "mmulsum_wq_i"
11918 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11919 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11924 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11925 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11926 (parallel [(const_int 0)]))
11927 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11928 (sign_extend:V4DI (match_dup 3)))
11929 (parallel [(const_int 1)])))
11931 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11932 (sign_extend:V4DI (match_dup 3)))
11933 (parallel [(const_int 2)]))
11934 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11935 (sign_extend:V4DI (match_dup 3)))
11936 (parallel [(const_int 3)]))))))]
11938 "mmulsum.wq %2, %3, %0"
11939 [(set_attr "type" "mac_media")])
11941 (define_expand "mperm_w"
11942 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11943 (match_operand:V4HI 1 "arith_reg_operand" "r")
11944 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11948 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11949 (operands[0], operands[1], operands[2]));
11953 ; This use of vec_select isn't exactly correct according to rtl.texi
11954 ; (because not constant), but it seems a straightforward extension.
11955 (define_insn "mperm_w_little"
11956 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11958 (match_operand:V4HI 1 "arith_reg_operand" "r")
11960 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11961 (const_int 2) (const_int 0))
11962 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11963 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11964 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11965 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11966 "mperm.w %1, %N2, %0"
11967 [(set_attr "type" "arith_media")])
11969 (define_insn "mperm_w_big"
11970 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11972 (match_operand:V4HI 1 "arith_reg_operand" "r")
11974 [(zero_extract:QI (not:QI (match_operand:QI 2
11975 "extend_reg_or_0_operand" "rZ"))
11976 (const_int 2) (const_int 0))
11977 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11978 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11979 (zero_extract:QI (not:QI (match_dup 2))
11980 (const_int 2) (const_int 6))])))]
11981 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11982 "mperm.w %1, %N2, %0"
11983 [(set_attr "type" "arith_media")])
11985 (define_insn "mperm_w0"
11986 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11987 (vec_duplicate:V4HI (truncate:HI (match_operand 1
11988 "trunc_hi_operand" "r"))))]
11990 "mperm.w %1, r63, %0"
11991 [(set_attr "type" "arith_media")
11992 (set_attr "highpart" "ignore")])
11994 (define_expand "msad_ubq"
11995 [(match_operand:DI 0 "arith_reg_dest" "")
11996 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
11997 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
11998 (match_operand:DI 3 "arith_reg_operand" "")]
12002 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12003 operands[1], operands[2]));
12007 (define_insn "msad_ubq_i"
12008 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12013 (match_operand:DI 1 "arith_reg_operand" "0")
12014 (abs:DI (vec_select:DI
12017 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12019 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12020 (parallel [(const_int 0)]))))
12021 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12022 (zero_extend:V8DI (match_dup 3)))
12023 (parallel [(const_int 1)]))))
12025 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12026 (zero_extend:V8DI (match_dup 3)))
12027 (parallel [(const_int 2)])))
12028 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12029 (zero_extend:V8DI (match_dup 3)))
12030 (parallel [(const_int 3)])))))
12033 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12034 (zero_extend:V8DI (match_dup 3)))
12035 (parallel [(const_int 4)])))
12036 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12037 (zero_extend:V8DI (match_dup 3)))
12038 (parallel [(const_int 5)]))))
12040 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12041 (zero_extend:V8DI (match_dup 3)))
12042 (parallel [(const_int 6)])))
12043 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12044 (zero_extend:V8DI (match_dup 3)))
12045 (parallel [(const_int 7)])))))))]
12047 "msad.ubq %N2, %N3, %0"
12048 [(set_attr "type" "mac_media")])
12050 (define_insn "mshalds_l"
12051 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12054 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12055 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12056 (const_int 31)))))]
12058 "mshalds.l %1, %2, %0"
12059 [(set_attr "type" "mcmp_media")
12060 (set_attr "highpart" "depend")])
12062 (define_insn "mshalds_w"
12063 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12066 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12067 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12068 (const_int 15)))))]
12070 "mshalds.w %1, %2, %0"
12071 [(set_attr "type" "mcmp_media")
12072 (set_attr "highpart" "depend")])
12074 (define_insn "ashrv2si3"
12075 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12076 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12077 (match_operand:DI 2 "arith_reg_operand" "r")))]
12079 "mshard.l %1, %2, %0"
12080 [(set_attr "type" "arith_media")
12081 (set_attr "highpart" "depend")])
12083 (define_insn "ashrv4hi3"
12084 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12085 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12086 (match_operand:DI 2 "arith_reg_operand" "r")))]
12088 "mshard.w %1, %2, %0"
12089 [(set_attr "type" "arith_media")
12090 (set_attr "highpart" "depend")])
12092 (define_insn "mshards_q"
12093 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12095 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12096 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12098 "mshards.q %1, %N2, %0"
12099 [(set_attr "type" "mcmp_media")])
12101 (define_expand "mshfhi_b"
12102 [(match_operand:V8QI 0 "arith_reg_dest" "")
12103 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12104 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12108 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12109 (operands[0], operands[1], operands[2]));
12113 (define_expand "mshflo_b"
12114 [(match_operand:V8QI 0 "arith_reg_dest" "")
12115 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12116 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12120 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12121 (operands[0], operands[1], operands[2]));
12125 (define_insn "mshf4_b"
12127 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12129 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12130 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12131 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12132 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12134 "* return (TARGET_LITTLE_ENDIAN
12135 ? \"mshfhi.b %N1, %N2, %0\"
12136 : \"mshflo.b %N1, %N2, %0\");"
12137 [(set_attr "type" "arith_media")
12138 (set (attr "highpart")
12139 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12140 (const_string "user")))])
12142 (define_insn "mshf0_b"
12144 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12146 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12147 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12148 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12149 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12151 "* return (TARGET_LITTLE_ENDIAN
12152 ? \"mshflo.b %N1, %N2, %0\"
12153 : \"mshfhi.b %N1, %N2, %0\");"
12154 [(set_attr "type" "arith_media")
12155 (set (attr "highpart")
12156 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12157 (const_string "user")))])
12159 (define_expand "mshfhi_l"
12160 [(match_operand:V2SI 0 "arith_reg_dest" "")
12161 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12162 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12166 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12167 (operands[0], operands[1], operands[2]));
12171 (define_expand "mshflo_l"
12172 [(match_operand:V2SI 0 "arith_reg_dest" "")
12173 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12174 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12178 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12179 (operands[0], operands[1], operands[2]));
12183 (define_insn "mshf4_l"
12184 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12186 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12187 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12188 (parallel [(const_int 1) (const_int 3)])))]
12190 "* return (TARGET_LITTLE_ENDIAN
12191 ? \"mshfhi.l %N1, %N2, %0\"
12192 : \"mshflo.l %N1, %N2, %0\");"
12193 [(set_attr "type" "arith_media")
12194 (set (attr "highpart")
12195 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12196 (const_string "user")))])
12198 (define_insn "mshf0_l"
12199 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12201 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12202 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12203 (parallel [(const_int 0) (const_int 2)])))]
12205 "* return (TARGET_LITTLE_ENDIAN
12206 ? \"mshflo.l %N1, %N2, %0\"
12207 : \"mshfhi.l %N1, %N2, %0\");"
12208 [(set_attr "type" "arith_media")
12209 (set (attr "highpart")
12210 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12211 (const_string "user")))])
12213 (define_expand "mshfhi_w"
12214 [(match_operand:V4HI 0 "arith_reg_dest" "")
12215 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12216 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12220 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12221 (operands[0], operands[1], operands[2]));
12225 (define_expand "mshflo_w"
12226 [(match_operand:V4HI 0 "arith_reg_dest" "")
12227 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12228 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12232 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12233 (operands[0], operands[1], operands[2]));
12237 (define_insn "mshf4_w"
12238 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12240 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12241 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12242 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12244 "* return (TARGET_LITTLE_ENDIAN
12245 ? \"mshfhi.w %N1, %N2, %0\"
12246 : \"mshflo.w %N1, %N2, %0\");"
12247 [(set_attr "type" "arith_media")
12248 (set (attr "highpart")
12249 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12250 (const_string "user")))])
12252 (define_insn "mshf0_w"
12253 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12255 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12256 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12257 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12259 "* return (TARGET_LITTLE_ENDIAN
12260 ? \"mshflo.w %N1, %N2, %0\"
12261 : \"mshfhi.w %N1, %N2, %0\");"
12262 [(set_attr "type" "arith_media")
12263 (set (attr "highpart")
12264 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12265 (const_string "user")))])
12267 (define_insn "mshflo_w_x"
12268 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12270 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12271 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12272 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12274 "mshflo.w %N1, %N2, %0"
12275 [(set_attr "type" "arith_media")
12276 (set_attr "highpart" "ignore")])
12278 /* These are useful to expand ANDs and as combiner patterns. */
12279 (define_insn_and_split "mshfhi_l_di"
12280 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12281 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12283 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12284 (const_int -4294967296))))]
12287 mshfhi.l %N1, %N2, %0
12289 "TARGET_SHMEDIA && reload_completed
12290 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12291 [(set (match_dup 3) (match_dup 4))
12292 (set (match_dup 5) (match_dup 6))]
12295 operands[3] = gen_lowpart (SImode, operands[0]);
12296 operands[4] = gen_highpart (SImode, operands[1]);
12297 operands[5] = gen_highpart (SImode, operands[0]);
12298 operands[6] = gen_highpart (SImode, operands[2]);
12300 [(set_attr "type" "arith_media")])
12302 (define_insn "*mshfhi_l_di_rev"
12303 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12304 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12305 (const_int -4294967296))
12306 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12309 "mshfhi.l %N2, %N1, %0"
12310 [(set_attr "type" "arith_media")])
12313 [(set (match_operand:DI 0 "arith_reg_dest" "")
12314 (ior:DI (zero_extend:DI (match_operand:SI 1
12315 "extend_reg_or_0_operand" ""))
12316 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12317 (const_int -4294967296))))
12318 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12323 emit_insn (gen_ashldi3_media (operands[3],
12324 simplify_gen_subreg (DImode, operands[1],
12327 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12331 (define_insn "mshflo_l_di"
12332 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12333 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12334 (const_int 4294967295))
12335 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12339 "mshflo.l %N1, %N2, %0"
12340 [(set_attr "type" "arith_media")
12341 (set_attr "highpart" "ignore")])
12343 (define_insn "*mshflo_l_di_rev"
12344 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12345 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12347 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12348 (const_int 4294967295))))]
12351 "mshflo.l %N2, %N1, %0"
12352 [(set_attr "type" "arith_media")
12353 (set_attr "highpart" "ignore")])
12355 ;; Combiner pattern for trampoline initialization.
12356 (define_insn_and_split "*double_shori"
12357 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12358 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12360 (match_operand:DI 2 "const_int_operand" "n")))]
12362 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12364 "rtx_equal_p (operands[0], operands[1])"
12368 HOST_WIDE_INT v = INTVAL (operands[2]);
12370 emit_insn (gen_shori_media (operands[0], operands[0],
12371 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12372 emit_insn (gen_shori_media (operands[0], operands[0],
12373 gen_int_mode (v, HImode)));
12376 [(set_attr "highpart" "ignore")])
12379 (define_insn "*mshflo_l_di_x"
12380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12381 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12383 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12387 "mshflo.l %N1, %N2, %0"
12388 [(set_attr "type" "arith_media")
12389 (set_attr "highpart" "ignore")])
12391 (define_insn_and_split "concat_v2sf"
12392 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12393 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12394 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12395 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12399 mshflo.l %N1, %N2, %0
12402 "TARGET_SHMEDIA && reload_completed
12403 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12404 [(set (match_dup 3) (match_dup 1))
12405 (set (match_dup 4) (match_dup 2))]
12408 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12409 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12411 [(set_attr "type" "arith_media")
12412 (set_attr "highpart" "ignore")])
12414 (define_insn "*mshflo_l_di_x_rev"
12415 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12416 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12418 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12421 "mshflo.l %N2, %N1, %0"
12422 [(set_attr "type" "arith_media")
12423 (set_attr "highpart" "ignore")])
12425 (define_insn "ashlv2si3"
12426 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12427 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12428 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12430 "mshlld.l %1, %2, %0"
12431 [(set_attr "type" "arith_media")
12432 (set_attr "highpart" "depend")])
12435 [(set (match_operand 0 "any_register_operand" "")
12436 (match_operator 3 "shift_operator"
12437 [(match_operand 1 "any_register_operand" "")
12438 (match_operand 2 "shift_count_reg_operand" "")]))]
12439 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12440 [(set (match_dup 0) (match_dup 3))]
12443 rtx count = operands[2];
12444 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12446 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12447 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12448 || GET_CODE (count) == TRUNCATE)
12449 count = XEXP (count, 0);
12450 inner_mode = GET_MODE (count);
12451 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12452 subreg_lowpart_offset (outer_mode, inner_mode));
12453 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12454 operands[1], count);
12457 (define_insn "ashlv4hi3"
12458 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12459 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12460 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12462 "mshlld.w %1, %2, %0"
12463 [(set_attr "type" "arith_media")
12464 (set_attr "highpart" "depend")])
12466 (define_insn "lshrv2si3"
12467 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12468 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12469 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12471 "mshlrd.l %1, %2, %0"
12472 [(set_attr "type" "arith_media")
12473 (set_attr "highpart" "depend")])
12475 (define_insn "lshrv4hi3"
12476 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12477 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12478 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12480 "mshlrd.w %1, %2, %0"
12481 [(set_attr "type" "arith_media")
12482 (set_attr "highpart" "depend")])
12484 (define_insn "subv2si3"
12485 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12486 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12487 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12489 "msub.l %N1, %2, %0"
12490 [(set_attr "type" "arith_media")
12491 (set_attr "highpart" "depend")])
12493 (define_insn "subv4hi3"
12494 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12495 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12496 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12498 "msub.w %N1, %2, %0"
12499 [(set_attr "type" "arith_media")
12500 (set_attr "highpart" "depend")])
12502 (define_insn_and_split "subv2hi3"
12503 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12504 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12505 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12512 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12513 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12514 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12515 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12516 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12518 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12519 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12522 [(set_attr "highpart" "must_split")])
12524 (define_insn "sssubv2si3"
12525 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12526 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12527 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12529 "msubs.l %N1, %2, %0"
12530 [(set_attr "type" "mcmp_media")
12531 (set_attr "highpart" "depend")])
12533 (define_insn "ussubv8qi3"
12534 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12535 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12536 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12538 "msubs.ub %N1, %2, %0"
12539 [(set_attr "type" "mcmp_media")
12540 (set_attr "highpart" "depend")])
12542 (define_insn "sssubv4hi3"
12543 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12544 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12545 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12547 "msubs.w %N1, %2, %0"
12548 [(set_attr "type" "mcmp_media")
12549 (set_attr "highpart" "depend")])
12551 ;; Floating Point Intrinsics
12553 (define_insn "fcosa_s"
12554 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12555 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12559 [(set_attr "type" "atrans_media")])
12561 (define_insn "fsina_s"
12562 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12563 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12567 [(set_attr "type" "atrans_media")])
12569 (define_insn "fipr"
12570 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12571 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12572 "fp_arith_reg_operand" "f")
12573 (match_operand:V4SF 2
12574 "fp_arith_reg_operand" "f"))
12575 (parallel [(const_int 0)]))
12576 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12577 (parallel [(const_int 1)])))
12578 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12579 (parallel [(const_int 2)]))
12580 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12581 (parallel [(const_int 3)])))))]
12583 "fipr.s %1, %2, %0"
12584 [(set_attr "type" "fparith_media")])
12586 (define_insn "fsrra_s"
12587 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12588 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12592 [(set_attr "type" "atrans_media")])
12594 (define_insn "ftrv"
12595 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12599 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12600 (parallel [(const_int 0) (const_int 5)
12601 (const_int 10) (const_int 15)]))
12602 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12604 (vec_select:V4SF (match_dup 1)
12605 (parallel [(const_int 4) (const_int 9)
12606 (const_int 14) (const_int 3)]))
12607 (vec_select:V4SF (match_dup 2)
12608 (parallel [(const_int 1) (const_int 2)
12609 (const_int 3) (const_int 0)]))))
12612 (vec_select:V4SF (match_dup 1)
12613 (parallel [(const_int 8) (const_int 13)
12614 (const_int 2) (const_int 7)]))
12615 (vec_select:V4SF (match_dup 2)
12616 (parallel [(const_int 2) (const_int 3)
12617 (const_int 0) (const_int 1)])))
12619 (vec_select:V4SF (match_dup 1)
12620 (parallel [(const_int 12) (const_int 1)
12621 (const_int 6) (const_int 11)]))
12622 (vec_select:V4SF (match_dup 2)
12623 (parallel [(const_int 3) (const_int 0)
12624 (const_int 1) (const_int 2)]))))))]
12626 "ftrv.s %1, %2, %0"
12627 [(set_attr "type" "fparith_media")])
12629 (define_insn "ldhi_l"
12630 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12632 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12635 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12639 [(set_attr "type" "load_media")])
12641 (define_insn "ldhi_q"
12642 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12644 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12647 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12651 [(set_attr "type" "load_media")])
12653 (define_insn_and_split "*ldhi_q_comb0"
12654 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12656 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12657 "register_operand" "r")
12658 (match_operand:SI 2
12659 "ua_offset" "I06"))
12662 (plus:SI (and:SI (match_dup 1) (const_int 7))
12665 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12669 "emit_insn (gen_ldhi_q (operands[0],
12670 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12674 (define_insn_and_split "*ldhi_q_comb1"
12675 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12677 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12678 "register_operand" "r")
12679 (match_operand:SI 2
12680 "ua_offset" "I06"))
12683 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12684 "ua_offset" "I06"))
12688 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12689 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12693 "emit_insn (gen_ldhi_q (operands[0],
12694 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12698 (define_insn "ldlo_l"
12699 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12701 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12703 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12704 (and:SI (match_dup 1) (const_int 3))))]
12707 [(set_attr "type" "load_media")])
12709 (define_insn "ldlo_q"
12710 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12712 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12714 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12715 (and:SI (match_dup 1) (const_int 7))))]
12718 [(set_attr "type" "load_media")])
12720 (define_insn_and_split "*ldlo_q_comb0"
12721 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12723 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12724 (match_operand:SI 2 "ua_offset" "I06"))
12726 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12727 (and:SI (match_dup 1) (const_int 7))))]
12728 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12732 "emit_insn (gen_ldlo_q (operands[0],
12733 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12736 (define_insn_and_split "*ldlo_q_comb1"
12737 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12739 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12740 (match_operand:SI 2 "ua_offset" "I06"))
12742 (minus:SI (const_int 8)
12743 (and:SI (plus:SI (match_dup 1)
12744 (match_operand:SI 3 "ua_offset" "I06"))
12746 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12747 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12748 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12752 "emit_insn (gen_ldlo_q (operands[0],
12753 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12756 (define_insn "sthi_l"
12757 [(set (zero_extract:SI
12758 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12761 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12763 (match_operand:SI 1 "arith_reg_operand" "r"))]
12766 [(set_attr "type" "ustore_media")])
12768 ;; All unaligned stores are considered to be 'narrow' because they typically
12769 ;; operate on less that a quadword, and when they operate on a full quadword,
12770 ;; the vanilla store high / store low sequence will cause a stall if not
12771 ;; scheduled apart.
12772 (define_insn "sthi_q"
12773 [(set (zero_extract:DI
12774 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12777 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12779 (match_operand:DI 1 "arith_reg_operand" "r"))]
12782 [(set_attr "type" "ustore_media")])
12784 (define_insn_and_split "*sthi_q_comb0"
12785 [(set (zero_extract:DI
12786 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12787 "register_operand" "r")
12788 (match_operand:SI 1 "ua_offset"
12792 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12794 (match_operand:DI 2 "arith_reg_operand" "r"))]
12795 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12799 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12803 (define_insn_and_split "*sthi_q_comb1"
12804 [(set (zero_extract:DI
12805 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12806 "register_operand" "r")
12807 (match_operand:SI 1 "ua_offset"
12811 (plus:SI (and:SI (plus:SI (match_dup 0)
12812 (match_operand:SI 2 "ua_offset" "I06"))
12816 (match_operand:DI 3 "arith_reg_operand" "r"))]
12817 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12818 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12822 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12826 ;; This is highpart user because the address is used as full 64 bit.
12827 (define_insn "stlo_l"
12828 [(set (zero_extract:SI
12829 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12831 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12832 (and:SI (match_dup 0) (const_int 3)))
12833 (match_operand:SI 1 "arith_reg_operand" "r"))]
12836 [(set_attr "type" "ustore_media")])
12838 (define_insn "stlo_q"
12839 [(set (zero_extract:DI
12840 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12842 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12843 (and:SI (match_dup 0) (const_int 7)))
12844 (match_operand:DI 1 "arith_reg_operand" "r"))]
12847 [(set_attr "type" "ustore_media")])
12849 (define_insn_and_split "*stlo_q_comb0"
12850 [(set (zero_extract:DI
12851 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12852 (match_operand:SI 1 "ua_offset" "I06"))
12854 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12855 (and:SI (match_dup 0) (const_int 7)))
12856 (match_operand:DI 2 "arith_reg_operand" "r"))]
12857 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12861 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12865 (define_insn_and_split "*stlo_q_comb1"
12866 [(set (zero_extract:DI
12867 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12868 (match_operand:SI 1 "ua_offset" "I06"))
12870 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12871 (match_operand:SI 2
12872 "ua_offset" "I06"))
12874 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12875 (match_operand:DI 3 "arith_reg_operand" "r"))]
12876 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12880 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12884 (define_insn "ldhi_l64"
12885 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12887 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12890 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12894 [(set_attr "type" "load_media")])
12896 (define_insn "ldhi_q64"
12897 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12899 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12902 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12906 [(set_attr "type" "load_media")])
12908 (define_insn "ldlo_l64"
12909 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12911 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12913 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12914 (and:DI (match_dup 1) (const_int 3))))]
12917 [(set_attr "type" "load_media")])
12919 (define_insn "ldlo_q64"
12920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12922 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12924 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12925 (and:DI (match_dup 1) (const_int 7))))]
12928 [(set_attr "type" "load_media")])
12930 (define_insn "sthi_l64"
12931 [(set (zero_extract:SI
12932 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12935 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12937 (match_operand:SI 1 "arith_reg_operand" "r"))]
12940 [(set_attr "type" "ustore_media")])
12942 (define_insn "sthi_q64"
12943 [(set (zero_extract:DI
12944 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12947 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12949 (match_operand:DI 1 "arith_reg_operand" "r"))]
12952 [(set_attr "type" "ustore_media")])
12954 (define_insn "stlo_l64"
12955 [(set (zero_extract:SI
12956 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12958 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12959 (and:DI (match_dup 0) (const_int 3)))
12960 (match_operand:SI 1 "arith_reg_operand" "r"))]
12963 [(set_attr "type" "ustore_media")])
12965 (define_insn "stlo_q64"
12966 [(set (zero_extract:DI
12967 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12969 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12970 (and:DI (match_dup 0) (const_int 7)))
12971 (match_operand:DI 1 "arith_reg_operand" "r"))]
12974 [(set_attr "type" "ustore_media")])
12977 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12978 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12982 [(set_attr "type" "arith_media")])
12984 (define_insn "nsbsi"
12985 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12987 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12991 [(set_attr "type" "arith_media")])
12993 (define_insn "nsbdi"
12994 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12996 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13000 [(set_attr "type" "arith_media")])
13002 (define_expand "ffsdi2"
13003 [(set (match_operand:DI 0 "arith_reg_dest" "")
13004 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13008 rtx scratch = gen_reg_rtx (DImode);
13011 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13012 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13013 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13014 emit_insn (gen_nsbdi (scratch, scratch));
13015 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13016 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13017 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13019 = gen_rtx_EXPR_LIST (REG_EQUAL,
13020 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13024 (define_expand "ffssi2"
13025 [(set (match_operand:SI 0 "arith_reg_dest" "")
13026 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13030 rtx scratch = gen_reg_rtx (SImode);
13031 rtx discratch = gen_reg_rtx (DImode);
13034 emit_insn (gen_adddi3 (discratch,
13035 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13037 emit_insn (gen_andcdi3 (discratch,
13038 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13040 emit_insn (gen_nsbsi (scratch, discratch));
13041 last = emit_insn (gen_subsi3 (operands[0],
13042 force_reg (SImode, GEN_INT (63)), scratch));
13044 = gen_rtx_EXPR_LIST (REG_EQUAL,
13045 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13049 (define_insn "byterev"
13050 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13051 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13052 (parallel [(const_int 7) (const_int 6) (const_int 5)
13053 (const_int 4) (const_int 3) (const_int 2)
13054 (const_int 1) (const_int 0)])))]
13057 [(set_attr "type" "arith_media")])
13059 (define_insn "*prefetch_media"
13060 [(prefetch (match_operand:QI 0 "address_operand" "p")
13061 (match_operand:SI 1 "const_int_operand" "n")
13062 (match_operand:SI 2 "const_int_operand" "n"))]
13066 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13067 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13070 [(set_attr "type" "other")])
13072 (define_insn "*prefetch_i4"
13073 [(prefetch (match_operand:SI 0 "register_operand" "r")
13074 (match_operand:SI 1 "const_int_operand" "n")
13075 (match_operand:SI 2 "const_int_operand" "n"))]
13076 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13079 return \"pref @%0\";
13081 [(set_attr "type" "other")])
13083 (define_expand "prefetch"
13084 [(prefetch (match_operand 0 "address_operand" "p")
13085 (match_operand:SI 1 "const_int_operand" "n")
13086 (match_operand:SI 2 "const_int_operand" "n"))]
13087 "TARGET_HARD_SH4 || TARGET_SH5"
13090 if (GET_MODE (operands[0]) != Pmode
13091 || GET_CODE (operands[1]) != CONST_INT
13092 || GET_CODE (operands[2]) != CONST_INT)
13094 if (! TARGET_SHMEDIA)
13095 operands[0] = force_reg (Pmode, operands[0]);
13098 (define_insn "alloco_i"
13099 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13100 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13106 if (GET_CODE (operands[0]) == PLUS)
13108 xops[0] = XEXP (operands[0], 0);
13109 xops[1] = XEXP (operands[0], 1);
13113 xops[0] = operands[0];
13114 xops[1] = const0_rtx;
13116 output_asm_insn (\"alloco %0, %1\", xops);
13119 [(set_attr "type" "other")])
13122 [(set (match_operand 0 "any_register_operand" "")
13123 (match_operand 1 "" ""))]
13124 "TARGET_SHMEDIA && reload_completed"
13125 [(set (match_dup 0) (match_dup 1))]
13130 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);