1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
138 (UNSPEC_EH_RETURN 19)
146 (UNSPEC_DIV_INV_M0 30)
147 (UNSPEC_DIV_INV_M1 31)
148 (UNSPEC_DIV_INV_M2 32)
149 (UNSPEC_DIV_INV_M3 33)
150 (UNSPEC_DIV_INV20 34)
156 ;; These are used with unspec_volatile.
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
166 ;; -------------------------------------------------------------------------
168 ;; -------------------------------------------------------------------------
173 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174 (const (symbol_ref "sh_cpu_attr")))
176 (define_attr "endian" "big,little"
177 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178 (const_string "little") (const_string "big"))))
180 ;; Indicate if the default fpu mode is single precision.
181 (define_attr "fpu_single" "yes,no"
182 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183 (const_string "yes") (const_string "no"))))
185 (define_attr "fmovd" "yes,no"
186 (const (if_then_else (symbol_ref "TARGET_FMOVD")
187 (const_string "yes") (const_string "no"))))
189 (define_attr "pipe_model" "sh1,sh4,sh5media"
191 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193 (const_string "sh1"))))
195 ;; cbranch conditional branch instructions
196 ;; jump unconditional jumps
197 ;; arith ordinary arithmetic
198 ;; arith3 a compound insn that behaves similarly to a sequence of
199 ;; three insns of type arith
200 ;; arith3b like above, but might end with a redirected branch
202 ;; load_si Likewise, SImode variant for general register.
203 ;; fload Likewise, but load to fp register.
205 ;; move general purpose register to register
206 ;; mt_group other sh4 mt instructions
207 ;; fmove register to register, floating point
208 ;; smpy word precision integer multiply
209 ;; dmpy longword or doublelongword precision integer multiply
211 ;; pload load of pr reg, which can't be put into delay slot of rts
212 ;; prset copy register to pr reg, ditto
213 ;; pstore store of pr reg, which can't be put into delay slot of jsr
214 ;; prget copy pr to register, ditto
215 ;; pcload pc relative load of constant value
216 ;; pcfload Likewise, but load to fp register.
217 ;; pcload_si Likewise, SImode variant for general register.
218 ;; rte return from exception
219 ;; sfunc special function call with known used registers
220 ;; call function call
222 ;; fdiv floating point divide (or square root)
223 ;; gp_fpul move from general purpose register to fpul
224 ;; fpul_gp move from fpul to general purpose register
225 ;; mac_gp move from mac[lh] to general purpose register
226 ;; dfp_arith, dfp_cmp,dfp_conv
227 ;; ftrc_s fix_truncsfsi2_i4
228 ;; dfdiv double precision floating point divide (or square root)
229 ;; cwb ic_invalidate_line_i
230 ;; movua SH4a unaligned load
231 ;; fsrra square root reciprocal approximate
232 ;; fsca sine and cosine approximate
233 ;; tls_load load TLS related address
234 ;; arith_media SHmedia arithmetic, logical, and shift instructions
235 ;; cbranch_media SHmedia conditional branch instructions
236 ;; cmp_media SHmedia compare instructions
237 ;; dfdiv_media SHmedia double precision divide and square root
238 ;; dfmul_media SHmedia double precision multiply instruction
239 ;; dfparith_media SHmedia double precision floating point arithmetic
240 ;; dfpconv_media SHmedia double precision floating point conversions
241 ;; dmpy_media SHmedia longword multiply
242 ;; fcmp_media SHmedia floating point compare instructions
243 ;; fdiv_media SHmedia single precision divide and square root
244 ;; fload_media SHmedia floating point register load instructions
245 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
246 ;; fparith_media SHmedia single precision floating point arithmetic
247 ;; fpconv_media SHmedia single precision floating point conversions
248 ;; fstore_media SHmedia floating point register store instructions
249 ;; gettr_media SHmedia gettr instruction
250 ;; invalidate_line_media SHmedia invalidate_line sequence
251 ;; jump_media SHmedia unconditional branch instructions
252 ;; load_media SHmedia general register load instructions
253 ;; pt_media SHmedia pt instruction (expanded by assembler)
254 ;; ptabs_media SHmedia ptabs instruction
255 ;; store_media SHmedia general register store instructions
256 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
257 ;; mac_media SHmedia mac-style fixed point operations
258 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
259 ;; atrans_media SHmedia approximate transcendental functions
260 ;; ustore_media SHmedia unaligned stores
261 ;; nil no-op move, will be deleted.
264 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
265 (const_string "other"))
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
270 ;; mt_group SH4 "mt" group instructions.
272 ;; ex_group SH4 "ex" group instructions.
274 ;; ls_group SH4 "ls" group instructions.
277 (define_attr "insn_class"
278 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282 (eq_attr "type" "cbranch,jump") (const_string "br_group")
283 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284 (const_string "fe_group")
285 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
286 (const_string "none")))
287 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288 ;; so these do not belong in an insn group, although they are modeled
289 ;; with their own define_insn_reservations.
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
295 ;; Indicate if the fpu mode is set by this instruction
296 ;; "unknown" must have the value as "none" in fp_mode, and means
297 ;; that the instruction/abi has left the processor in an unknown
299 ;; "none" means that nothing has changed and no mode is set.
300 ;; This attribute is only used for the Renesas ABI.
301 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
303 ; If a conditional branch destination is within -252..258 bytes away
304 ; from the instruction it can be 2 bytes long. Something in the
305 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
306 ; branches are initially assumed to be 16 bytes long.
307 ; In machine_dependent_reorg, we split all branches that are longer than
310 ;; The maximum range used for SImode constant pool entries is 1018. A final
311 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
313 ;; instruction around the pool table, 2 bytes of alignment before the table,
314 ;; and 30 bytes of alignment after the table. That gives a maximum total
315 ;; pool size of 1058 bytes.
316 ;; Worst case code/pool content size ratio is 1:2 (using asms).
317 ;; Thus, in the worst case, there is one instruction in front of a maximum
318 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
320 ;; If we have a forward branch, the initial table will be put after the
321 ;; unconditional branch.
323 ;; ??? We could do much better by keeping track of the actual pcloads within
324 ;; the branch range and in the pcload range in front of the branch range.
326 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
328 (define_attr "short_cbranch_p" "no,yes"
329 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
331 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
333 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
335 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
337 ] (const_string "no")))
339 (define_attr "med_branch_p" "no,yes"
340 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
343 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
345 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
348 ] (const_string "no")))
350 (define_attr "med_cbranch_p" "no,yes"
351 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
354 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
359 ] (const_string "no")))
361 (define_attr "braf_branch_p" "no,yes"
362 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
367 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
372 ] (const_string "no")))
374 (define_attr "braf_cbranch_p" "no,yes"
375 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
380 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
382 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
385 ] (const_string "no")))
387 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
388 ; For wider ranges, we need a combination of a code and a data part.
389 ; If we can get a scratch register for a long range jump, the code
390 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
392 ; long; otherwise, it must be 6 bytes long.
394 ; All other instructions are two bytes long by default.
396 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397 ;; but getattrtab doesn't understand this.
398 (define_attr "length" ""
399 (cond [(eq_attr "type" "cbranch")
400 (cond [(eq_attr "short_cbranch_p" "yes")
402 (eq_attr "med_cbranch_p" "yes")
404 (eq_attr "braf_cbranch_p" "yes")
406 ;; ??? using pc is not computed transitively.
407 (ne (match_dup 0) (match_dup 0))
409 (ne (symbol_ref ("flag_pic")) (const_int 0))
412 (eq_attr "type" "jump")
413 (cond [(eq_attr "med_branch_p" "yes")
415 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
417 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
419 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
420 (symbol_ref "code_for_indirect_jump_scratch"))))
421 (cond [(eq_attr "braf_branch_p" "yes")
423 (eq (symbol_ref "flag_pic") (const_int 0))
425 (ne (symbol_ref "TARGET_SH2") (const_int 0))
426 (const_int 10)] (const_int 18))
427 (eq_attr "braf_branch_p" "yes")
429 ;; ??? using pc is not computed transitively.
430 (ne (match_dup 0) (match_dup 0))
432 (ne (symbol_ref ("flag_pic")) (const_int 0))
435 (eq_attr "type" "pt_media")
436 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
437 (const_int 20) (const_int 12))
438 (and (eq_attr "type" "jump_media")
439 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
441 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
445 ;; DFA descriptions for the pipelines
448 (include "shmedia.md")
451 (include "predicates.md")
453 ;; Definitions for filling delay slots
455 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
457 ;; ??? This should be (nil) instead of (const_int 0)
458 (define_attr "hit_stack" "yes,no"
459 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
462 (const_string "yes")))
464 (define_attr "interrupt_function" "no,yes"
465 (const (symbol_ref "current_function_interrupt")))
467 (define_attr "in_delay_slot" "yes,no"
468 (cond [(eq_attr "type" "cbranch") (const_string "no")
469 (eq_attr "type" "pcload,pcload_si") (const_string "no")
470 (eq_attr "needs_delay_slot" "yes") (const_string "no")
471 (eq_attr "length" "2") (const_string "yes")
472 ] (const_string "no")))
474 (define_attr "cond_delay_slot" "yes,no"
475 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
476 ] (const_string "no")))
478 (define_attr "is_sfunc" ""
479 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
481 (define_attr "is_mac_media" ""
482 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
484 (define_attr "branch_zero" "yes,no"
485 (cond [(eq_attr "type" "!cbranch") (const_string "no")
486 (ne (symbol_ref "(next_active_insn (insn)\
487 == (prev_active_insn\
488 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
489 && get_attr_length (next_active_insn (insn)) == 2")
491 (const_string "yes")]
492 (const_string "no")))
494 ;; SH4 Double-precision computation with double-precision result -
495 ;; the two halves are ready at different times.
496 (define_attr "dfp_comp" "yes,no"
497 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
498 (const_string "no")))
500 ;; Insns for which the latency of a preceding fp insn is decreased by one.
501 (define_attr "late_fp_use" "yes,no" (const_string "no"))
502 ;; And feeding insns for which this relevant.
503 (define_attr "any_fp_comp" "yes,no"
504 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
505 (const_string "yes")]
506 (const_string "no")))
508 (define_attr "any_int_load" "yes,no"
509 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
510 (const_string "yes")]
511 (const_string "no")))
513 (define_attr "highpart" "user, ignore, extend, depend, must_split"
514 (const_string "user"))
517 (eq_attr "needs_delay_slot" "yes")
518 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
520 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
521 ;; and thus we can't put a pop instruction in its delay slot.
522 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
523 ;; instruction can go in the delay slot.
525 ;; Since a normal return (rts) implicitly uses the PR register,
526 ;; we can't allow PR register loads in an rts delay slot.
529 (eq_attr "type" "return")
530 [(and (eq_attr "in_delay_slot" "yes")
531 (ior (and (eq_attr "interrupt_function" "no")
532 (eq_attr "type" "!pload,prset"))
533 (and (eq_attr "interrupt_function" "yes")
535 (ne (symbol_ref "TARGET_SH3") (const_int 0))
536 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
538 ;; Since a call implicitly uses the PR register, we can't allow
539 ;; a PR register store in a jsr delay slot.
542 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
543 [(and (eq_attr "in_delay_slot" "yes")
544 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
546 ;; Say that we have annulled true branches, since this gives smaller and
547 ;; faster code when branches are predicted as not taken.
549 ;; ??? The non-annulled condition should really be "in_delay_slot",
550 ;; but insns that can be filled in non-annulled get priority over insns
551 ;; that can only be filled in anulled.
554 (and (eq_attr "type" "cbranch")
555 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
556 ;; SH2e has a hardware bug that pretty much prohibits the use of
557 ;; annuled delay slots.
558 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
559 (not (eq_attr "cpu" "sh2e"))) (nil)])
561 ;; -------------------------------------------------------------------------
562 ;; SImode signed integer comparisons
563 ;; -------------------------------------------------------------------------
567 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
568 (match_operand:SI 1 "arith_operand" "K08,r"))
572 [(set_attr "type" "mt_group")])
574 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
575 ;; That would still allow reload to create cmpi instructions, but would
576 ;; perhaps allow forcing the constant into a register when that is better.
577 ;; Probably should use r0 for mem/imm compares, but force constant into a
578 ;; register for pseudo/imm compares.
580 (define_insn "cmpeqsi_t"
582 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
583 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
589 [(set_attr "type" "mt_group")])
591 (define_insn "cmpgtsi_t"
593 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
594 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
599 [(set_attr "type" "mt_group")])
601 (define_insn "cmpgesi_t"
603 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
604 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
609 [(set_attr "type" "mt_group")])
611 ;; -------------------------------------------------------------------------
612 ;; SImode unsigned integer comparisons
613 ;; -------------------------------------------------------------------------
615 (define_insn "cmpgeusi_t"
617 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
618 (match_operand:SI 1 "arith_reg_operand" "r")))]
621 [(set_attr "type" "mt_group")])
623 (define_insn "cmpgtusi_t"
625 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
626 (match_operand:SI 1 "arith_reg_operand" "r")))]
629 [(set_attr "type" "mt_group")])
631 ;; We save the compare operands in the cmpxx patterns and use them when
632 ;; we generate the branch.
634 (define_expand "cmpsi"
636 (compare (match_operand:SI 0 "cmpsi_operand" "")
637 (match_operand:SI 1 "arith_operand" "")))]
638 "TARGET_SH1 || TARGET_SHMEDIA"
641 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
642 && GET_CODE (operands[1]) != CONST_INT)
643 operands[0] = copy_to_mode_reg (SImode, operands[0]);
644 sh_compare_op0 = operands[0];
645 sh_compare_op1 = operands[1];
649 ;; -------------------------------------------------------------------------
650 ;; DImode signed integer comparisons
651 ;; -------------------------------------------------------------------------
653 ;; ??? Could get better scheduling by splitting the initial test from the
654 ;; rest of the insn after reload. However, the gain would hardly justify
655 ;; the sh.md size increase necessary to do that.
659 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
660 (match_operand:DI 1 "arith_operand" "r"))
663 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
665 [(set_attr "length" "6")
666 (set_attr "type" "arith3b")])
668 (define_insn "cmpeqdi_t"
670 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
671 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
674 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
675 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
676 [(set_attr "length" "6")
677 (set_attr "type" "arith3b")])
681 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
682 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
683 ;; If we applied this split when not optimizing, it would only be
684 ;; applied during the machine-dependent reorg, when no new basic blocks
686 "TARGET_SH1 && reload_completed && optimize"
687 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
688 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
689 (label_ref (match_dup 6))
691 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
696 = gen_rtx_REG (SImode,
697 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
699 = (operands[1] == const0_rtx
701 : gen_rtx_REG (SImode,
702 true_regnum (operands[1])
703 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
704 operands[4] = gen_lowpart (SImode, operands[0]);
705 operands[5] = gen_lowpart (SImode, operands[1]);
706 operands[6] = gen_label_rtx ();
709 (define_insn "cmpgtdi_t"
711 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
712 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
715 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
716 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
717 [(set_attr "length" "8")
718 (set_attr "type" "arith3")])
720 (define_insn "cmpgedi_t"
722 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
723 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
726 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
728 [(set_attr "length" "8,2")
729 (set_attr "type" "arith3,mt_group")])
731 ;; -------------------------------------------------------------------------
732 ;; DImode unsigned integer comparisons
733 ;; -------------------------------------------------------------------------
735 (define_insn "cmpgeudi_t"
737 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
738 (match_operand:DI 1 "arith_reg_operand" "r")))]
740 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
741 [(set_attr "length" "8")
742 (set_attr "type" "arith3")])
744 (define_insn "cmpgtudi_t"
746 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
747 (match_operand:DI 1 "arith_reg_operand" "r")))]
749 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
750 [(set_attr "length" "8")
751 (set_attr "type" "arith3")])
753 (define_insn "cmpeqsi_media"
754 [(set (match_operand:DI 0 "register_operand" "=r")
755 (eq:DI (match_operand:SI 1 "logical_operand" "%r")
756 (match_operand:SI 2 "cmp_operand" "Nr")))]
759 [(set_attr "type" "cmp_media")])
761 (define_insn "cmpeqdi_media"
762 [(set (match_operand:DI 0 "register_operand" "=r")
763 (eq:DI (match_operand:DI 1 "register_operand" "%r")
764 (match_operand:DI 2 "cmp_operand" "Nr")))]
767 [(set_attr "type" "cmp_media")])
769 (define_insn "cmpgtsi_media"
770 [(set (match_operand:DI 0 "register_operand" "=r")
771 (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
772 (match_operand:SI 2 "cmp_operand" "rN")))]
775 [(set_attr "type" "cmp_media")])
777 (define_insn "cmpgtdi_media"
778 [(set (match_operand:DI 0 "register_operand" "=r")
779 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
780 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
783 [(set_attr "type" "cmp_media")])
785 (define_insn "cmpgtusi_media"
786 [(set (match_operand:DI 0 "register_operand" "=r")
787 (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
788 (match_operand:SI 2 "cmp_operand" "rN")))]
790 "cmpgtu %N1, %N2, %0"
791 [(set_attr "type" "cmp_media")])
793 (define_insn "cmpgtudi_media"
794 [(set (match_operand:DI 0 "register_operand" "=r")
795 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
796 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
798 "cmpgtu %N1, %N2, %0"
799 [(set_attr "type" "cmp_media")])
801 (define_insn "cmpsieqsi_media"
802 [(set (match_operand:SI 0 "register_operand" "=r")
803 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
804 (match_operand:SI 2 "cmp_operand" "Nr")))]
807 [(set_attr "type" "cmp_media")])
809 (define_insn "cmpsieqdi_media"
810 [(set (match_operand:SI 0 "register_operand" "=r")
811 (eq:SI (match_operand:DI 1 "register_operand" "%r")
812 (match_operand:DI 2 "cmp_operand" "Nr")))]
815 [(set_attr "type" "cmp_media")])
817 (define_insn "cmpsigtsi_media"
818 [(set (match_operand:SI 0 "register_operand" "=r")
819 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
820 (match_operand:SI 2 "cmp_operand" "rN")))]
823 [(set_attr "type" "cmp_media")])
825 (define_insn "cmpsigtdi_media"
826 [(set (match_operand:SI 0 "register_operand" "=r")
827 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
828 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
831 [(set_attr "type" "cmp_media")])
833 (define_insn "cmpsigtusi_media"
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
836 (match_operand:SI 2 "cmp_operand" "rN")))]
838 "cmpgtu %N1, %N2, %0"
839 [(set_attr "type" "cmp_media")])
841 (define_insn "cmpsigtudi_media"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
844 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
846 "cmpgtu %N1, %N2, %0"
847 [(set_attr "type" "cmp_media")])
849 ; These two patterns are for combine.
850 (define_insn "*cmpne0si_media"
851 [(set (match_operand:DI 0 "register_operand" "=r")
852 (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
855 [(set_attr "type" "cmp_media")])
857 (define_insn "*cmpne0sisi_media"
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
862 [(set_attr "type" "cmp_media")])
864 ;; We save the compare operands in the cmpxx patterns and use them when
865 ;; we generate the branch.
867 (define_expand "cmpdi"
869 (compare (match_operand:DI 0 "arith_operand" "")
870 (match_operand:DI 1 "arith_operand" "")))]
871 "TARGET_SH2 || TARGET_SHMEDIA"
874 sh_compare_op0 = operands[0];
875 sh_compare_op1 = operands[1];
878 ;; -------------------------------------------------------------------------
879 ;; Conditional move instructions
880 ;; -------------------------------------------------------------------------
882 ;; The insn names may seem reversed, but note that cmveq performs the move
883 ;; if op1 == 0, and cmvne does it if op1 != 0.
885 (define_insn "movdicc_false"
886 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
887 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
889 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
890 (match_operand:DI 3 "arith_reg_operand" "0")))]
893 [(set_attr "type" "arith_media")])
895 (define_insn "movdicc_true"
896 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
897 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
899 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
900 (match_operand:DI 3 "arith_reg_operand" "0")))]
903 [(set_attr "type" "arith_media")])
906 [(set (match_operand:DI 0 "arith_reg_dest" "")
907 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
908 [(match_operand:DI 1 "arith_reg_operand" "")
910 (match_operand:DI 2 "arith_reg_dest" "")
912 (set (match_dup 2) (match_dup 0))]
913 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
915 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
918 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
919 VOIDmode, operands[1], CONST0_RTX (DImode));
923 [(set (match_operand:DI 0 "general_movdst_operand" "")
924 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
925 (set (match_operand:DI 2 "arith_reg_dest" "")
926 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
927 [(match_operand:DI 3 "arith_reg_operand" "")
931 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
933 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
936 (define_expand "movdicc"
937 [(set (match_operand:DI 0 "register_operand" "")
938 (if_then_else:DI (match_operand 1 "comparison_operator" "")
939 (match_operand:DI 2 "register_operand" "")
940 (match_operand:DI 3 "register_operand" "")))]
944 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
945 && GET_MODE (sh_compare_op0) == DImode
946 && sh_compare_op1 == const0_rtx)
947 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
948 sh_compare_op0, sh_compare_op1);
956 tmp = gen_reg_rtx (DImode);
958 switch (GET_CODE (operands[1]))
961 emit_insn (gen_seq (tmp));
962 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
966 emit_insn (gen_seq (tmp));
967 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
971 emit_insn (gen_sgt (tmp));
972 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
976 emit_insn (gen_slt (tmp));
977 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
981 emit_insn (gen_slt (tmp));
982 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
986 emit_insn (gen_sgt (tmp));
987 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
991 emit_insn (gen_sgtu (tmp));
992 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
996 emit_insn (gen_sltu (tmp));
997 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1001 emit_insn (gen_sltu (tmp));
1002 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006 emit_insn (gen_sgtu (tmp));
1007 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1011 emit_insn (gen_sunordered (tmp));
1012 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1016 emit_insn (gen_sunordered (tmp));
1017 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1034 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1035 ;; SImode to DImode.
1036 (define_insn "movsicc_false"
1037 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1038 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1040 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1041 (match_operand:SI 3 "arith_reg_operand" "0")))]
1044 [(set_attr "type" "arith_media")])
1046 (define_insn "movsicc_true"
1047 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1048 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1050 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1051 (match_operand:SI 3 "arith_reg_operand" "0")))]
1054 [(set_attr "type" "arith_media")])
1057 [(set (match_operand:SI 0 "arith_reg_dest" "")
1058 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1059 [(match_operand:SI 1 "arith_reg_operand" "")
1061 (match_operand:SI 2 "arith_reg_dest" "")
1063 (set (match_dup 2) (match_dup 0))]
1064 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1066 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1069 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1070 VOIDmode, operands[1], CONST0_RTX (SImode));
1074 [(set (match_operand:SI 0 "general_movdst_operand" "")
1075 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1076 (set (match_operand:SI 2 "arith_reg_dest" "")
1077 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1078 [(match_operand:SI 3 "arith_reg_operand" "")
1082 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1083 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1085 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1088 replace_rtx (operands[4], operands[0], operands[1]);
1092 [(set (match_operand 0 "any_register_operand" "")
1093 (match_operand 1 "any_register_operand" ""))
1094 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1095 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1096 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1097 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1098 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1099 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1100 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1101 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1102 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1103 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1104 && (REGNO_REG_CLASS (REGNO (operands[0]))
1105 == REGNO_REG_CLASS (REGNO (operands[2])))
1106 && (REGNO_REG_CLASS (REGNO (operands[1]))
1107 == REGNO_REG_CLASS (REGNO (operands[0])))"
1108 [(set (match_dup 0) (match_dup 3))
1109 (set (match_dup 4) (match_dup 5))]
1113 rtx replacements[4];
1115 /* We want to replace occurrences of operands[0] with operands[1] and
1116 operands[2] with operands[0] in operands[4]/operands[5].
1117 Doing just two replace_rtx calls naively would result in the second
1118 replacement undoing all that the first did if operands[1] and operands[2]
1119 are identical, so we must do this simultaneously. */
1120 replacements[0] = operands[0];
1121 replacements[1] = operands[1];
1122 replacements[2] = operands[2];
1123 replacements[3] = operands[0];
1124 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1125 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1126 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1129 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1130 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1131 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1132 /* The operands array is aliased to recog_data.operand, which gets
1133 clobbered by extract_insn, so finish with it now. */
1134 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1135 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1136 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1137 always uses emit_insn. */
1138 /* Check that we don't violate matching constraints or earlyclobbers. */
1139 extract_insn (emit_insn (set1));
1140 if (! constrain_operands (1))
1142 extract_insn (emit (set2));
1143 if (! constrain_operands (1))
1147 tmp = replacements[0];
1148 replacements[0] = replacements[1];
1149 replacements[1] = tmp;
1150 tmp = replacements[2];
1151 replacements[2] = replacements[3];
1152 replacements[3] = tmp;
1153 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1154 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1155 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1161 ;; The register allocator is rather clumsy in handling multi-way conditional
1162 ;; moves, so allow the combiner to make them, and we split them up after
1164 (define_insn_and_split "*movsicc_umin"
1165 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1166 (umin:SI (if_then_else:SI
1167 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1169 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1170 (match_operand:SI 3 "register_operand" "0"))
1171 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1172 (clobber (match_scratch:SI 5 "=&r"))]
1173 "TARGET_SHMEDIA && no_new_pseudos"
1175 "TARGET_SHMEDIA && reload_completed"
1179 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1181 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1182 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1187 (define_expand "movsicc"
1188 [(set (match_operand:SI 0 "register_operand" "")
1189 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1190 (match_operand:SI 2 "register_operand" "")
1191 (match_operand:SI 3 "register_operand" "")))]
1195 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1196 && GET_MODE (sh_compare_op0) == SImode
1197 && sh_compare_op1 == const0_rtx)
1198 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1199 sh_compare_op0, sh_compare_op1);
1207 tmp = gen_reg_rtx (SImode);
1209 switch (GET_CODE (operands[1]))
1212 emit_insn (gen_seq (tmp));
1213 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1217 emit_insn (gen_seq (tmp));
1218 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1222 emit_insn (gen_sgt (tmp));
1223 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1227 emit_insn (gen_slt (tmp));
1228 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1232 emit_insn (gen_slt (tmp));
1233 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1237 emit_insn (gen_sgt (tmp));
1238 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1242 emit_insn (gen_sgtu (tmp));
1243 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1247 emit_insn (gen_sltu (tmp));
1248 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1252 emit_insn (gen_sltu (tmp));
1253 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1257 emit_insn (gen_sgtu (tmp));
1258 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1262 emit_insn (gen_sunordered (tmp));
1263 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1267 emit_insn (gen_sunordered (tmp));
1268 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1285 (define_expand "movqicc"
1286 [(set (match_operand:QI 0 "register_operand" "")
1287 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1288 (match_operand:QI 2 "register_operand" "")
1289 (match_operand:QI 3 "register_operand" "")))]
1293 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1294 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1295 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1296 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1300 ;; -------------------------------------------------------------------------
1301 ;; Addition instructions
1302 ;; -------------------------------------------------------------------------
1304 (define_expand "adddi3"
1305 [(set (match_operand:DI 0 "arith_reg_operand" "")
1306 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1307 (match_operand:DI 2 "arith_operand" "")))]
1313 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1315 operands[2] = force_reg (DImode, operands[2]);
1316 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1321 (define_insn "*adddi3_media"
1322 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1323 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1324 (match_operand:DI 2 "arith_operand" "r,I10")))]
1329 [(set_attr "type" "arith_media")])
1331 (define_insn "*adddisi3_media"
1332 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1333 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1334 (match_operand:DI 2 "arith_operand" "r,I10")))]
1339 [(set_attr "type" "arith_media")
1340 (set_attr "highpart" "ignore")])
1342 (define_insn "adddi3z_media"
1343 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1345 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1346 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1348 "addz.l %1, %N2, %0"
1349 [(set_attr "type" "arith_media")
1350 (set_attr "highpart" "ignore")])
1352 (define_insn "adddi3_compact"
1353 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1354 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1355 (match_operand:DI 2 "arith_reg_operand" "r")))
1356 (clobber (reg:SI T_REG))]
1359 [(set_attr "length" "6")])
1362 [(set (match_operand:DI 0 "arith_reg_dest" "")
1363 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1364 (match_operand:DI 2 "arith_reg_operand" "")))
1365 (clobber (reg:SI T_REG))]
1366 "TARGET_SH1 && reload_completed"
1370 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1371 high0 = gen_rtx_REG (SImode,
1372 true_regnum (operands[0])
1373 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1374 high2 = gen_rtx_REG (SImode,
1375 true_regnum (operands[2])
1376 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1377 emit_insn (gen_clrt ());
1378 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1379 emit_insn (gen_addc1 (high0, high0, high2));
1384 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1385 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1386 (match_operand:SI 2 "arith_reg_operand" "r"))
1389 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1392 [(set_attr "type" "arith")])
1394 (define_insn "addc1"
1395 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1396 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1397 (match_operand:SI 2 "arith_reg_operand" "r"))
1399 (clobber (reg:SI T_REG))]
1402 [(set_attr "type" "arith")])
1404 (define_expand "addsi3"
1405 [(set (match_operand:SI 0 "arith_reg_operand" "")
1406 (plus:SI (match_operand:SI 1 "arith_operand" "")
1407 (match_operand:SI 2 "arith_operand" "")))]
1412 operands[1] = force_reg (SImode, operands[1]);
1415 (define_insn "addsi3_media"
1416 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1417 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1418 (match_operand:SI 2 "arith_operand" "r,I10")))]
1423 [(set_attr "type" "arith_media")
1424 (set_attr "highpart" "ignore")])
1426 (define_insn "addsidi3_media"
1427 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1428 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1430 (match_operand:SI 2 "arith_operand"
1436 [(set_attr "type" "arith_media")
1437 (set_attr "highpart" "ignore")])
1439 (define_insn "*addsi3_compact"
1440 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1441 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1442 (match_operand:SI 2 "arith_operand" "rI08")))]
1445 [(set_attr "type" "arith")])
1447 ;; -------------------------------------------------------------------------
1448 ;; Subtraction instructions
1449 ;; -------------------------------------------------------------------------
1451 (define_expand "subdi3"
1452 [(set (match_operand:DI 0 "arith_reg_operand" "")
1453 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1454 (match_operand:DI 2 "arith_reg_operand" "")))]
1460 operands[1] = force_reg (DImode, operands[1]);
1461 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1466 (define_insn "*subdi3_media"
1467 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1468 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1469 (match_operand:DI 2 "arith_reg_operand" "r")))]
1472 [(set_attr "type" "arith_media")])
1474 (define_insn "subdisi3_media"
1475 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1476 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1477 (match_operand:DI 2 "arith_reg_operand" "r")))]
1480 [(set_attr "type" "arith_media")
1481 (set_attr "highpart" "ignore")])
1483 (define_insn "subdi3_compact"
1484 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1485 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1486 (match_operand:DI 2 "arith_reg_operand" "r")))
1487 (clobber (reg:SI T_REG))]
1490 [(set_attr "length" "6")])
1493 [(set (match_operand:DI 0 "arith_reg_dest" "")
1494 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1495 (match_operand:DI 2 "arith_reg_operand" "")))
1496 (clobber (reg:SI T_REG))]
1497 "TARGET_SH1 && reload_completed"
1501 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1502 high0 = gen_rtx_REG (SImode,
1503 true_regnum (operands[0])
1504 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1505 high2 = gen_rtx_REG (SImode,
1506 true_regnum (operands[2])
1507 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1508 emit_insn (gen_clrt ());
1509 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1510 emit_insn (gen_subc1 (high0, high0, high2));
1515 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1516 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1517 (match_operand:SI 2 "arith_reg_operand" "r"))
1520 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1525 [(set_attr "type" "arith")])
1527 (define_insn "subc1"
1528 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1529 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1530 (match_operand:SI 2 "arith_reg_operand" "r"))
1532 (clobber (reg:SI T_REG))]
1535 [(set_attr "type" "arith")])
1537 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1538 ;; pattern for this case. This helps multimedia applications that compute
1539 ;; the sum of absolute differences.
1540 (define_insn "mov_neg_si_t"
1541 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1544 [(set_attr "type" "arith")])
1546 (define_insn "*subsi3_internal"
1547 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1548 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1549 (match_operand:SI 2 "arith_reg_operand" "r")))]
1552 [(set_attr "type" "arith")])
1554 (define_insn_and_split "*subsi3_media"
1555 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1556 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1557 (match_operand:SI 2 "extend_reg_operand" "r")))]
1559 && (operands[1] != constm1_rtx
1560 || (GET_CODE (operands[2]) != TRUNCATE
1561 && GET_CODE (operands[2]) != SUBREG))"
1563 "operands[1] == constm1_rtx"
1564 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1566 [(set_attr "type" "arith_media")
1567 (set_attr "highpart" "ignore")])
1570 [(set (match_operand:SI 0 "arith_reg_dest" "")
1571 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1572 "general_extend_operand"
1574 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1575 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1576 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1580 [(set (match_operand:SI 0 "arith_reg_dest" "")
1581 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1582 "general_extend_operand"
1584 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1585 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1586 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1588 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1589 ;; will sometimes save one instruction. Otherwise we might get
1590 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1593 (define_expand "subsi3"
1594 [(set (match_operand:SI 0 "arith_reg_operand" "")
1595 (minus:SI (match_operand:SI 1 "arith_operand" "")
1596 (match_operand:SI 2 "arith_reg_operand" "")))]
1600 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1602 emit_insn (gen_negsi2 (operands[0], operands[2]));
1603 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1608 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1610 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1611 operands[1] = force_reg (SImode, operands[1]);
1615 ;; -------------------------------------------------------------------------
1616 ;; Division instructions
1617 ;; -------------------------------------------------------------------------
1619 ;; We take advantage of the library routines which don't clobber as many
1620 ;; registers as a normal function call would.
1622 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1623 ;; also has an effect on the register that holds the address of the sfunc.
1624 ;; To make this work, we have an extra dummy insn that shows the use
1625 ;; of this register for reorg.
1627 (define_insn "use_sfunc_addr"
1628 [(set (reg:SI PR_REG)
1629 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1630 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1632 [(set_attr "length" "0")])
1634 (define_insn "udivsi3_sh2a"
1635 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1636 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1637 (match_operand:SI 2 "arith_reg_operand" "z")))]
1640 [(set_attr "type" "arith")
1641 (set_attr "in_delay_slot" "no")])
1643 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1644 ;; hard register 0. If we used hard register 0, then the next instruction
1645 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1646 ;; gets allocated to a stack slot that needs its address reloaded, then
1647 ;; there is nothing to prevent reload from using r0 to reload the address.
1648 ;; This reload would clobber the value in r0 we are trying to store.
1649 ;; If we let reload allocate r0, then this problem can never happen.
1651 (define_insn "udivsi3_i1"
1652 [(set (match_operand:SI 0 "register_operand" "=z")
1653 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1654 (clobber (reg:SI T_REG))
1655 (clobber (reg:SI PR_REG))
1656 (clobber (reg:SI R4_REG))
1657 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1658 "TARGET_SH1 && ! TARGET_SH4"
1660 [(set_attr "type" "sfunc")
1661 (set_attr "needs_delay_slot" "yes")])
1663 ; Since shmedia-nofpu code could be linked against shcompact code, and
1664 ; the udivsi3 libcall has the same name, we must consider all registers
1665 ; clobbered that are in the union of the registers clobbered by the
1666 ; shmedia and the shcompact implementation. Note, if the shcompact
1667 ; implementation actually used shcompact code, we'd need to clobber
1668 ; also r23 and fr23.
1669 (define_insn "udivsi3_i1_media"
1670 [(set (match_operand:SI 0 "register_operand" "=z")
1671 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1672 (clobber (reg:SI T_MEDIA_REG))
1673 (clobber (reg:SI PR_MEDIA_REG))
1674 (clobber (reg:SI R20_REG))
1675 (clobber (reg:SI R21_REG))
1676 (clobber (reg:SI R22_REG))
1677 (clobber (reg:DI TR0_REG))
1678 (clobber (reg:DI TR1_REG))
1679 (clobber (reg:DI TR2_REG))
1680 (use (match_operand 1 "target_reg_operand" "b"))]
1681 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1683 [(set_attr "type" "sfunc")
1684 (set_attr "needs_delay_slot" "yes")])
1686 (define_expand "udivsi3_i4_media"
1688 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1690 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1691 (set (match_dup 5) (float:DF (match_dup 3)))
1692 (set (match_dup 6) (float:DF (match_dup 4)))
1693 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1694 (set (match_dup 8) (fix:DI (match_dup 7)))
1695 (set (match_operand:SI 0 "register_operand" "")
1696 (truncate:SI (match_dup 8)))]
1697 "TARGET_SHMEDIA_FPU"
1700 operands[3] = gen_reg_rtx (DImode);
1701 operands[4] = gen_reg_rtx (DImode);
1702 operands[5] = gen_reg_rtx (DFmode);
1703 operands[6] = gen_reg_rtx (DFmode);
1704 operands[7] = gen_reg_rtx (DFmode);
1705 operands[8] = gen_reg_rtx (DImode);
1708 (define_insn "udivsi3_i4"
1709 [(set (match_operand:SI 0 "register_operand" "=y")
1710 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1711 (clobber (reg:SI T_REG))
1712 (clobber (reg:SI PR_REG))
1713 (clobber (reg:DF DR0_REG))
1714 (clobber (reg:DF DR2_REG))
1715 (clobber (reg:DF DR4_REG))
1716 (clobber (reg:SI R0_REG))
1717 (clobber (reg:SI R1_REG))
1718 (clobber (reg:SI R4_REG))
1719 (clobber (reg:SI R5_REG))
1720 (use (reg:PSI FPSCR_REG))
1721 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1722 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1724 [(set_attr "type" "sfunc")
1725 (set_attr "fp_mode" "double")
1726 (set_attr "needs_delay_slot" "yes")])
1728 (define_insn "udivsi3_i4_single"
1729 [(set (match_operand:SI 0 "register_operand" "=y")
1730 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1731 (clobber (reg:SI T_REG))
1732 (clobber (reg:SI PR_REG))
1733 (clobber (reg:DF DR0_REG))
1734 (clobber (reg:DF DR2_REG))
1735 (clobber (reg:DF DR4_REG))
1736 (clobber (reg:SI R0_REG))
1737 (clobber (reg:SI R1_REG))
1738 (clobber (reg:SI R4_REG))
1739 (clobber (reg:SI R5_REG))
1740 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1741 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1743 [(set_attr "type" "sfunc")
1744 (set_attr "needs_delay_slot" "yes")])
1746 (define_expand "udivsi3"
1747 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1748 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1749 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1750 (parallel [(set (match_operand:SI 0 "register_operand" "")
1751 (udiv:SI (reg:SI R4_REG)
1753 (clobber (reg:SI T_REG))
1754 (clobber (reg:SI PR_REG))
1755 (clobber (reg:SI R4_REG))
1756 (use (match_dup 3))])]
1762 operands[3] = gen_reg_rtx (Pmode);
1763 /* Emit the move of the address to a pseudo outside of the libcall. */
1764 if (TARGET_HARD_SH4 && TARGET_SH2E)
1766 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1767 if (TARGET_FPU_SINGLE)
1768 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1770 last = gen_udivsi3_i4 (operands[0], operands[3]);
1772 else if (TARGET_SHMEDIA_FPU)
1774 operands[1] = force_reg (SImode, operands[1]);
1775 operands[2] = force_reg (SImode, operands[2]);
1776 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1779 else if (TARGET_SH2A)
1781 operands[1] = force_reg (SImode, operands[1]);
1782 operands[2] = force_reg (SImode, operands[2]);
1783 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1786 else if (TARGET_SH5)
1788 function_symbol (operands[3],
1789 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1793 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1794 else if (TARGET_FPU_ANY)
1795 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1797 last = gen_udivsi3_i1 (operands[0], operands[3]);
1801 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1802 last = gen_udivsi3_i1 (operands[0], operands[3]);
1804 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1805 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1806 last = emit_insn (last);
1807 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1808 invariant code motion can move it. */
1809 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1810 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1814 (define_insn "divsi3_sh2a"
1815 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1816 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1817 (match_operand:SI 2 "arith_reg_operand" "z")))]
1820 [(set_attr "type" "arith")
1821 (set_attr "in_delay_slot" "no")])
1823 (define_insn "divsi3_i1"
1824 [(set (match_operand:SI 0 "register_operand" "=z")
1825 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1826 (clobber (reg:SI T_REG))
1827 (clobber (reg:SI PR_REG))
1828 (clobber (reg:SI R1_REG))
1829 (clobber (reg:SI R2_REG))
1830 (clobber (reg:SI R3_REG))
1831 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1832 "TARGET_SH1 && ! TARGET_SH4"
1834 [(set_attr "type" "sfunc")
1835 (set_attr "needs_delay_slot" "yes")])
1837 (define_insn "divsi3_i1_media"
1838 [(set (match_operand:SI 0 "register_operand" "=z")
1839 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1840 (clobber (reg:SI T_MEDIA_REG))
1841 (clobber (reg:SI PR_MEDIA_REG))
1842 (clobber (reg:SI R1_REG))
1843 (clobber (reg:SI R20_REG))
1844 (clobber (reg:SI R21_REG))
1845 (clobber (reg:SI TR0_REG))
1846 (use (match_operand 1 "target_reg_operand" "b"))]
1847 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1849 [(set_attr "type" "sfunc")])
1851 (define_insn "divsi3_media_2"
1852 [(set (match_operand:SI 0 "register_operand" "=z")
1853 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1854 (clobber (reg:SI T_MEDIA_REG))
1855 (clobber (reg:SI PR_MEDIA_REG))
1856 (clobber (reg:SI R1_REG))
1857 (clobber (reg:SI R21_REG))
1858 (clobber (reg:SI TR0_REG))
1859 (use (reg:SI R20_REG))
1860 (use (match_operand 1 "target_reg_operand" "b"))]
1861 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1863 [(set_attr "type" "sfunc")])
1865 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1866 ;; hard reg clobbers and data dependencies that we need when we want
1867 ;; to rematerialize the division into a call.
1868 (define_insn_and_split "divsi_inv_call"
1869 [(set (match_operand:SI 0 "register_operand" "=r")
1870 (div:SI (match_operand:SI 1 "register_operand" "r")
1871 (match_operand:SI 2 "register_operand" "r")))
1872 (clobber (reg:SI R4_REG))
1873 (clobber (reg:SI R5_REG))
1874 (clobber (reg:SI T_MEDIA_REG))
1875 (clobber (reg:SI PR_MEDIA_REG))
1876 (clobber (reg:SI R1_REG))
1877 (clobber (reg:SI R21_REG))
1878 (clobber (reg:SI TR0_REG))
1879 (clobber (reg:SI R20_REG))
1880 (use (match_operand:SI 3 "register_operand" "r"))]
1883 "&& (high_life_started || reload_completed)"
1884 [(set (match_dup 0) (match_dup 3))]
1886 [(set_attr "highpart" "must_split")])
1888 ;; This is the combiner pattern for -mdiv=inv:call .
1889 (define_insn_and_split "*divsi_inv_call_combine"
1890 [(set (match_operand:SI 0 "register_operand" "=z")
1891 (div:SI (match_operand:SI 1 "register_operand" "r")
1892 (match_operand:SI 2 "register_operand" "r")))
1893 (clobber (reg:SI R4_REG))
1894 (clobber (reg:SI R5_REG))
1895 (clobber (reg:SI T_MEDIA_REG))
1896 (clobber (reg:SI PR_MEDIA_REG))
1897 (clobber (reg:SI R1_REG))
1898 (clobber (reg:SI R21_REG))
1899 (clobber (reg:SI TR0_REG))
1900 (clobber (reg:SI R20_REG))
1901 (use (unspec:SI [(match_dup 1)
1902 (match_operand:SI 3 "" "")
1903 (unspec:SI [(match_operand:SI 4 "" "")
1905 (match_operand:DI 5 "" "")]
1907 (match_operand:DI 6 "" "")
1910 UNSPEC_DIV_INV_M3))]
1913 "&& (high_life_started || reload_completed)"
1917 const char *name = sh_divsi3_libfunc;
1918 enum sh_function_kind kind = SFUNC_GOT;
1921 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1922 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1923 while (TARGET_DIVIDE_INV_CALL2)
1925 rtx x = operands[3];
1927 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1929 x = XVECEXP (x, 0, 0);
1930 name = \"__sdivsi3_2\";
1931 kind = SFUNC_STATIC;
1932 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1935 sym = function_symbol (NULL, name, kind);
1936 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1939 [(set_attr "highpart" "must_split")])
1941 (define_expand "divsi3_i4_media"
1942 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1943 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1944 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1945 (set (match_operand:SI 0 "register_operand" "=r")
1946 (fix:SI (match_dup 5)))]
1947 "TARGET_SHMEDIA_FPU"
1950 operands[3] = gen_reg_rtx (DFmode);
1951 operands[4] = gen_reg_rtx (DFmode);
1952 operands[5] = gen_reg_rtx (DFmode);
1955 (define_insn "divsi3_i4"
1956 [(set (match_operand:SI 0 "register_operand" "=y")
1957 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1958 (clobber (reg:SI PR_REG))
1959 (clobber (reg:DF DR0_REG))
1960 (clobber (reg:DF DR2_REG))
1961 (use (reg:PSI FPSCR_REG))
1962 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1963 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1965 [(set_attr "type" "sfunc")
1966 (set_attr "fp_mode" "double")
1967 (set_attr "needs_delay_slot" "yes")])
1969 (define_insn "divsi3_i4_single"
1970 [(set (match_operand:SI 0 "register_operand" "=y")
1971 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1972 (clobber (reg:SI PR_REG))
1973 (clobber (reg:DF DR0_REG))
1974 (clobber (reg:DF DR2_REG))
1975 (clobber (reg:SI R2_REG))
1976 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1977 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1979 [(set_attr "type" "sfunc")
1980 (set_attr "needs_delay_slot" "yes")])
1982 (define_expand "divsi3"
1983 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1984 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1985 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1986 (parallel [(set (match_operand:SI 0 "register_operand" "")
1987 (div:SI (reg:SI R4_REG)
1989 (clobber (reg:SI T_REG))
1990 (clobber (reg:SI PR_REG))
1991 (clobber (reg:SI R1_REG))
1992 (clobber (reg:SI R2_REG))
1993 (clobber (reg:SI R3_REG))
1994 (use (match_dup 3))])]
2000 operands[3] = gen_reg_rtx (Pmode);
2001 /* Emit the move of the address to a pseudo outside of the libcall. */
2002 if (TARGET_HARD_SH4 && TARGET_SH2E)
2004 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2005 if (TARGET_FPU_SINGLE)
2006 last = gen_divsi3_i4_single (operands[0], operands[3]);
2008 last = gen_divsi3_i4 (operands[0], operands[3]);
2010 else if (TARGET_SH2A)
2012 operands[1] = force_reg (SImode, operands[1]);
2013 operands[2] = force_reg (SImode, operands[2]);
2014 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2017 else if (TARGET_DIVIDE_INV)
2019 rtx dividend = operands[1];
2020 rtx divisor = operands[2];
2022 rtx nsb_res = gen_reg_rtx (DImode);
2023 rtx norm64 = gen_reg_rtx (DImode);
2024 rtx tab_ix = gen_reg_rtx (DImode);
2025 rtx norm32 = gen_reg_rtx (SImode);
2026 rtx i92 = force_reg (DImode, GEN_INT (92));
2027 rtx scratch0a = gen_reg_rtx (DImode);
2028 rtx scratch0b = gen_reg_rtx (DImode);
2029 rtx inv0 = gen_reg_rtx (SImode);
2030 rtx scratch1a = gen_reg_rtx (DImode);
2031 rtx scratch1b = gen_reg_rtx (DImode);
2032 rtx shift = gen_reg_rtx (DImode);
2034 rtx inv1 = gen_reg_rtx (SImode);
2035 rtx scratch2a = gen_reg_rtx (DImode);
2036 rtx scratch2b = gen_reg_rtx (SImode);
2037 rtx inv2 = gen_reg_rtx (SImode);
2038 rtx scratch3a = gen_reg_rtx (DImode);
2039 rtx scratch3b = gen_reg_rtx (DImode);
2040 rtx scratch3c = gen_reg_rtx (DImode);
2041 rtx scratch3d = gen_reg_rtx (SImode);
2042 rtx scratch3e = gen_reg_rtx (DImode);
2043 rtx result = gen_reg_rtx (SImode);
2045 if (! arith_reg_or_0_operand (dividend, SImode))
2046 dividend = force_reg (SImode, dividend);
2047 if (! arith_reg_operand (divisor, SImode))
2048 divisor = force_reg (SImode, divisor);
2049 if (flag_pic && Pmode != DImode)
2051 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2052 tab_base = gen_datalabel_ref (tab_base);
2053 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2057 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2058 tab_base = gen_datalabel_ref (tab_base);
2059 tab_base = force_reg (DImode, tab_base);
2061 if (TARGET_DIVIDE_INV20U)
2062 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2064 i2p27 = GEN_INT (0);
2065 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2066 i43 = force_reg (DImode, GEN_INT (43));
2069 emit_insn (gen_nsbdi (nsb_res,
2070 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2071 emit_insn (gen_ashldi3_media (norm64,
2072 gen_rtx_SUBREG (DImode, divisor, 0),
2074 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2075 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2076 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2077 inv0, scratch0a, scratch0b,
2078 scratch1a, scratch1b));
2079 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2080 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2082 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2084 scratch3a, scratch3b, scratch3c,
2085 scratch2a, scratch2b, scratch3d, scratch3e));
2086 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2087 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2088 else if (TARGET_DIVIDE_INV_FP)
2089 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2090 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2091 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2092 gen_reg_rtx (DFmode)));
2094 emit_move_insn (operands[0], result);
2097 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2099 operands[1] = force_reg (SImode, operands[1]);
2100 operands[2] = force_reg (SImode, operands[2]);
2101 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2104 else if (TARGET_SH5)
2106 if (TARGET_DIVIDE_CALL2)
2108 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2109 tab_base = gen_datalabel_ref (tab_base);
2110 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2112 if (TARGET_FPU_ANY && TARGET_SH1)
2113 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2114 else if (TARGET_DIVIDE_CALL2)
2115 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2117 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2120 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2121 (operands[0], operands[3]));
2122 else if (TARGET_FPU_ANY)
2123 last = gen_divsi3_i4_single (operands[0], operands[3]);
2125 last = gen_divsi3_i1 (operands[0], operands[3]);
2129 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2130 last = gen_divsi3_i1 (operands[0], operands[3]);
2132 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2133 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2134 last = emit_insn (last);
2135 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2136 invariant code motion can move it. */
2137 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2138 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2142 ;; operands: inv0, tab_base, tab_ix, norm32
2143 ;; scratch equiv in sdivsi3_2: r19, r21
2144 (define_expand "divsi_inv_m0"
2145 [(set (match_operand:SI 0 "register_operand" "=r")
2146 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2147 (match_operand:DI 2 "register_operand" "r")
2148 (match_operand:SI 3 "register_operand" "r")]
2150 (clobber (match_operand:DI 4 "register_operand" "=r"))
2151 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2159 ldx.ub r20, r21, r19 // u0.8
2161 muls.l r25, r19, r19 // s2.38
2162 ldx.w r20, r21, r21 // s2.14
2163 shari r19, 24, r19 // truncate to s2.14
2164 sub r21, r19, r19 // some 11 bit inverse in s1.14
2167 rtx inv0 = operands[0];
2168 rtx tab_base = operands[1];
2169 rtx tab_ix = operands[2];
2170 rtx norm32 = operands[3];
2171 rtx scratch0 = operands[4];
2172 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2173 rtx scratch1 = operands[5];
2176 mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2177 emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2178 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2179 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2180 mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2181 emit_insn (gen_extendhidi2 (scratch1, mem));
2182 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2183 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2187 ;; operands: inv1, tab_base, tab_ix, norm32
2188 (define_insn_and_split "divsi_inv_m1"
2189 [(set (match_operand:SI 0 "register_operand" "=r")
2190 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2191 (match_operand:DI 2 "register_operand" "r")
2192 (match_operand:SI 3 "register_operand" "r")]
2194 (clobber (match_operand:SI 4 "register_operand" "=r"))
2195 (clobber (match_operand:DI 5 "register_operand" "=r"))
2196 (clobber (match_operand:DI 6 "register_operand" "=r"))
2197 (clobber (match_operand:DI 7 "register_operand" "=r"))
2198 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2206 muls.l r19, r19, r18 // u0.28
2207 muls.l r25, r18, r18 // s2.58
2208 shlli r19, 45, r0 // multiply by two and convert to s2.58
2210 shari r18, 28, r18 // some 18 bit inverse in s1.30
2213 rtx inv1 = operands[0];
2214 rtx tab_base = operands[1];
2215 rtx tab_ix = operands[2];
2216 rtx norm32 = operands[3];
2217 rtx inv0 = operands[4];
2218 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2219 rtx scratch0a = operands[5];
2220 rtx scratch0b = operands[6];
2221 rtx scratch0 = operands[7];
2222 rtx scratch1 = operands[8];
2223 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2225 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2226 scratch0a, scratch0b));
2227 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2228 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2229 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2230 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2231 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2235 ;; operands: inv2, norm32, inv1, i92
2236 (define_insn_and_split "divsi_inv_m2"
2237 [(set (match_operand:SI 0 "register_operand" "=r")
2238 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2239 (match_operand:SI 2 "register_operand" "r")
2240 (match_operand:DI 3 "register_operand" "r")]
2242 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2250 muls.l r18, r25, r0 // s2.60
2251 shari r0, 16, r0 // s-16.44
2253 muls.l r0, r18, r19 // s-16.74
2254 shari r19, 30, r19 // s-16.44
2256 rtx inv2 = operands[0];
2257 rtx norm32 = operands[1];
2258 rtx inv1 = operands[2];
2259 rtx i92 = operands[3];
2260 rtx scratch0 = operands[4];
2261 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2263 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2264 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2265 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2266 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2267 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2271 (define_insn_and_split "divsi_inv_m3"
2272 [(set (match_operand:SI 0 "register_operand" "=r")
2273 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2274 (match_operand:SI 2 "register_operand" "r")
2275 (match_operand:SI 3 "register_operand" "r")
2276 (match_operand:DI 4 "register_operand" "r")
2277 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2278 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2280 (clobber (match_operand:DI 7 "register_operand" "=r"))
2281 (clobber (match_operand:DI 8 "register_operand" "=r"))
2282 (clobber (match_operand:DI 9 "register_operand" "=r"))
2283 (clobber (match_operand:DI 10 "register_operand" "=r"))
2284 (clobber (match_operand:SI 11 "register_operand" "=r"))
2285 (clobber (match_operand:SI 12 "register_operand" "=r"))
2286 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2294 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2295 r0: scratch0 r19: scratch1 r21: scratch2
2297 muls.l r18, r4, r25 // s32.30
2298 muls.l r19, r4, r19 // s15.30
2300 shari r19, 14, r19 // s18.-14
2306 rtx result = operands[0];
2307 rtx dividend = operands[1];
2308 rtx inv1 = operands[2];
2309 rtx inv2 = operands[3];
2310 rtx shift = operands[4];
2311 rtx scratch0 = operands[7];
2312 rtx scratch1 = operands[8];
2313 rtx scratch2 = operands[9];
2315 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2316 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2317 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2318 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2319 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2320 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2321 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2325 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2326 ;; inv1: tab_base, tab_ix, norm32
2327 ;; inv2: norm32, inv1, i92
2328 (define_insn_and_split "divsi_inv_m1_3"
2329 [(set (match_operand:SI 0 "register_operand" "=r")
2330 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2331 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2332 (match_operand:DI 3 "register_operand" "r")
2333 (match_operand:SI 4 "register_operand" "r")]
2335 (unspec:SI [(match_dup 4)
2336 (unspec:SI [(match_dup 2)
2338 (match_dup 4)] UNSPEC_DIV_INV_M1)
2339 (match_operand:SI 5 "" "")]
2341 (match_operand:DI 6 "register_operand" "r")
2342 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2343 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2345 (clobber (match_operand:DI 9 "register_operand" "=r"))
2346 (clobber (match_operand:DI 10 "register_operand" "=r"))
2347 (clobber (match_operand:DI 11 "register_operand" "=r"))
2348 (clobber (match_operand:DI 12 "register_operand" "=r"))
2349 (clobber (match_operand:SI 13 "register_operand" "=r"))
2350 (clobber (match_operand:SI 14 "register_operand" "=r"))
2351 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2353 && (TARGET_DIVIDE_INV_MINLAT
2354 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2360 rtx result = operands[0];
2361 rtx dividend = operands[1];
2362 rtx tab_base = operands[2];
2363 rtx tab_ix = operands[3];
2364 rtx norm32 = operands[4];
2365 /* rtx i92 = operands[5]; */
2366 rtx shift = operands[6];
2367 rtx i2p27 = operands[7];
2368 rtx i43 = operands[8];
2369 rtx scratch0 = operands[9];
2370 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2371 rtx scratch1 = operands[10];
2372 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2373 rtx scratch2 = operands[11];
2374 rtx scratch3 = operands[12];
2375 rtx scratch4 = operands[13];
2376 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2377 rtx scratch5 = operands[14];
2378 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2379 rtx scratch6 = operands[15];
2381 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2382 scratch0, scratch1));
2383 /* inv0 == scratch4 */
2384 if (! TARGET_DIVIDE_INV20U)
2386 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2388 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2392 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2393 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2395 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2396 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2397 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2398 /* inv1 == scratch4 */
2400 if (TARGET_DIVIDE_INV_MINLAT)
2402 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2403 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2404 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2405 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2406 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2407 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2408 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2409 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2410 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2411 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2412 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2416 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2417 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2418 emit_insn (gen_nsbdi (scratch6,
2419 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2420 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2421 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2422 emit_insn (gen_divsi_inv20 (scratch2,
2423 norm32, scratch4, dividend,
2424 scratch6, scratch3, i43,
2425 /* scratch0 may be shared with i2p27. */
2426 scratch0, scratch1, scratch5,
2427 label, label, i2p27));
2429 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2430 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2434 (define_insn "divsi_inv20"
2435 [(set (match_operand:DI 0 "register_operand" "=&r")
2436 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2437 (match_operand:SI 2 "register_operand" "r")
2438 (match_operand:SI 3 "register_operand" "r")
2439 (match_operand:DI 4 "register_operand" "r")
2440 (match_operand:DI 5 "register_operand" "r")
2441 (match_operand:DI 6 "register_operand" "r")
2442 (match_operand:DI 12 "register_operand" "r")
2443 (match_operand 10 "target_operand" "b")
2444 (match_operand 11 "immediate_operand" "i")]
2446 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2447 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2448 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2450 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2453 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2454 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2455 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2456 %10 label (tr), %11 label (imm)
2458 muls.l inv1, norm32, scratch0 // s2.60
2459 muls.l inv1, dividend, result // s32.30
2460 xor i2p27, result_sign, round_scratch
2461 bge/u dividend_nsb, i43, tr.. (label)
2462 shari scratch0, 16, scratch0 // s-16.44
2463 muls.l sratch0_si, inv1, scratch0 // s-16.74
2464 sub result, round_scratch, result
2465 shari dividend, 14, scratch1 // s19.-14
2466 shari scratch0, 30, scratch0 // s-16.44
2467 muls.l scratch0, scratch1, round_scratch // s15.30
2469 sub result, round_scratch, result */
2471 int likely = TARGET_DIVIDE_INV20L;
2473 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2474 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2475 output_asm_insn (likely
2476 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2477 : \"bge/u\t%4, %6, %10\", operands);
2478 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2479 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2480 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2482 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2483 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2486 (define_insn_and_split "divsi_inv_fp"
2487 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2488 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2489 (match_operand:SI 2 "register_operand" "rf")))
2490 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2491 (clobber (match_operand:SI 4 "register_operand" "=r"))
2492 (clobber (match_operand:SI 5 "register_operand" "=r"))
2493 (clobber (match_operand:DF 6 "register_operand" "=r"))
2494 (clobber (match_operand:DF 7 "register_operand" "=r"))
2495 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2496 "TARGET_SHMEDIA_FPU"
2498 "&& (high_life_started || reload_completed)"
2499 [(set (match_dup 0) (match_dup 3))]
2501 [(set_attr "highpart" "must_split")])
2503 ;; If a matching group of divide-by-inverse instructions is in the same
2504 ;; basic block after gcse & loop optimizations, we want to transform them
2505 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2506 (define_insn_and_split "*divsi_inv_fp_combine"
2507 [(set (match_operand:SI 0 "register_operand" "=f")
2508 (div:SI (match_operand:SI 1 "register_operand" "f")
2509 (match_operand:SI 2 "register_operand" "f")))
2510 (use (unspec:SI [(match_dup 1)
2511 (match_operand:SI 3 "" "")
2512 (unspec:SI [(match_operand:SI 4 "" "")
2514 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2515 (match_operand:DI 6 "" "")
2517 (const_int 0)] UNSPEC_DIV_INV_M3))
2518 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2519 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2520 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2521 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2522 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2523 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2526 [(set (match_dup 9) (float:DF (match_dup 1)))
2527 (set (match_dup 10) (float:DF (match_dup 2)))
2528 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2530 (fix:SI (match_dup 11)))
2531 (set (match_dup 0) (match_dup 8))]
2534 if (! fp_arith_reg_operand (operands[1], SImode))
2536 emit_move_insn (operands[7], operands[1]);
2537 operands[1] = operands[7];
2539 if (! fp_arith_reg_operand (operands[2], SImode))
2541 emit_move_insn (operands[8], operands[2]);
2542 operands[2] = operands[8];
2545 [(set_attr "highpart" "must_split")])
2547 ;; -------------------------------------------------------------------------
2548 ;; Multiplication instructions
2549 ;; -------------------------------------------------------------------------
2551 (define_insn "umulhisi3_i"
2552 [(set (reg:SI MACL_REG)
2553 (mult:SI (zero_extend:SI
2554 (match_operand:HI 0 "arith_reg_operand" "r"))
2556 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2559 [(set_attr "type" "smpy")])
2561 (define_insn "mulhisi3_i"
2562 [(set (reg:SI MACL_REG)
2563 (mult:SI (sign_extend:SI
2564 (match_operand:HI 0 "arith_reg_operand" "r"))
2566 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2569 [(set_attr "type" "smpy")])
2571 (define_expand "mulhisi3"
2572 [(set (reg:SI MACL_REG)
2573 (mult:SI (sign_extend:SI
2574 (match_operand:HI 1 "arith_reg_operand" ""))
2576 (match_operand:HI 2 "arith_reg_operand" ""))))
2577 (set (match_operand:SI 0 "arith_reg_operand" "")
2584 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2585 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2586 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2587 invariant code motion can move it. */
2588 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2589 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2590 /* expand_binop can't find a suitable code in umul_widen_optab to
2591 make a REG_EQUAL note from, so make one here.
2592 See also smulsi3_highpart.
2593 ??? Alternatively, we could put this at the calling site of expand_binop,
2594 i.e. expand_expr. */
2596 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2601 (define_expand "umulhisi3"
2602 [(set (reg:SI MACL_REG)
2603 (mult:SI (zero_extend:SI
2604 (match_operand:HI 1 "arith_reg_operand" ""))
2606 (match_operand:HI 2 "arith_reg_operand" ""))))
2607 (set (match_operand:SI 0 "arith_reg_operand" "")
2614 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2615 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2616 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2617 invariant code motion can move it. */
2618 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2619 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2620 /* expand_binop can't find a suitable code in umul_widen_optab to
2621 make a REG_EQUAL note from, so make one here.
2622 See also smulsi3_highpart.
2623 ??? Alternatively, we could put this at the calling site of expand_binop,
2624 i.e. expand_expr. */
2626 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2631 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2632 ;; a call to a routine which clobbers known registers.
2635 [(set (match_operand:SI 1 "register_operand" "=z")
2636 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2637 (clobber (reg:SI MACL_REG))
2638 (clobber (reg:SI T_REG))
2639 (clobber (reg:SI PR_REG))
2640 (clobber (reg:SI R3_REG))
2641 (clobber (reg:SI R2_REG))
2642 (clobber (reg:SI R1_REG))
2643 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2646 [(set_attr "type" "sfunc")
2647 (set_attr "needs_delay_slot" "yes")])
2649 (define_expand "mulsi3_call"
2650 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2651 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2652 (parallel[(set (match_operand:SI 0 "register_operand" "")
2653 (mult:SI (reg:SI R4_REG)
2655 (clobber (reg:SI MACL_REG))
2656 (clobber (reg:SI T_REG))
2657 (clobber (reg:SI PR_REG))
2658 (clobber (reg:SI R3_REG))
2659 (clobber (reg:SI R2_REG))
2660 (clobber (reg:SI R1_REG))
2661 (use (match_operand:SI 3 "register_operand" ""))])]
2665 (define_insn "mul_r"
2666 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2667 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2668 (match_operand:SI 2 "arith_reg_operand" "z")))]
2671 [(set_attr "type" "dmpy")])
2673 (define_insn "mul_l"
2674 [(set (reg:SI MACL_REG)
2675 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2676 (match_operand:SI 1 "arith_reg_operand" "r")))]
2679 [(set_attr "type" "dmpy")])
2681 (define_expand "mulsi3"
2682 [(set (reg:SI MACL_REG)
2683 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2684 (match_operand:SI 2 "arith_reg_operand" "")))
2685 (set (match_operand:SI 0 "arith_reg_operand" "")
2694 /* The address must be set outside the libcall,
2695 since it goes into a pseudo. */
2696 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2697 rtx addr = force_reg (SImode, sym);
2698 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2701 last = emit_insn (insns);
2705 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2707 first = emit_insn (gen_mul_l (operands[1], operands[2]));
2708 /* consec_sets_giv can only recognize the first insn that sets a
2709 giv as the giv insn. So we must tag this also with a REG_EQUAL
2711 last = emit_insn (gen_movsi_i ((operands[0]), macl));
2713 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2714 invariant code motion can move it. */
2715 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2716 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2720 (define_insn "mulsidi3_i"
2721 [(set (reg:SI MACH_REG)
2725 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2726 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2728 (set (reg:SI MACL_REG)
2729 (mult:SI (match_dup 0)
2733 [(set_attr "type" "dmpy")])
2735 (define_expand "mulsidi3"
2736 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2737 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2738 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2739 "TARGET_SH2 || TARGET_SHMEDIA"
2744 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2750 (define_insn "mulsidi3_media"
2751 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2752 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2753 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2756 [(set_attr "type" "dmpy_media")
2757 (set_attr "highpart" "ignore")])
2759 (define_insn "mulsidi3_compact"
2760 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2762 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2763 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2764 (clobber (reg:SI MACH_REG))
2765 (clobber (reg:SI MACL_REG))]
2770 [(set (match_operand:DI 0 "arith_reg_dest" "")
2772 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2773 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2774 (clobber (reg:SI MACH_REG))
2775 (clobber (reg:SI MACL_REG))]
2780 rtx low_dst = gen_lowpart (SImode, operands[0]);
2781 rtx high_dst = gen_highpart (SImode, operands[0]);
2783 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2785 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2786 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2787 /* We need something to tag the possible REG_EQUAL notes on to. */
2788 emit_move_insn (operands[0], operands[0]);
2792 (define_insn "umulsidi3_i"
2793 [(set (reg:SI MACH_REG)
2797 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2798 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2800 (set (reg:SI MACL_REG)
2801 (mult:SI (match_dup 0)
2805 [(set_attr "type" "dmpy")])
2807 (define_expand "umulsidi3"
2808 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2809 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2810 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2811 "TARGET_SH2 || TARGET_SHMEDIA"
2816 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2822 (define_insn "umulsidi3_media"
2823 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2824 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2825 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2828 [(set_attr "type" "dmpy_media")
2829 (set_attr "highpart" "ignore")])
2831 (define_insn "umulsidi3_compact"
2832 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2834 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2835 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2836 (clobber (reg:SI MACH_REG))
2837 (clobber (reg:SI MACL_REG))]
2842 [(set (match_operand:DI 0 "arith_reg_dest" "")
2843 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2844 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2845 (clobber (reg:SI MACH_REG))
2846 (clobber (reg:SI MACL_REG))]
2851 rtx low_dst = gen_lowpart (SImode, operands[0]);
2852 rtx high_dst = gen_highpart (SImode, operands[0]);
2854 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2856 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2857 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2858 /* We need something to tag the possible REG_EQUAL notes on to. */
2859 emit_move_insn (operands[0], operands[0]);
2863 (define_insn "smulsi3_highpart_i"
2864 [(set (reg:SI MACH_REG)
2868 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2869 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2871 (clobber (reg:SI MACL_REG))]
2874 [(set_attr "type" "dmpy")])
2876 (define_expand "smulsi3_highpart"
2878 [(set (reg:SI MACH_REG)
2882 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2883 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2885 (clobber (reg:SI MACL_REG))])
2886 (set (match_operand:SI 0 "arith_reg_operand" "")
2893 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2894 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2895 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2896 invariant code motion can move it. */
2897 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2898 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2899 /* expand_binop can't find a suitable code in mul_highpart_optab to
2900 make a REG_EQUAL note from, so make one here.
2901 See also {,u}mulhisi.
2902 ??? Alternatively, we could put this at the calling site of expand_binop,
2903 i.e. expand_mult_highpart. */
2905 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2910 (define_insn "umulsi3_highpart_i"
2911 [(set (reg:SI MACH_REG)
2915 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2916 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2918 (clobber (reg:SI MACL_REG))]
2921 [(set_attr "type" "dmpy")])
2923 (define_expand "umulsi3_highpart"
2925 [(set (reg:SI MACH_REG)
2929 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2930 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2932 (clobber (reg:SI MACL_REG))])
2933 (set (match_operand:SI 0 "arith_reg_operand" "")
2940 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2941 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2942 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2943 invariant code motion can move it. */
2944 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2945 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2949 (define_insn_and_split "muldi3"
2950 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2951 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2952 (match_operand:DI 2 "arith_reg_operand" "r")))
2953 (clobber (match_scratch:DI 3 "=&r"))
2954 (clobber (match_scratch:DI 4 "=r"))]
2961 rtx op3_v2si, op2_v2si;
2963 op3_v2si = operands[3];
2964 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2966 op3_v2si = XEXP (op3_v2si, 0);
2967 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2969 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2970 op2_v2si = operands[2];
2971 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2973 op2_v2si = XEXP (op2_v2si, 0);
2974 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2976 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2977 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2978 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2979 emit_insn (gen_umulsidi3_media (operands[4],
2980 sh_gen_truncate (SImode, operands[1], 0),
2981 sh_gen_truncate (SImode, operands[2], 0)));
2982 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2983 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2984 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2985 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2990 ;; -------------------------------------------------------------------------
2991 ;; Logical operations
2992 ;; -------------------------------------------------------------------------
2994 (define_insn "*andsi3_compact"
2995 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2996 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2997 (match_operand:SI 2 "logical_operand" "r,K08")))]
3000 [(set_attr "type" "arith")])
3002 (define_insn "*andsi3_media"
3003 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3004 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3005 (match_operand:SI 2 "logical_operand" "r,I10")))]
3010 [(set_attr "type" "arith_media")])
3012 ;; If the constant is 255, then emit an extu.b instruction instead of an
3013 ;; and, since that will give better code.
3015 (define_expand "andsi3"
3016 [(set (match_operand:SI 0 "arith_reg_operand" "")
3017 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3018 (match_operand:SI 2 "logical_operand" "")))]
3023 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255
3024 && (GET_CODE (operands[1]) != SUBREG
3025 || SCALAR_INT_MODE_P (GET_MODE (XEXP (operands[1], 0)))))
3027 emit_insn (gen_zero_extendqisi2 (operands[0],
3028 gen_lowpart (QImode, operands[1])));
3033 (define_insn_and_split "anddi3"
3034 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3035 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3036 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3043 && ! logical_operand (operands[2], DImode)"
3047 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3048 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3050 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3053 [(set_attr "type" "arith_media")])
3055 (define_insn "andcsi3"
3056 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3057 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3058 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3061 [(set_attr "type" "arith_media")])
3063 (define_insn "andcdi3"
3064 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3065 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3066 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3069 [(set_attr "type" "arith_media")])
3071 (define_expand "iorsi3"
3072 [(set (match_operand:SI 0 "arith_reg_operand" "")
3073 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3074 (match_operand:SI 2 "logical_operand" "")))]
3078 (define_insn "*iorsi3_compact"
3079 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3080 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3081 (match_operand:SI 2 "logical_operand" "r,K08")))]
3084 [(set_attr "type" "arith")])
3086 (define_insn "*iorsi3_media"
3087 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3088 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3089 (match_operand:SI 2 "logical_operand" "r,I10")))]
3094 [(set_attr "type" "arith_media")])
3096 (define_insn "iordi3"
3097 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3098 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3099 (match_operand:DI 2 "logical_operand" "r,I10")))]
3104 [(set_attr "type" "arith_media")])
3106 (define_insn_and_split "*logical_sidi3"
3107 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3108 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3109 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3110 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3113 "&& reload_completed"
3114 [(set (match_dup 0) (match_dup 3))]
3118 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3119 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3120 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3123 (define_insn_and_split "*logical_sidisi3"
3124 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3125 (truncate:SI (sign_extend:DI
3126 (match_operator:SI 3 "logical_operator"
3127 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3128 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3132 [(set (match_dup 0) (match_dup 3))])
3134 (define_insn_and_split "*logical_sidi3_2"
3135 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3136 (sign_extend:DI (truncate:SI (sign_extend:DI
3137 (match_operator:SI 3 "logical_operator"
3138 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3139 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3143 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3145 (define_expand "xorsi3"
3146 [(set (match_operand:SI 0 "arith_reg_operand" "")
3147 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3148 (match_operand:SI 2 "xor_operand" "")))]
3152 (define_insn "*xorsi3_compact"
3153 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3154 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3155 (match_operand:SI 2 "logical_operand" "K08,r")))]
3158 [(set_attr "type" "arith")])
3160 (define_insn "*xorsi3_media"
3161 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3162 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3163 (match_operand:SI 2 "xor_operand" "r,I06")))]
3168 [(set_attr "type" "arith_media")])
3170 (define_insn "xordi3"
3171 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3172 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3173 (match_operand:DI 2 "xor_operand" "r,I06")))]
3178 [(set_attr "type" "arith_media")])
3180 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3181 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3183 [(set (match_operand:DI 0 "arith_reg_dest" "")
3184 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3185 [(match_operand 1 "any_register_operand" "")
3186 (match_operand 2 "any_register_operand" "")])))]
3188 [(set (match_dup 5) (match_dup 4))
3189 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3192 enum machine_mode inmode = GET_MODE (operands[1]);
3195 if (GET_CODE (operands[0]) == SUBREG)
3197 offset = SUBREG_BYTE (operands[0]);
3198 operands[0] = SUBREG_REG (operands[0]);
3200 gcc_assert (GET_CODE (operands[0]) == REG);
3201 if (! TARGET_LITTLE_ENDIAN)
3202 offset += 8 - GET_MODE_SIZE (inmode);
3203 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3206 ;; -------------------------------------------------------------------------
3207 ;; Shifts and rotates
3208 ;; -------------------------------------------------------------------------
3210 (define_expand "rotldi3"
3211 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3212 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3213 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3215 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3217 (define_insn "rotldi3_mextr"
3218 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3219 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3220 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3224 static char templ[16];
3226 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3227 8 - (int) (INTVAL (operands[2]) >> 3));
3230 [(set_attr "type" "arith_media")])
3232 (define_expand "rotrdi3"
3233 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3234 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3235 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3237 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3239 (define_insn "rotrdi3_mextr"
3240 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3241 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3242 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3246 static char templ[16];
3248 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3251 [(set_attr "type" "arith_media")])
3254 [(set (match_operand:DI 0 "arith_reg_dest" "")
3255 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3256 "ua_address_operand" "")))
3257 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3259 (clobber (match_operand:DI 3 "register_operand" ""))]
3261 [(match_dup 4) (match_dup 5)]
3264 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3265 (operands[3], operands[1]));
3266 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3267 GEN_INT (56), GEN_INT (8));
3270 (define_insn "rotlsi3_1"
3271 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3272 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3275 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3278 [(set_attr "type" "arith")])
3280 (define_insn "rotlsi3_31"
3281 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3282 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3284 (clobber (reg:SI T_REG))]
3287 [(set_attr "type" "arith")])
3289 (define_insn "rotlsi3_16"
3290 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3291 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3295 [(set_attr "type" "arith")])
3297 (define_expand "rotlsi3"
3298 [(set (match_operand:SI 0 "arith_reg_dest" "")
3299 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3300 (match_operand:SI 2 "immediate_operand" "")))]
3304 static const char rot_tab[] = {
3305 000, 000, 000, 000, 000, 000, 010, 001,
3306 001, 001, 011, 013, 003, 003, 003, 003,
3307 003, 003, 003, 003, 003, 013, 012, 002,
3308 002, 002, 010, 000, 000, 000, 000, 000,
3313 if (GET_CODE (operands[2]) != CONST_INT)
3315 count = INTVAL (operands[2]);
3316 choice = rot_tab[count];
3317 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3323 emit_move_insn (operands[0], operands[1]);
3324 count -= (count & 16) * 2;
3327 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3334 parts[0] = gen_reg_rtx (SImode);
3335 parts[1] = gen_reg_rtx (SImode);
3336 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3337 emit_move_insn (parts[choice-1], operands[1]);
3338 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3339 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3340 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3341 count = (count & ~16) - 8;
3345 for (; count > 0; count--)
3346 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3347 for (; count < 0; count++)
3348 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3353 (define_insn "*rotlhi3_8"
3354 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3355 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3359 [(set_attr "type" "arith")])
3361 (define_expand "rotlhi3"
3362 [(set (match_operand:HI 0 "arith_reg_operand" "")
3363 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3364 (match_operand:HI 2 "immediate_operand" "")))]
3368 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3375 (define_insn "ashlsi3_sh2a"
3376 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3377 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3378 (match_operand:SI 2 "arith_reg_operand" "r")))]
3381 [(set_attr "type" "arith")
3382 (set_attr "length" "4")])
3384 ;; This pattern is used by init_expmed for computing the costs of shift
3387 (define_insn_and_split "ashlsi3_std"
3388 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3389 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3390 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3391 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3393 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3394 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3402 && GET_CODE (operands[2]) == CONST_INT
3403 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3404 [(set (match_dup 3) (match_dup 2))
3406 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3407 (clobber (match_dup 4))])]
3408 "operands[4] = gen_rtx_SCRATCH (SImode);"
3409 [(set_attr "length" "*,*,*,4")
3410 (set_attr "type" "dyn_shift,arith,arith,arith")])
3412 (define_insn "ashlhi3_k"
3413 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3414 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3415 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3416 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3420 [(set_attr "type" "arith")])
3422 (define_insn "ashlsi3_n"
3423 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3424 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3425 (match_operand:SI 2 "const_int_operand" "n")))
3426 (clobber (reg:SI T_REG))]
3427 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3429 [(set (attr "length")
3430 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3432 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3434 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3436 (const_string "8")))
3437 (set_attr "type" "arith")])
3440 [(set (match_operand:SI 0 "arith_reg_dest" "")
3441 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3442 (match_operand:SI 2 "const_int_operand" "")))
3443 (clobber (reg:SI T_REG))]
3444 "TARGET_SH1 && reload_completed"
3445 [(use (reg:SI R0_REG))]
3448 gen_shifty_op (ASHIFT, operands);
3452 (define_insn "ashlsi3_media"
3453 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3454 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3455 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3460 [(set_attr "type" "arith_media")
3461 (set_attr "highpart" "ignore")])
3463 (define_expand "ashlsi3"
3464 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3465 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3466 (match_operand:SI 2 "nonmemory_operand" "")))
3467 (clobber (reg:SI T_REG))])]
3473 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3476 if (GET_CODE (operands[2]) == CONST_INT
3477 && sh_dynamicalize_shift_p (operands[2]))
3478 operands[2] = force_reg (SImode, operands[2]);
3481 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3484 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3488 (define_insn "*ashlhi3_n"
3489 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3490 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3491 (match_operand:HI 2 "const_int_operand" "n")))
3492 (clobber (reg:SI T_REG))]
3495 [(set (attr "length")
3496 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3498 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3500 (const_string "6")))
3501 (set_attr "type" "arith")])
3503 (define_expand "ashlhi3"
3504 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3505 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3506 (match_operand:SI 2 "nonmemory_operand" "")))
3507 (clobber (reg:SI T_REG))])]
3511 if (GET_CODE (operands[2]) != CONST_INT)
3513 /* It may be possible to call gen_ashlhi3 directly with more generic
3514 operands. Make sure operands[1] is a HImode register here. */
3515 if (!arith_reg_operand (operands[1], HImode))
3516 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3520 [(set (match_operand:HI 0 "arith_reg_dest" "")
3521 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3522 (match_operand:HI 2 "const_int_operand" "")))
3523 (clobber (reg:SI T_REG))]
3524 "TARGET_SH1 && reload_completed"
3525 [(use (reg:SI R0_REG))]
3528 gen_shifty_hi_op (ASHIFT, operands);
3533 ; arithmetic shift right
3536 (define_insn "ashrsi3_sh2a"
3537 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3538 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3539 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3542 [(set_attr "type" "dyn_shift")
3543 (set_attr "length" "4")])
3545 (define_insn "ashrsi3_k"
3546 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3547 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3548 (match_operand:SI 2 "const_int_operand" "M")))
3549 (clobber (reg:SI T_REG))]
3550 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3552 [(set_attr "type" "arith")])
3554 ;; We can't do HImode right shifts correctly unless we start out with an
3555 ;; explicit zero / sign extension; doing that would result in worse overall
3556 ;; code, so just let the machine independent code widen the mode.
3557 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3560 ;; ??? This should be a define expand.
3562 (define_insn "ashrsi2_16"
3563 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3564 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3568 [(set_attr "length" "4")])
3571 [(set (match_operand:SI 0 "arith_reg_dest" "")
3572 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3575 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3576 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3577 "operands[2] = gen_lowpart (HImode, operands[0]);")
3579 ;; ??? This should be a define expand.
3581 (define_insn "ashrsi2_31"
3582 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3583 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3585 (clobber (reg:SI T_REG))]
3588 [(set_attr "length" "4")])
3591 [(set (match_operand:SI 0 "arith_reg_dest" "")
3592 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3594 (clobber (reg:SI T_REG))]
3599 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3600 emit_insn (gen_mov_neg_si_t (operands[0]));
3605 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3607 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3609 && peep2_reg_dead_p (2, operands[0])
3610 && peep2_reg_dead_p (2, operands[1])"
3614 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3618 (define_insn "ashlsi_c"
3619 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3620 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3622 (lt:SI (match_dup 1) (const_int 0)))]
3625 [(set_attr "type" "arith")])
3627 (define_insn "*ashlsi_c_void"
3628 [(set (reg:SI T_REG)
3629 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3630 (clobber (match_scratch:SI 1 "=0"))]
3631 "TARGET_SH1 && cse_not_expected"
3633 [(set_attr "type" "arith")])
3635 (define_insn "ashrsi3_d"
3636 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3637 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3638 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3641 [(set_attr "type" "dyn_shift")])
3643 (define_insn "ashrsi3_n"
3644 [(set (reg:SI R4_REG)
3645 (ashiftrt:SI (reg:SI R4_REG)
3646 (match_operand:SI 0 "const_int_operand" "i")))
3647 (clobber (reg:SI T_REG))
3648 (clobber (reg:SI PR_REG))
3649 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3652 [(set_attr "type" "sfunc")
3653 (set_attr "needs_delay_slot" "yes")])
3655 (define_insn "ashrsi3_media"
3656 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3657 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3658 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3663 [(set_attr "type" "arith_media")
3664 (set_attr "highpart" "ignore")])
3666 (define_expand "ashrsi3"
3667 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3668 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3669 (match_operand:SI 2 "nonmemory_operand" "")))
3670 (clobber (reg:SI T_REG))])]
3676 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3679 if (expand_ashiftrt (operands))
3685 ;; logical shift right
3687 (define_insn "lshrsi3_sh2a"
3688 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3689 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3690 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3693 [(set_attr "type" "dyn_shift")
3694 (set_attr "length" "4")])
3696 (define_insn "lshrsi3_d"
3697 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3698 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3699 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3702 [(set_attr "type" "dyn_shift")])
3704 ;; Only the single bit shift clobbers the T bit.
3706 (define_insn "lshrsi3_m"
3707 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3708 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3709 (match_operand:SI 2 "const_int_operand" "M")))
3710 (clobber (reg:SI T_REG))]
3711 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3713 [(set_attr "type" "arith")])
3715 (define_insn "lshrsi3_k"
3716 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3717 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3718 (match_operand:SI 2 "const_int_operand" "P27")))]
3719 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3720 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3722 [(set_attr "type" "arith")])
3724 (define_insn "lshrsi3_n"
3725 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3726 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3727 (match_operand:SI 2 "const_int_operand" "n")))
3728 (clobber (reg:SI T_REG))]
3729 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3731 [(set (attr "length")
3732 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3734 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3736 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3738 (const_string "8")))
3739 (set_attr "type" "arith")])
3742 [(set (match_operand:SI 0 "arith_reg_dest" "")
3743 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3744 (match_operand:SI 2 "const_int_operand" "")))
3745 (clobber (reg:SI T_REG))]
3746 "TARGET_SH1 && reload_completed"
3747 [(use (reg:SI R0_REG))]
3750 gen_shifty_op (LSHIFTRT, operands);
3754 (define_insn "lshrsi3_media"
3755 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3756 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3757 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3762 [(set_attr "type" "arith_media")
3763 (set_attr "highpart" "ignore")])
3765 (define_expand "lshrsi3"
3766 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3767 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3768 (match_operand:SI 2 "nonmemory_operand" "")))
3769 (clobber (reg:SI T_REG))])]
3775 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3778 if (GET_CODE (operands[2]) == CONST_INT
3779 && sh_dynamicalize_shift_p (operands[2]))
3780 operands[2] = force_reg (SImode, operands[2]);
3781 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3783 rtx count = copy_to_mode_reg (SImode, operands[2]);
3784 emit_insn (gen_negsi2 (count, count));
3785 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3788 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3792 ;; ??? This should be a define expand.
3794 (define_insn "ashldi3_k"
3795 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3796 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3798 (clobber (reg:SI T_REG))]
3800 "shll %R0\;rotcl %S0"
3801 [(set_attr "length" "4")
3802 (set_attr "type" "arith")])
3804 (define_insn "ashldi3_media"
3805 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3806 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3807 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3812 [(set_attr "type" "arith_media")])
3814 (define_insn "*ashldisi3_media"
3815 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3816 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3817 (match_operand:DI 2 "const_int_operand" "n")))]
3818 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3819 "shlli.l %1, %2, %0"
3820 [(set_attr "type" "arith_media")
3821 (set_attr "highpart" "ignore")])
3823 (define_expand "ashldi3"
3824 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3825 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3826 (match_operand:DI 2 "immediate_operand" "")))
3827 (clobber (reg:SI T_REG))])]
3833 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3836 if (GET_CODE (operands[2]) != CONST_INT
3837 || INTVAL (operands[2]) != 1)
3841 ;; ??? This should be a define expand.
3843 (define_insn "lshrdi3_k"
3844 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3845 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3847 (clobber (reg:SI T_REG))]
3849 "shlr %S0\;rotcr %R0"
3850 [(set_attr "length" "4")
3851 (set_attr "type" "arith")])
3853 (define_insn "lshrdi3_media"
3854 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3855 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3856 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3858 && (arith_reg_dest (operands[0], DImode)
3859 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3863 [(set_attr "type" "arith_media")])
3865 (define_insn "*lshrdisi3_media"
3866 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3867 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3868 (match_operand:DI 2 "const_int_operand" "n")))]
3869 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3870 "shlri.l %1, %2, %0"
3871 [(set_attr "type" "arith_media")
3872 (set_attr "highpart" "ignore")])
3874 (define_expand "lshrdi3"
3875 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3876 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3877 (match_operand:DI 2 "immediate_operand" "")))
3878 (clobber (reg:SI T_REG))])]
3884 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3887 if (GET_CODE (operands[2]) != CONST_INT
3888 || INTVAL (operands[2]) != 1)
3892 ;; ??? This should be a define expand.
3894 (define_insn "ashrdi3_k"
3895 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3896 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3898 (clobber (reg:SI T_REG))]
3900 "shar %S0\;rotcr %R0"
3901 [(set_attr "length" "4")
3902 (set_attr "type" "arith")])
3904 (define_insn "ashrdi3_media"
3905 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3906 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3907 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3909 && (arith_reg_dest (operands[0], DImode)
3910 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3914 [(set_attr "type" "arith_media")])
3916 (define_insn "*ashrdisi3_media"
3917 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3918 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3919 (match_operand:DI 2 "const_int_operand" "n")))]
3920 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3921 "shari.l %1, %2, %0"
3922 [(set_attr "type" "arith_media")
3923 (set_attr "highpart" "ignore")])
3925 (define_insn "ashrdisi3_media_high"
3926 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3928 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3929 (match_operand:DI 2 "const_int_operand" "n"))))]
3930 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3932 [(set_attr "type" "arith_media")])
3934 (define_insn "ashrdisi3_media_opaque"
3935 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3936 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3937 (match_operand:DI 2 "const_int_operand" "n")]
3941 [(set_attr "type" "arith_media")])
3943 (define_expand "ashrdi3"
3944 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3945 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3946 (match_operand:DI 2 "immediate_operand" "")))
3947 (clobber (reg:SI T_REG))])]
3953 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3956 if (GET_CODE (operands[2]) != CONST_INT
3957 || INTVAL (operands[2]) != 1)
3961 ;; combined left/right shift
3964 [(set (match_operand:SI 0 "register_operand" "")
3965 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3966 (match_operand:SI 2 "const_int_operand" ""))
3967 (match_operand:SI 3 "const_int_operand" "")))]
3968 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3969 [(use (reg:SI R0_REG))]
3970 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3974 [(set (match_operand:SI 0 "register_operand" "")
3975 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3976 (match_operand:SI 2 "const_int_operand" ""))
3977 (match_operand:SI 3 "const_int_operand" "")))
3978 (clobber (reg:SI T_REG))]
3979 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3980 [(use (reg:SI R0_REG))]
3981 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3985 [(set (match_operand:SI 0 "register_operand" "=r")
3986 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3987 (match_operand:SI 2 "const_int_operand" "n"))
3988 (match_operand:SI 3 "const_int_operand" "n")))
3989 (clobber (reg:SI T_REG))]
3990 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3992 [(set (attr "length")
3993 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3995 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3997 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3999 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4001 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4003 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4005 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4006 (const_string "16")]
4007 (const_string "18")))
4008 (set_attr "type" "arith")])
4011 [(set (match_operand:SI 0 "register_operand" "=z")
4012 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4013 (match_operand:SI 2 "const_int_operand" "n"))
4014 (match_operand:SI 3 "const_int_operand" "n")))
4015 (clobber (reg:SI T_REG))]
4016 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4018 [(set (attr "length")
4019 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4021 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4023 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4025 (const_string "10")))
4026 (set_attr "type" "arith")])
4028 ;; shift left / and combination with a scratch register: The combine pass
4029 ;; does not accept the individual instructions, even though they are
4030 ;; cheap. But it needs a precise description so that it is usable after
4032 (define_insn "and_shl_scratch"
4033 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4037 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4038 (match_operand:SI 2 "const_int_operand" "N,n"))
4039 (match_operand:SI 3 "" "0,r"))
4040 (match_operand:SI 4 "const_int_operand" "n,n"))
4041 (match_operand:SI 5 "const_int_operand" "n,n")))
4042 (clobber (reg:SI T_REG))]
4045 [(set (attr "length")
4046 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4048 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4050 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4052 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4053 (const_string "10")]
4054 (const_string "12")))
4055 (set_attr "type" "arith")])
4058 [(set (match_operand:SI 0 "register_operand" "")
4062 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4063 (match_operand:SI 2 "const_int_operand" ""))
4064 (match_operand:SI 3 "register_operand" ""))
4065 (match_operand:SI 4 "const_int_operand" ""))
4066 (match_operand:SI 5 "const_int_operand" "")))
4067 (clobber (reg:SI T_REG))]
4069 [(use (reg:SI R0_REG))]
4072 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4074 if (INTVAL (operands[2]))
4076 gen_shifty_op (LSHIFTRT, operands);
4078 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4079 operands[2] = operands[4];
4080 gen_shifty_op (ASHIFT, operands);
4081 if (INTVAL (operands[5]))
4083 operands[2] = operands[5];
4084 gen_shifty_op (LSHIFTRT, operands);
4089 ;; signed left/right shift combination.
4091 [(set (match_operand:SI 0 "register_operand" "")
4093 (ashift:SI (match_operand:SI 1 "register_operand" "")
4094 (match_operand:SI 2 "const_int_operand" ""))
4095 (match_operand:SI 3 "const_int_operand" "")
4097 (clobber (reg:SI T_REG))]
4099 [(use (reg:SI R0_REG))]
4100 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4103 (define_insn "shl_sext_ext"
4104 [(set (match_operand:SI 0 "register_operand" "=r")
4106 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4107 (match_operand:SI 2 "const_int_operand" "n"))
4108 (match_operand:SI 3 "const_int_operand" "n")
4110 (clobber (reg:SI T_REG))]
4111 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4113 [(set (attr "length")
4114 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4116 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4118 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4120 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4122 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4124 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4126 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4128 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4129 (const_string "16")]
4130 (const_string "18")))
4131 (set_attr "type" "arith")])
4133 (define_insn "shl_sext_sub"
4134 [(set (match_operand:SI 0 "register_operand" "=z")
4136 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4137 (match_operand:SI 2 "const_int_operand" "n"))
4138 (match_operand:SI 3 "const_int_operand" "n")
4140 (clobber (reg:SI T_REG))]
4141 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4143 [(set (attr "length")
4144 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4146 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4148 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4150 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4151 (const_string "12")]
4152 (const_string "14")))
4153 (set_attr "type" "arith")])
4155 ;; These patterns are found in expansions of DImode shifts by 16, and
4156 ;; allow the xtrct instruction to be generated from C source.
4158 (define_insn "xtrct_left"
4159 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4160 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4162 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4166 [(set_attr "type" "arith")])
4168 (define_insn "xtrct_right"
4169 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4170 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4172 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4176 [(set_attr "type" "arith")])
4178 ;; -------------------------------------------------------------------------
4180 ;; -------------------------------------------------------------------------
4183 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4184 (neg:SI (plus:SI (reg:SI T_REG)
4185 (match_operand:SI 1 "arith_reg_operand" "r"))))
4187 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4191 [(set_attr "type" "arith")])
4193 (define_insn "*negdi_media"
4194 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4195 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4198 [(set_attr "type" "arith_media")])
4200 (define_expand "negdi2"
4201 [(set (match_operand:DI 0 "arith_reg_operand" "")
4202 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4208 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4209 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4211 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4212 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4214 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4215 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4217 emit_insn (gen_clrt ());
4218 emit_insn (gen_negc (low_dst, low_src));
4219 emit_insn (gen_negc (high_dst, high_src));
4224 (define_insn "negsi2"
4225 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4226 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4229 [(set_attr "type" "arith")])
4231 (define_insn "one_cmplsi2"
4232 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4233 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4236 [(set_attr "type" "arith")])
4238 (define_expand "one_cmpldi2"
4239 [(set (match_operand:DI 0 "arith_reg_dest" "")
4240 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4242 "TARGET_SHMEDIA" "")
4244 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4245 This can be used as some kind of conditional execution, which is useful
4248 [(set (match_operand:SI 0 "arith_reg_dest" "")
4249 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4250 (match_operand:SI 1 "arith_reg_operand" ""))
4254 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4255 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4259 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4260 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4261 (match_operand:SI 1 "arith_reg_operand" "0")
4262 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4264 "bf 0f\;neg %2,%0\\n0:"
4265 [(set_attr "type" "arith") ;; poor approximation
4266 (set_attr "length" "4")])
4269 ;; -------------------------------------------------------------------------
4270 ;; Zero extension instructions
4271 ;; -------------------------------------------------------------------------
4273 (define_insn "zero_extendsidi2"
4274 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4275 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4277 "addz.l %1, r63, %0"
4278 [(set_attr "type" "arith_media")
4279 (set_attr "highpart" "extend")])
4281 (define_insn "zero_extendhidi2"
4282 [(set (match_operand:DI 0 "register_operand" "=r,r")
4283 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4288 [(set_attr "type" "*,load_media")
4289 (set (attr "highpart")
4290 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4291 (const_string "user")]
4292 (const_string "ignore")))])
4295 [(set (match_operand:DI 0 "register_operand" "")
4296 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4297 "TARGET_SHMEDIA && reload_completed"
4298 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4299 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4302 if (GET_CODE (operands[1]) == TRUNCATE)
4303 operands[1] = XEXP (operands[1], 0);
4306 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4307 ;; reload the entire truncate expression.
4308 (define_insn_and_split "*loaddi_trunc"
4309 [(set (match_operand 0 "any_register_operand" "=r")
4310 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4311 "TARGET_SHMEDIA && reload_completed"
4313 "TARGET_SHMEDIA && reload_completed"
4314 [(set (match_dup 0) (match_dup 1))]
4315 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4317 (define_insn "zero_extendqidi2"
4318 [(set (match_operand:DI 0 "register_operand" "=r,r")
4319 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4324 [(set_attr "type" "arith_media,load_media")
4325 (set (attr "highpart")
4326 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4327 (const_string "user")]
4328 (const_string "ignore")))])
4330 (define_expand "zero_extendhisi2"
4331 [(set (match_operand:SI 0 "arith_reg_operand" "")
4332 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4336 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4337 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4340 (define_insn "*zero_extendhisi2_compact"
4341 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4342 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4345 [(set_attr "type" "arith")])
4347 (define_insn "*zero_extendhisi2_media"
4348 [(set (match_operand:SI 0 "register_operand" "=r,r")
4349 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4354 [(set_attr "type" "arith_media,load_media")
4355 (set (attr "highpart")
4356 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4357 (const_string "user")]
4358 (const_string "ignore")))])
4361 [(set (match_operand:SI 0 "register_operand" "")
4362 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4363 "TARGET_SHMEDIA && reload_completed"
4364 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4365 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4368 rtx op1 = operands[1];
4370 if (GET_CODE (op1) == TRUNCATE)
4371 op1 = XEXP (op1, 0);
4373 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4374 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4377 (define_expand "zero_extendqisi2"
4378 [(set (match_operand:SI 0 "arith_reg_operand" "")
4379 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4383 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4384 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4387 (define_insn "*zero_extendqisi2_compact"
4388 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4389 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4392 [(set_attr "type" "arith")])
4394 (define_insn "*zero_extendqisi2_media"
4395 [(set (match_operand:SI 0 "register_operand" "=r,r")
4396 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4401 [(set_attr "type" "arith_media,load_media")
4402 (set (attr "highpart")
4403 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4404 (const_string "user")]
4405 (const_string "ignore")))])
4407 (define_insn "zero_extendqihi2"
4408 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4409 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4412 [(set_attr "type" "arith")])
4414 ;; -------------------------------------------------------------------------
4415 ;; Sign extension instructions
4416 ;; -------------------------------------------------------------------------
4418 ;; ??? This should be a define expand.
4419 ;; ??? Or perhaps it should be dropped?
4421 ;; convert_move generates good code for SH[1-4].
4422 (define_insn "extendsidi2"
4423 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4424 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4430 [(set_attr "type" "arith_media,load_media,fpconv_media")
4431 (set (attr "highpart")
4432 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4433 (const_string "user")]
4434 (const_string "extend")))])
4436 (define_insn "extendhidi2"
4437 [(set (match_operand:DI 0 "register_operand" "=r,r")
4438 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4443 [(set_attr "type" "*,load_media")
4444 (set (attr "highpart")
4445 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4446 (const_string "user")]
4447 (const_string "ignore")))])
4450 [(set (match_operand:DI 0 "register_operand" "")
4451 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4452 "TARGET_SHMEDIA && reload_completed"
4453 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4454 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4457 if (GET_CODE (operands[1]) == TRUNCATE)
4458 operands[1] = XEXP (operands[1], 0);
4461 (define_insn "extendqidi2"
4462 [(set (match_operand:DI 0 "register_operand" "=r,r")
4463 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4468 [(set_attr "type" "*,load_media")
4469 (set (attr "highpart")
4470 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4471 (const_string "user")]
4472 (const_string "ignore")))])
4475 [(set (match_operand:DI 0 "register_operand" "")
4476 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4477 "TARGET_SHMEDIA && reload_completed"
4478 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4479 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4482 if (GET_CODE (operands[1]) == TRUNCATE)
4483 operands[1] = XEXP (operands[1], 0);
4486 (define_expand "extendhisi2"
4487 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4488 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4492 (define_insn "*extendhisi2_compact"
4493 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4494 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4499 [(set_attr "type" "arith,load")])
4501 (define_insn "*extendhisi2_media"
4502 [(set (match_operand:SI 0 "register_operand" "=r,r")
4503 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4508 [(set_attr "type" "arith_media,load_media")
4509 (set (attr "highpart")
4510 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4511 (const_string "user")]
4512 (const_string "ignore")))])
4515 [(set (match_operand:SI 0 "register_operand" "")
4516 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4517 "TARGET_SHMEDIA && reload_completed"
4518 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4519 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4522 rtx op1 = operands[1];
4523 if (GET_CODE (op1) == TRUNCATE)
4524 op1 = XEXP (op1, 0);
4526 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4527 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4530 (define_expand "extendqisi2"
4531 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4532 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4536 (define_insn "*extendqisi2_compact"
4537 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4538 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4543 [(set_attr "type" "arith,load")])
4545 (define_insn "*extendqisi2_media"
4546 [(set (match_operand:SI 0 "register_operand" "=r,r")
4547 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4552 [(set_attr "type" "arith_media,load_media")
4553 (set (attr "highpart")
4554 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4555 (const_string "user")]
4556 (const_string "ignore")))])
4559 [(set (match_operand:SI 0 "register_operand" "")
4560 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4561 "TARGET_SHMEDIA && reload_completed"
4562 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4563 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4566 rtx op1 = operands[1];
4567 if (GET_CODE (op1) == TRUNCATE)
4568 op1 = XEXP (op1, 0);
4570 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4571 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4574 (define_insn "extendqihi2"
4575 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4576 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4581 [(set_attr "type" "arith,load")])
4583 /* It would seem useful to combine the truncXi patterns into the movXi
4584 patterns, but unary operators are ignored when matching constraints,
4585 so we need separate patterns. */
4586 (define_insn "truncdisi2"
4587 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4588 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4597 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4598 (set (attr "highpart")
4599 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4600 (const_string "user")]
4601 (const_string "extend")))])
4603 (define_insn "truncdihi2"
4604 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4605 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4608 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4610 [(set_attr "type" "arith_media,store_media")
4611 (set_attr "length" "8,4")
4612 (set (attr "highpart")
4613 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4614 (const_string "user")]
4615 (const_string "extend")))])
4617 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4618 ; Because we use zero extension, we can't provide signed QImode compares
4619 ; using a simple compare or conditional banch insn.
4620 (define_insn "truncdiqi2"
4621 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4622 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4627 [(set_attr "type" "arith_media,store")
4628 (set (attr "highpart")
4629 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4630 (const_string "user")]
4631 (const_string "extend")))])
4632 ;; -------------------------------------------------------------------------
4633 ;; Move instructions
4634 ;; -------------------------------------------------------------------------
4636 ;; define push and pop so it is easy for sh.c
4637 ;; We can't use push and pop on SHcompact because the stack must always
4638 ;; be 8-byte aligned.
4640 (define_expand "push"
4641 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4642 (match_operand:SI 0 "register_operand" "r,l,x"))]
4643 "TARGET_SH1 && ! TARGET_SH5"
4646 (define_expand "pop"
4647 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4648 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4649 "TARGET_SH1 && ! TARGET_SH5"
4652 (define_expand "push_e"
4653 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4654 (match_operand:SF 0 "" ""))
4655 (use (reg:PSI FPSCR_REG))
4656 (clobber (scratch:SI))])]
4657 "TARGET_SH1 && ! TARGET_SH5"
4660 (define_insn "push_fpul"
4661 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4662 "TARGET_SH2E && ! TARGET_SH5"
4664 [(set_attr "type" "store")
4665 (set_attr "late_fp_use" "yes")
4666 (set_attr "hit_stack" "yes")])
4668 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4670 (define_expand "push_4"
4671 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4672 (match_operand:DF 0 "" ""))
4673 (use (reg:PSI FPSCR_REG))
4674 (clobber (scratch:SI))])]
4675 "TARGET_SH1 && ! TARGET_SH5"
4678 (define_expand "pop_e"
4679 [(parallel [(set (match_operand:SF 0 "" "")
4680 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4681 (use (reg:PSI FPSCR_REG))
4682 (clobber (scratch:SI))])]
4683 "TARGET_SH1 && ! TARGET_SH5"
4686 (define_insn "pop_fpul"
4687 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4688 "TARGET_SH2E && ! TARGET_SH5"
4690 [(set_attr "type" "load")
4691 (set_attr "hit_stack" "yes")])
4693 (define_expand "pop_4"
4694 [(parallel [(set (match_operand:DF 0 "" "")
4695 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4696 (use (reg:PSI FPSCR_REG))
4697 (clobber (scratch:SI))])]
4698 "TARGET_SH1 && ! TARGET_SH5"
4701 (define_expand "push_fpscr"
4706 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4707 gen_rtx_PRE_DEC (Pmode,
4708 stack_pointer_rtx)),
4710 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4714 (define_expand "pop_fpscr"
4719 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4720 gen_frame_mem (PSImode,
4721 gen_rtx_POST_INC (Pmode,
4722 stack_pointer_rtx))));
4723 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4727 ;; These two patterns can happen as the result of optimization, when
4728 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4729 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4732 [(set (reg:SI T_REG) (const_int 0))]
4737 [(set (reg:SI T_REG) (const_int 1))]
4741 ;; t/r must come after r/r, lest reload will try to reload stuff like
4742 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4743 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4744 (define_insn "movsi_i"
4745 [(set (match_operand:SI 0 "general_movdst_operand"
4746 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4747 (match_operand:SI 1 "general_movsrc_operand"
4748 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4752 && (register_operand (operands[0], SImode)
4753 || register_operand (operands[1], SImode))"
4770 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4771 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4773 ;; t/r must come after r/r, lest reload will try to reload stuff like
4774 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4775 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4776 ;; will require a reload.
4777 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4778 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4779 (define_insn "movsi_ie"
4780 [(set (match_operand:SI 0 "general_movdst_operand"
4781 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4782 (match_operand:SI 1 "general_movsrc_operand"
4783 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4784 "(TARGET_SH2E || TARGET_SH2A)
4785 && (register_operand (operands[0], SImode)
4786 || register_operand (operands[1], SImode))"
4811 ! move optimized away"
4812 [(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")
4813 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4814 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4816 (define_insn "movsi_i_lowpart"
4817 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4818 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4820 && (register_operand (operands[0], SImode)
4821 || register_operand (operands[1], SImode))"
4831 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4833 (define_insn_and_split "load_ra"
4834 [(set (match_operand:SI 0 "general_movdst_operand" "")
4835 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4838 "&& ! currently_expanding_to_rtl"
4839 [(set (match_dup 0) (match_dup 1))]
4842 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4843 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4846 ;; The '?'s in the following constraints may not reflect the time taken
4847 ;; to perform the move. They are there to discourage the use of floating-
4848 ;; point registers for storing integer values.
4849 (define_insn "*movsi_media"
4850 [(set (match_operand:SI 0 "general_movdst_operand"
4851 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4852 (match_operand:SI 1 "general_movsrc_operand"
4853 "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4855 && (register_operand (operands[0], SImode)
4856 || sh_register_operand (operands[1], SImode)
4857 || GET_CODE (operands[1]) == TRUNCATE)"
4872 [(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")
4873 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4874 (set (attr "highpart")
4875 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4876 (const_string "user")]
4877 (const_string "ignore")))])
4879 (define_insn "*movsi_media_nofpu"
4880 [(set (match_operand:SI 0 "general_movdst_operand"
4881 "=r,r,r,r,m,*b,r,*b")
4882 (match_operand:SI 1 "general_movsrc_operand"
4883 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4885 && (register_operand (operands[0], SImode)
4886 || sh_register_operand (operands[1], SImode)
4887 || GET_CODE (operands[1]) == TRUNCATE)"
4897 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4898 (set_attr "length" "4,4,8,4,4,4,4,12")
4899 (set (attr "highpart")
4900 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4901 (const_string "user")]
4902 (const_string "ignore")))])
4904 (define_expand "movsi_const"
4905 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4906 (const:SI (sign_extend:SI
4909 (match_operand:DI 1 "immediate_operand" "s")
4912 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4917 (truncate:HI (match_dup 1))))))))]
4918 "TARGET_SHMEDIA && reload_completed
4919 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4922 if (GET_CODE (operands[1]) == LABEL_REF
4923 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4924 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4925 else if (GOTOFF_P (operands[1]))
4927 rtx unspec = XEXP (operands[1], 0);
4929 if (! UNSPEC_GOTOFF_P (unspec))
4931 unspec = XEXP (unspec, 0);
4932 if (! UNSPEC_GOTOFF_P (unspec))
4935 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4936 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4937 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4941 (define_expand "movsi_const_16bit"
4942 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4943 (const:SI (sign_extend:SI
4945 (match_operand:DI 1 "immediate_operand" "s")))))]
4946 "TARGET_SHMEDIA && flag_pic && reload_completed
4947 && GET_CODE (operands[1]) == SYMBOL_REF"
4951 [(set (match_operand:SI 0 "arith_reg_dest" "")
4952 (match_operand:SI 1 "immediate_operand" ""))]
4953 "TARGET_SHMEDIA && reload_completed
4954 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4958 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4960 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4967 [(set (match_operand:SI 0 "register_operand" "")
4968 (match_operand:SI 1 "immediate_operand" ""))]
4969 "TARGET_SHMEDIA && reload_completed
4970 && ((GET_CODE (operands[1]) == CONST_INT
4971 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4972 || GET_CODE (operands[1]) == CONST_DOUBLE)"
4973 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4975 (define_expand "movsi"
4976 [(set (match_operand:SI 0 "general_movdst_operand" "")
4977 (match_operand:SI 1 "general_movsrc_operand" ""))]
4979 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4981 (define_expand "ic_invalidate_line"
4982 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4983 (match_dup 1)] UNSPEC_ICACHE)
4984 (clobber (scratch:SI))])]
4985 "TARGET_HARD_SH4 || TARGET_SH5"
4990 emit_insn (gen_ic_invalidate_line_media (operands[0]));
4993 else if (TARGET_SHCOMPACT)
4995 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4996 operands[1] = force_reg (Pmode, operands[1]);
4997 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5000 else if (TARGET_SH4A_ARCH)
5002 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5005 operands[0] = force_reg (Pmode, operands[0]);
5006 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5010 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5011 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5012 ;; the requirement *1*00 for associative address writes. The alignment of
5013 ;; %0 implies that its least significant bit is cleared,
5014 ;; thus we clear the V bit of a matching entry if there is one.
5015 (define_insn "ic_invalidate_line_i"
5016 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5017 (match_operand:SI 1 "register_operand" "r")]
5019 (clobber (match_scratch:SI 2 "=&r"))]
5021 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5022 [(set_attr "length" "8")
5023 (set_attr "type" "cwb")])
5025 (define_insn "ic_invalidate_line_sh4a"
5026 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5029 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5030 [(set_attr "length" "16")
5031 (set_attr "type" "cwb")])
5033 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5034 ;; an add in the code that calculates the address.
5035 (define_insn "ic_invalidate_line_media"
5036 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5039 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5040 [(set_attr "length" "16")
5041 (set_attr "type" "invalidate_line_media")])
5043 (define_insn "ic_invalidate_line_compact"
5044 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5045 (match_operand:SI 1 "register_operand" "r")]
5047 (clobber (reg:SI PR_REG))]
5050 [(set_attr "type" "sfunc")
5051 (set_attr "needs_delay_slot" "yes")])
5053 (define_expand "initialize_trampoline"
5054 [(match_operand:SI 0 "" "")
5055 (match_operand:SI 1 "" "")
5056 (match_operand:SI 2 "" "")]
5062 tramp = force_reg (Pmode, operands[0]);
5063 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5065 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5066 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5068 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5072 (define_insn "initialize_trampoline_compact"
5073 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5074 (match_operand:SI 1 "register_operand" "r")
5075 (reg:SI R2_REG) (reg:SI R3_REG)]
5078 (clobber (reg:SI PR_REG))]
5081 [(set_attr "type" "sfunc")
5082 (set_attr "needs_delay_slot" "yes")])
5084 (define_insn "movqi_i"
5085 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5086 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
5088 && (arith_reg_operand (operands[0], QImode)
5089 || arith_reg_operand (operands[1], QImode))"
5097 [(set_attr "type" "move,load,store,move,move,move")])
5099 (define_insn "*movqi_media"
5100 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5101 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5103 && (arith_reg_operand (operands[0], QImode)
5104 || extend_reg_or_0_operand (operands[1], QImode))"
5110 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5111 (set (attr "highpart")
5112 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5113 (const_string "user")]
5114 (const_string "ignore")))])
5116 (define_expand "movqi"
5117 [(set (match_operand:QI 0 "general_operand" "")
5118 (match_operand:QI 1 "general_operand" ""))]
5120 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5122 (define_expand "reload_inqi"
5123 [(set (match_operand:SI 2 "" "=&r")
5124 (match_operand:QI 1 "inqhi_operand" ""))
5125 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5126 (truncate:QI (match_dup 3)))]
5130 rtx inner = XEXP (operands[1], 0);
5131 int regno = REGNO (inner);
5133 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5134 operands[1] = gen_rtx_REG (SImode, regno);
5135 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5138 /* When storing r0, we have to avoid reg+reg addressing. */
5139 (define_insn "movhi_i"
5140 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5141 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5143 && (arith_reg_operand (operands[0], HImode)
5144 || arith_reg_operand (operands[1], HImode))
5145 && (GET_CODE (operands[0]) != MEM
5146 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5147 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5148 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5158 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5160 (define_insn "*movhi_media"
5161 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5162 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5164 && (arith_reg_operand (operands[0], HImode)
5165 || arith_reg_or_0_operand (operands[1], HImode))"
5172 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5173 (set (attr "highpart")
5174 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5175 (const_string "user")]
5176 (const_string "ignore")))])
5179 [(set (match_operand:HI 0 "register_operand" "")
5180 (match_operand:HI 1 "immediate_operand" ""))]
5181 "TARGET_SHMEDIA && reload_completed
5182 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5183 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5185 (define_expand "movhi"
5186 [(set (match_operand:HI 0 "general_movdst_operand" "")
5187 (match_operand:HI 1 "general_movsrc_operand" ""))]
5189 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5191 (define_expand "reload_inhi"
5192 [(set (match_operand:SI 2 "" "=&r")
5193 (match_operand:HI 1 "inqhi_operand" ""))
5194 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5195 (truncate:HI (match_dup 3)))]
5199 rtx inner = XEXP (operands[1], 0);
5200 int regno = REGNO (inner);
5202 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5203 operands[1] = gen_rtx_REG (SImode, regno);
5204 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5207 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5208 ;; compiled with -m2 -ml -O3 -funroll-loops
5209 (define_insn "*movdi_i"
5210 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5211 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5213 && (arith_reg_operand (operands[0], DImode)
5214 || arith_reg_operand (operands[1], DImode))"
5215 "* return output_movedouble (insn, operands, DImode);"
5216 [(set_attr "length" "4")
5217 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5219 ;; If the output is a register and the input is memory or a register, we have
5220 ;; to be careful and see which word needs to be loaded first.
5223 [(set (match_operand:DI 0 "general_movdst_operand" "")
5224 (match_operand:DI 1 "general_movsrc_operand" ""))]
5225 "TARGET_SH1 && reload_completed"
5226 [(set (match_dup 2) (match_dup 3))
5227 (set (match_dup 4) (match_dup 5))]
5232 if ((GET_CODE (operands[0]) == MEM
5233 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5234 || (GET_CODE (operands[1]) == MEM
5235 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5238 switch (GET_CODE (operands[0]))
5241 regno = REGNO (operands[0]);
5244 regno = subreg_regno (operands[0]);
5254 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5256 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5257 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5258 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5259 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5263 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5264 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5265 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5266 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5269 if (operands[2] == 0 || operands[3] == 0
5270 || operands[4] == 0 || operands[5] == 0)
5274 ;; The '?'s in the following constraints may not reflect the time taken
5275 ;; to perform the move. They are there to discourage the use of floating-
5276 ;; point registers for storing integer values.
5277 (define_insn "*movdi_media"
5278 [(set (match_operand:DI 0 "general_movdst_operand"
5279 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5280 (match_operand:DI 1 "general_movsrc_operand"
5281 "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5283 && (register_operand (operands[0], DImode)
5284 || sh_register_operand (operands[1], DImode))"
5299 [(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")
5300 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5302 (define_insn "*movdi_media_nofpu"
5303 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5304 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5306 && (register_operand (operands[0], DImode)
5307 || sh_register_operand (operands[1], DImode))"
5317 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5318 (set_attr "length" "4,4,16,4,4,4,4,*")])
5320 (define_insn "*movdi_media_I16"
5321 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5322 (match_operand:DI 1 "const_int_operand" "I16"))]
5323 "TARGET_SHMEDIA && reload_completed"
5325 [(set_attr "type" "arith_media")
5326 (set_attr "length" "4")])
5329 [(set (match_operand:DI 0 "arith_reg_dest" "")
5330 (match_operand:DI 1 "immediate_operand" ""))]
5331 "TARGET_SHMEDIA && reload_completed
5332 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5333 [(set (match_dup 0) (match_dup 1))]
5338 if (TARGET_SHMEDIA64)
5339 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5341 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5343 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5349 (define_expand "movdi_const"
5350 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5351 (const:DI (sign_extend:DI
5354 (match_operand:DI 1 "immediate_operand" "s")
5357 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5365 (const_int 32)))))))))
5367 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5375 (const_int 16)))))))))
5377 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5383 (match_dup 1))))))))]
5384 "TARGET_SHMEDIA64 && reload_completed
5385 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5388 sh_mark_label (operands[1], 4);
5391 (define_expand "movdi_const_32bit"
5392 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5393 (const:DI (sign_extend:DI
5396 (match_operand:DI 1 "immediate_operand" "s")
5399 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5405 (match_dup 1))))))))]
5406 "TARGET_SHMEDIA32 && reload_completed
5407 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5410 sh_mark_label (operands[1], 2);
5413 (define_expand "movdi_const_16bit"
5414 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5415 (const:DI (sign_extend:DI
5417 (match_operand:DI 1 "immediate_operand" "s")))))]
5418 "TARGET_SHMEDIA && flag_pic && reload_completed
5419 && GET_CODE (operands[1]) == SYMBOL_REF"
5423 [(set (match_operand:DI 0 "ext_dest_operand" "")
5424 (match_operand:DI 1 "immediate_operand" ""))]
5425 "TARGET_SHMEDIA && reload_completed
5426 && GET_CODE (operands[1]) == CONST_INT
5427 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5428 [(set (match_dup 0) (match_dup 2))
5432 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5433 unsigned HOST_WIDE_INT low = val;
5434 unsigned HOST_WIDE_INT high = val;
5435 unsigned HOST_WIDE_INT sign;
5436 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5438 /* Sign-extend the 16 least-significant bits. */
5443 /* Arithmetic shift right the word by 16 bits. */
5445 if (GET_CODE (operands[0]) == SUBREG
5446 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5455 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5461 /* If we can't generate the constant with a two-insn movi / shori
5462 sequence, try some other strategies. */
5463 if (! CONST_OK_FOR_I16 (high))
5465 /* Try constant load / left shift. We know VAL != 0. */
5466 val2 = val ^ (val-1);
5469 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5471 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5472 || (! CONST_OK_FOR_I16 (high >> 16)
5473 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5475 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5476 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5477 GEN_INT (trailing_zeroes));
5481 /* Try constant load / right shift. */
5482 val2 = (val >> 15) + 1;
5483 if (val2 == (val2 & -val2))
5485 int shift = 49 - exact_log2 (val2);
5487 val2 = trunc_int_for_mode (val << shift, DImode);
5488 if (CONST_OK_FOR_I16 (val2))
5490 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5496 val2 = val & 0xffff;
5497 if ((val >> 16 & 0xffff) == val2
5498 && (val >> 32 & 0xffff) == val2
5499 && (val >> 48 & 0xffff) == val2)
5501 val2 = (HOST_WIDE_INT) val >> 48;
5502 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5503 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5506 /* Try movi / mshflo.l */
5507 val2 = (HOST_WIDE_INT) val >> 32;
5508 if (val2 == ((unsigned HOST_WIDE_INT)
5509 trunc_int_for_mode (val, SImode)))
5511 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5515 /* Try movi / mshflo.l w/ r63. */
5516 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5517 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5519 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5525 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5528 operands[2] = GEN_INT (val2);
5532 [(set (match_operand:DI 0 "ext_dest_operand" "")
5533 (match_operand:DI 1 "immediate_operand" ""))]
5534 "TARGET_SHMEDIA && reload_completed
5535 && GET_CODE (operands[1]) == CONST_DOUBLE"
5536 [(set (match_dup 0) (match_dup 2))
5538 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5539 (zero_extend:DI (truncate:HI (match_dup 1)))))]
5542 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5543 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5544 unsigned HOST_WIDE_INT val = low;
5545 unsigned HOST_WIDE_INT sign;
5547 /* Sign-extend the 16 least-significant bits. */
5551 operands[1] = GEN_INT (val);
5553 /* Arithmetic shift right the double-word by 16 bits. */
5555 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5558 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5562 /* This will only be true if high is a sign-extension of low, i.e.,
5563 it must be either 0 or (unsigned)-1, and be zero iff the
5564 most-significant bit of low is set. */
5565 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5566 operands[2] = GEN_INT (low);
5568 operands[2] = immed_double_const (low, high, DImode);
5571 (define_insn "shori_media"
5572 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5573 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5577 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5578 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5582 [(set_attr "type" "arith_media,*")])
5584 (define_insn "*shori_media_si"
5585 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5586 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5590 (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5594 (define_expand "movdi"
5595 [(set (match_operand:DI 0 "general_movdst_operand" "")
5596 (match_operand:DI 1 "general_movsrc_operand" ""))]
5598 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5600 (define_insn "movdf_media"
5601 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5602 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5604 && (register_operand (operands[0], DFmode)
5605 || sh_register_operand (operands[1], DFmode))"
5616 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5618 (define_insn "movdf_media_nofpu"
5619 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5620 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5622 && (register_operand (operands[0], DFmode)
5623 || sh_register_operand (operands[1], DFmode))"
5629 [(set_attr "type" "arith_media,*,load_media,store_media")])
5632 [(set (match_operand:DF 0 "arith_reg_dest" "")
5633 (match_operand:DF 1 "immediate_operand" ""))]
5634 "TARGET_SHMEDIA && reload_completed"
5635 [(set (match_dup 3) (match_dup 2))]
5638 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5640 REAL_VALUE_TYPE value;
5642 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5643 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5645 if (HOST_BITS_PER_WIDE_INT >= 64)
5646 operands[2] = immed_double_const ((unsigned long) values[endian]
5647 | ((HOST_WIDE_INT) values[1 - endian]
5651 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5652 operands[2] = immed_double_const (values[endian], values[1 - endian],
5656 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5659 ;; ??? This should be a define expand.
5661 (define_insn "movdf_k"
5662 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5663 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5665 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5666 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5667 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5668 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5669 && (arith_reg_operand (operands[0], DFmode)
5670 || arith_reg_operand (operands[1], DFmode))"
5671 "* return output_movedouble (insn, operands, DFmode);"
5672 [(set_attr "length" "4")
5673 (set_attr "type" "move,pcload,load,store")])
5675 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5676 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5677 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5678 ;; the d/m/c/X alternative, which is split later into single-precision
5679 ;; instructions. And when not optimizing, no splits are done before fixing
5680 ;; up pcloads, so we need usable length information for that.
5681 (define_insn "movdf_i4"
5682 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5683 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5684 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5685 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5686 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5687 && (arith_reg_operand (operands[0], DFmode)
5688 || arith_reg_operand (operands[1], DFmode))"
5700 [(set_attr_alternative "length"
5701 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5703 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5704 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5705 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5707 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5708 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5709 ;; increment or decrement r15 explicitly.
5711 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5712 (const_int 10) (const_int 8))
5714 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5715 (const_int 10) (const_int 8))])
5716 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5717 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5718 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5719 (const_string "double")
5720 (const_string "none")))])
5722 ;; Moving DFmode between fp/general registers through memory
5723 ;; (the top of the stack) is faster than moving through fpul even for
5724 ;; little endian. Because the type of an instruction is important for its
5725 ;; scheduling, it is beneficial to split these operations, rather than
5726 ;; emitting them in one single chunk, even if this will expose a stack
5727 ;; use that will prevent scheduling of other stack accesses beyond this
5730 [(set (match_operand:DF 0 "register_operand" "")
5731 (match_operand:DF 1 "register_operand" ""))
5732 (use (match_operand:PSI 2 "fpscr_operand" ""))
5733 (clobber (match_scratch:SI 3 "=X"))]
5734 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5735 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5741 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5743 emit_move_insn (stack_pointer_rtx,
5744 plus_constant (stack_pointer_rtx, -8));
5745 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5748 tos = gen_tmp_stack_mem (DFmode,
5749 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5750 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5751 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5752 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5753 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5754 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5756 tos = gen_tmp_stack_mem (DFmode,
5757 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5758 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5759 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5760 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5762 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5766 ;; local-alloc sometimes allocates scratch registers even when not required,
5767 ;; so we must be prepared to handle these.
5769 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5771 [(set (match_operand:DF 0 "general_movdst_operand" "")
5772 (match_operand:DF 1 "general_movsrc_operand" ""))
5773 (use (match_operand:PSI 2 "fpscr_operand" ""))
5774 (clobber (match_scratch:SI 3 ""))]
5775 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5777 && true_regnum (operands[0]) < 16
5778 && true_regnum (operands[1]) < 16"
5779 [(set (match_dup 0) (match_dup 1))]
5782 /* If this was a reg <-> mem operation with base + index reg addressing,
5783 we have to handle this in a special way. */
5784 rtx mem = operands[0];
5786 if (! memory_operand (mem, DFmode))
5791 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5792 mem = SUBREG_REG (mem);
5793 if (GET_CODE (mem) == MEM)
5795 rtx addr = XEXP (mem, 0);
5796 if (GET_CODE (addr) == PLUS
5797 && GET_CODE (XEXP (addr, 0)) == REG
5798 && GET_CODE (XEXP (addr, 1)) == REG)
5801 rtx reg0 = gen_rtx_REG (Pmode, 0);
5802 rtx regop = operands[store_p], word0 ,word1;
5804 if (GET_CODE (regop) == SUBREG)
5805 alter_subreg (®op);
5806 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5810 mem = copy_rtx (mem);
5811 PUT_MODE (mem, SImode);
5812 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5813 alter_subreg (&word0);
5814 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5815 alter_subreg (&word1);
5816 if (store_p || ! refers_to_regno_p (REGNO (word0),
5817 REGNO (word0) + 1, addr, 0))
5820 ? gen_movsi_ie (mem, word0)
5821 : gen_movsi_ie (word0, mem));
5822 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5823 mem = copy_rtx (mem);
5825 ? gen_movsi_ie (mem, word1)
5826 : gen_movsi_ie (word1, mem));
5827 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5831 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5832 emit_insn (gen_movsi_ie (word1, mem));
5833 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5834 mem = copy_rtx (mem);
5835 emit_insn (gen_movsi_ie (word0, mem));
5842 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5844 [(set (match_operand:DF 0 "register_operand" "")
5845 (match_operand:DF 1 "memory_operand" ""))
5846 (use (match_operand:PSI 2 "fpscr_operand" ""))
5847 (clobber (reg:SI R0_REG))]
5848 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5849 [(parallel [(set (match_dup 0) (match_dup 1))
5851 (clobber (scratch:SI))])]
5854 (define_expand "reload_indf"
5855 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5856 (match_operand:DF 1 "immediate_operand" "FQ"))
5857 (use (reg:PSI FPSCR_REG))
5858 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5862 (define_expand "reload_outdf"
5863 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5864 (match_operand:DF 1 "register_operand" "af,r"))
5865 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5869 ;; Simplify no-op moves.
5871 [(set (match_operand:SF 0 "register_operand" "")
5872 (match_operand:SF 1 "register_operand" ""))
5873 (use (match_operand:PSI 2 "fpscr_operand" ""))
5874 (clobber (match_scratch:SI 3 ""))]
5875 "TARGET_SH2E && reload_completed
5876 && true_regnum (operands[0]) == true_regnum (operands[1])"
5877 [(set (match_dup 0) (match_dup 0))]
5880 ;; fmovd substitute post-reload splits
5882 [(set (match_operand:DF 0 "register_operand" "")
5883 (match_operand:DF 1 "register_operand" ""))
5884 (use (match_operand:PSI 2 "fpscr_operand" ""))
5885 (clobber (match_scratch:SI 3 ""))]
5886 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5887 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5888 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5892 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5893 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5894 gen_rtx_REG (SFmode, src), operands[2]));
5895 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5896 gen_rtx_REG (SFmode, src + 1), operands[2]));
5901 [(set (match_operand:DF 0 "register_operand" "")
5902 (mem:DF (match_operand:SI 1 "register_operand" "")))
5903 (use (match_operand:PSI 2 "fpscr_operand" ""))
5904 (clobber (match_scratch:SI 3 ""))]
5905 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5906 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5907 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5911 int regno = true_regnum (operands[0]);
5913 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5915 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5916 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5917 regno + !! TARGET_LITTLE_ENDIAN),
5918 mem2, operands[2]));
5919 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5920 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5921 regno + ! TARGET_LITTLE_ENDIAN),
5922 change_address (mem, SFmode, NULL_RTX),
5928 [(set (match_operand:DF 0 "register_operand" "")
5929 (match_operand:DF 1 "memory_operand" ""))
5930 (use (match_operand:PSI 2 "fpscr_operand" ""))
5931 (clobber (match_scratch:SI 3 ""))]
5932 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5933 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5937 int regno = true_regnum (operands[0]);
5938 rtx addr, insn, adjust = NULL_RTX;
5939 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
5940 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5941 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5943 operands[1] = copy_rtx (mem2);
5944 addr = XEXP (mem2, 0);
5945 if (GET_CODE (addr) != POST_INC)
5947 /* If we have to modify the stack pointer, the value that we have
5948 read with post-increment might be modified by an interrupt,
5949 so write it back. */
5950 if (REGNO (addr) == STACK_POINTER_REGNUM)
5951 adjust = gen_push_e (reg0);
5953 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5954 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5956 addr = XEXP (addr, 0);
5957 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5958 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5959 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5963 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5968 [(set (match_operand:DF 0 "memory_operand" "")
5969 (match_operand:DF 1 "register_operand" ""))
5970 (use (match_operand:PSI 2 "fpscr_operand" ""))
5971 (clobber (match_scratch:SI 3 ""))]
5972 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5973 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5977 int regno = true_regnum (operands[1]);
5978 rtx insn, addr, adjust = NULL_RTX;
5980 operands[0] = copy_rtx (operands[0]);
5981 PUT_MODE (operands[0], SFmode);
5982 insn = emit_insn (gen_movsf_ie (operands[0],
5983 gen_rtx_REG (SFmode,
5984 regno + ! TARGET_LITTLE_ENDIAN),
5986 operands[0] = copy_rtx (operands[0]);
5987 addr = XEXP (operands[0], 0);
5988 if (GET_CODE (addr) != PRE_DEC)
5990 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5991 emit_insn_before (adjust, insn);
5992 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5994 addr = XEXP (addr, 0);
5996 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5997 insn = emit_insn (gen_movsf_ie (operands[0],
5998 gen_rtx_REG (SFmode,
5999 regno + !! TARGET_LITTLE_ENDIAN),
6001 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6005 ;; If the output is a register and the input is memory or a register, we have
6006 ;; to be careful and see which word needs to be loaded first.
6009 [(set (match_operand:DF 0 "general_movdst_operand" "")
6010 (match_operand:DF 1 "general_movsrc_operand" ""))]
6011 "TARGET_SH1 && reload_completed"
6012 [(set (match_dup 2) (match_dup 3))
6013 (set (match_dup 4) (match_dup 5))]
6018 if ((GET_CODE (operands[0]) == MEM
6019 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6020 || (GET_CODE (operands[1]) == MEM
6021 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6024 switch (GET_CODE (operands[0]))
6027 regno = REGNO (operands[0]);
6030 regno = subreg_regno (operands[0]);
6040 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6042 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6043 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6044 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6045 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6049 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6050 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6051 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6052 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6055 if (operands[2] == 0 || operands[3] == 0
6056 || operands[4] == 0 || operands[5] == 0)
6060 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6061 ;; used only once, let combine add in the index again.
6064 [(set (match_operand:SI 0 "register_operand" "")
6065 (match_operand:SI 1 "" ""))
6066 (clobber (match_operand 2 "register_operand" ""))]
6067 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6068 && ALLOW_INDEXED_ADDRESS"
6069 [(use (reg:SI R0_REG))]
6072 rtx addr, reg, const_int;
6074 if (GET_CODE (operands[1]) != MEM)
6076 addr = XEXP (operands[1], 0);
6077 if (GET_CODE (addr) != PLUS)
6079 reg = XEXP (addr, 0);
6080 const_int = XEXP (addr, 1);
6081 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6082 && GET_CODE (const_int) == CONST_INT))
6084 emit_move_insn (operands[2], const_int);
6085 emit_move_insn (operands[0],
6086 change_address (operands[1], VOIDmode,
6087 gen_rtx_PLUS (SImode, reg, operands[2])));
6092 [(set (match_operand:SI 1 "" "")
6093 (match_operand:SI 0 "register_operand" ""))
6094 (clobber (match_operand 2 "register_operand" ""))]
6095 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6096 && ALLOW_INDEXED_ADDRESS"
6097 [(use (reg:SI R0_REG))]
6100 rtx addr, reg, const_int;
6102 if (GET_CODE (operands[1]) != MEM)
6104 addr = XEXP (operands[1], 0);
6105 if (GET_CODE (addr) != PLUS)
6107 reg = XEXP (addr, 0);
6108 const_int = XEXP (addr, 1);
6109 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6110 && GET_CODE (const_int) == CONST_INT))
6112 emit_move_insn (operands[2], const_int);
6113 emit_move_insn (change_address (operands[1], VOIDmode,
6114 gen_rtx_PLUS (SImode, reg, operands[2])),
6119 (define_expand "movdf"
6120 [(set (match_operand:DF 0 "general_movdst_operand" "")
6121 (match_operand:DF 1 "general_movsrc_operand" ""))]
6125 if (prepare_move_operands (operands, DFmode)) DONE;
6128 if (TARGET_SHMEDIA_FPU)
6129 emit_insn (gen_movdf_media (operands[0], operands[1]));
6131 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6134 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6136 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6141 ;;This is incompatible with the way gcc uses subregs.
6142 ;;(define_insn "movv2sf_i"
6143 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6144 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6145 ;; "TARGET_SHMEDIA_FPU
6146 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6147 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6151 ;; fst%M0.p %m0, %1"
6152 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6154 (define_insn_and_split "movv2sf_i"
6155 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6156 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6157 "TARGET_SHMEDIA_FPU"
6159 "TARGET_SHMEDIA_FPU && reload_completed"
6160 [(set (match_dup 0) (match_dup 1))]
6163 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6164 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6167 (define_expand "movv2sf"
6168 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6169 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6170 "TARGET_SHMEDIA_FPU"
6173 if (prepare_move_operands (operands, V2SFmode))
6177 (define_expand "addv2sf3"
6178 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6179 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6180 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6181 "TARGET_SHMEDIA_FPU"
6184 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6188 (define_expand "subv2sf3"
6189 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6190 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6191 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6192 "TARGET_SHMEDIA_FPU"
6195 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6199 (define_expand "mulv2sf3"
6200 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6201 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6202 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6203 "TARGET_SHMEDIA_FPU"
6206 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6210 (define_expand "divv2sf3"
6211 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6212 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6213 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6214 "TARGET_SHMEDIA_FPU"
6217 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6221 (define_insn_and_split "*movv4sf_i"
6222 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6223 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6224 "TARGET_SHMEDIA_FPU"
6226 "&& reload_completed"
6232 for (i = 0; i < 4/2; i++)
6236 if (GET_CODE (operands[0]) == MEM)
6237 x = adjust_address (operands[0], V2SFmode,
6238 i * GET_MODE_SIZE (V2SFmode));
6240 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6242 if (GET_CODE (operands[1]) == MEM)
6243 y = adjust_address (operands[1], V2SFmode,
6244 i * GET_MODE_SIZE (V2SFmode));
6246 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6248 emit_insn (gen_movv2sf_i (x, y));
6253 [(set_attr "length" "8")])
6255 (define_expand "movv4sf"
6256 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6257 (match_operand:V4SF 1 "general_operand" ""))]
6258 "TARGET_SHMEDIA_FPU"
6261 if (prepare_move_operands (operands, V4SFmode))
6265 (define_insn_and_split "*movv16sf_i"
6266 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6267 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6268 "TARGET_SHMEDIA_FPU"
6270 "&& reload_completed"
6276 for (i = 0; i < 16/2; i++)
6280 if (GET_CODE (operands[0]) == MEM)
6281 x = adjust_address (operands[0], V2SFmode,
6282 i * GET_MODE_SIZE (V2SFmode));
6285 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6289 if (GET_CODE (operands[1]) == MEM)
6290 y = adjust_address (operands[1], V2SFmode,
6291 i * GET_MODE_SIZE (V2SFmode));
6294 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6298 emit_insn (gen_movv2sf_i (x, y));
6303 [(set_attr "length" "32")])
6305 (define_expand "movv16sf"
6306 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6307 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6308 "TARGET_SHMEDIA_FPU"
6311 if (prepare_move_operands (operands, V16SFmode))
6315 (define_insn "movsf_media"
6316 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6317 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6319 && (register_operand (operands[0], SFmode)
6320 || sh_register_operand (operands[1], SFmode))"
6331 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6332 (set (attr "highpart")
6333 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6334 (const_string "user")]
6335 (const_string "ignore")))])
6337 (define_insn "movsf_media_nofpu"
6338 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6339 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6341 && (register_operand (operands[0], SFmode)
6342 || sh_register_operand (operands[1], SFmode))"
6348 [(set_attr "type" "arith_media,*,load_media,store_media")
6349 (set (attr "highpart")
6350 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6351 (const_string "user")]
6352 (const_string "ignore")))])
6355 [(set (match_operand:SF 0 "arith_reg_dest" "")
6356 (match_operand:SF 1 "immediate_operand" ""))]
6357 "TARGET_SHMEDIA && reload_completed
6358 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6359 [(set (match_dup 3) (match_dup 2))]
6363 REAL_VALUE_TYPE value;
6365 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6366 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6367 operands[2] = GEN_INT (values);
6369 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6372 (define_insn "movsf_i"
6373 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6374 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6377 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6378 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6379 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6380 && (arith_reg_operand (operands[0], SFmode)
6381 || arith_reg_operand (operands[1], SFmode))"
6390 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6392 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6393 ;; update_flow_info would not know where to put REG_EQUAL notes
6394 ;; when the destination changes mode.
6395 (define_insn "movsf_ie"
6396 [(set (match_operand:SF 0 "general_movdst_operand"
6397 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6398 (match_operand:SF 1 "general_movsrc_operand"
6399 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6400 (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"))
6401 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6404 && (arith_reg_operand (operands[0], SFmode)
6405 || arith_reg_operand (operands[1], SFmode)
6406 || arith_reg_operand (operands[3], SImode)
6407 || (fpul_operand (operands[0], SFmode)
6408 && memory_operand (operands[1], SFmode)
6409 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6410 || (fpul_operand (operands[1], SFmode)
6411 && memory_operand (operands[0], SFmode)
6412 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6432 ! move optimized away"
6433 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6434 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6435 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6436 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6437 (const_string "single")
6438 (const_string "none")))])
6441 [(set (match_operand:SF 0 "register_operand" "")
6442 (match_operand:SF 1 "register_operand" ""))
6443 (use (match_operand:PSI 2 "fpscr_operand" ""))
6444 (clobber (reg:SI FPUL_REG))]
6446 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6448 (clobber (scratch:SI))])
6449 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6451 (clobber (scratch:SI))])]
6454 (define_expand "movsf"
6455 [(set (match_operand:SF 0 "general_movdst_operand" "")
6456 (match_operand:SF 1 "general_movsrc_operand" ""))]
6460 if (prepare_move_operands (operands, SFmode))
6464 if (TARGET_SHMEDIA_FPU)
6465 emit_insn (gen_movsf_media (operands[0], operands[1]));
6467 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6472 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6477 (define_insn "mov_nop"
6478 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6481 [(set_attr "length" "0")
6482 (set_attr "type" "nil")])
6484 (define_expand "reload_insf"
6485 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6486 (match_operand:SF 1 "immediate_operand" "FQ"))
6487 (use (reg:PSI FPSCR_REG))
6488 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6492 (define_expand "reload_insi"
6493 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6494 (match_operand:SI 1 "immediate_operand" "i"))
6495 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6499 (define_expand "ptabs"
6500 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6504 if (!TARGET_PT_FIXED)
6506 rtx eq = operands[1];
6508 /* ??? For canonical RTL we really should remove any CONST from EQ
6509 before wrapping it in the AND, and finally wrap the EQ into a
6510 const if is constant. However, for reload we must expose the
6511 input register or symbolic constant, and we can't have
6512 different insn structures outside of the operands for different
6513 alternatives of the same pattern. */
6514 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6517 = (gen_rtx_IF_THEN_ELSE
6520 gen_rtx_MEM (PDImode, operands[1]),
6521 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6522 PDImode, operands[1])));
6526 ;; expanded by ptabs expander.
6527 (define_insn "*extendsipdi_media"
6528 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6529 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6533 (mem:PDI (match_dup 1))
6534 (sign_extend:PDI (match_dup 1))))]
6535 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6539 [(set_attr "type" "ptabs_media,pt_media")
6540 (set_attr "length" "4,*")])
6542 (define_insn "*truncdipdi_media"
6543 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6544 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6548 (mem:PDI (match_dup 1))
6549 (truncate:PDI (match_dup 1))))]
6550 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6554 [(set_attr "type" "ptabs_media,pt_media")
6555 (set_attr "length" "4,*")])
6557 (define_insn "*movsi_y"
6558 [(set (match_operand:SI 0 "register_operand" "=y,y")
6559 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6560 (clobber (match_scratch:SI 2 "=&z,r"))]
6562 && (reload_in_progress || reload_completed)"
6564 [(set_attr "length" "4")
6565 (set_attr "type" "pcload,move")])
6568 [(set (match_operand:SI 0 "register_operand" "")
6569 (match_operand:SI 1 "immediate_operand" ""))
6570 (clobber (match_operand:SI 2 "register_operand" ""))]
6572 [(set (match_dup 2) (match_dup 1))
6573 (set (match_dup 0) (match_dup 2))]
6577 [(set (match_operand:SI 0 "register_operand" "")
6578 (match_operand:SI 1 "memory_operand" ""))
6579 (clobber (reg:SI R0_REG))]
6581 [(set (match_dup 0) (match_dup 1))]
6584 ;; ------------------------------------------------------------------------
6585 ;; Define the real conditional branch instructions.
6586 ;; ------------------------------------------------------------------------
6588 (define_insn "branch_true"
6589 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6590 (label_ref (match_operand 0 "" ""))
6593 "* return output_branch (1, insn, operands);"
6594 [(set_attr "type" "cbranch")])
6596 (define_insn "branch_false"
6597 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6598 (label_ref (match_operand 0 "" ""))
6601 "* return output_branch (0, insn, operands);"
6602 [(set_attr "type" "cbranch")])
6604 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6605 ;; which destination is too far away.
6606 ;; The const_int_operand is distinct for each branch target; it avoids
6607 ;; unwanted matches with redundant_insn.
6608 (define_insn "block_branch_redirect"
6609 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6612 [(set_attr "length" "0")])
6614 ;; This one has the additional purpose to record a possible scratch register
6615 ;; for the following branch.
6616 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6617 ;; because the insn then might be deemed dead and deleted. And we can't
6618 ;; make the use in the jump insn explicit because that would disable
6619 ;; delay slot scheduling from the target.
6620 (define_insn "indirect_jump_scratch"
6621 [(set (match_operand:SI 0 "register_operand" "=r")
6622 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6623 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6626 [(set_attr "length" "0")])
6628 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6629 ;; being pulled into the delay slot of a condbranch that has been made to
6630 ;; jump around the unconditional jump because it was out of range.
6631 (define_insn "stuff_delay_slot"
6633 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6634 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6637 [(set_attr "length" "0")
6638 (set_attr "cond_delay_slot" "yes")])
6640 ;; Conditional branch insns
6642 (define_expand "beq_media"
6644 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6645 (match_operand:DI 2 "arith_operand" "r,I06"))
6646 (match_operand 0 "" "")
6649 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6651 (define_insn "*beq_media_i"
6653 (if_then_else (match_operator 3 "equality_comparison_operator"
6654 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6655 (match_operand:DI 2 "arith_operand" "r,I06")])
6656 (match_operand 0 "target_operand" "b,b")
6661 b%o3i%' %1, %2, %0%>"
6662 [(set_attr "type" "cbranch_media")])
6664 (define_insn "*beq_media_i32"
6666 (if_then_else (match_operator 3 "equality_comparison_operator"
6667 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6668 (match_operand:SI 2 "arith_operand" "r,I06")])
6669 (match_operand 0 "target_operand" "b,b")
6674 b%o3i%' %1, %2, %0%>"
6675 [(set_attr "type" "cbranch_media")])
6677 (define_expand "bne_media"
6679 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6680 (match_operand:DI 2 "arith_operand" "r,I06"))
6681 (match_operand 0 "" "")
6684 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6686 (define_expand "bgt_media"
6688 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6689 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6690 (match_operand 0 "" "")
6693 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6695 (define_expand "bge_media"
6697 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6698 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6699 (match_operand 0 "" "")
6702 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6704 (define_expand "bgtu_media"
6706 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6707 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6708 (match_operand 0 "" "")
6711 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6713 (define_expand "bgeu_media"
6715 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6716 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6717 (match_operand 0 "" "")
6720 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6722 (define_insn "*bgt_media_i"
6724 (if_then_else (match_operator 3 "greater_comparison_operator"
6725 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6726 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6727 (match_operand 0 "target_operand" "b")
6730 "b%o3%' %N1, %N2, %0%>"
6731 [(set_attr "type" "cbranch_media")])
6733 (define_insn "*bgt_media_i32"
6735 (if_then_else (match_operator 3 "greater_comparison_operator"
6736 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6737 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6738 (match_operand 0 "target_operand" "b")
6741 "b%o3%' %N1, %N2, %0%>"
6742 [(set_attr "type" "cbranch_media")])
6744 ;; These are only needed to make invert_jump() happy - otherwise, jump
6745 ;; optimization will be silently disabled.
6746 (define_insn "*blt_media_i"
6748 (if_then_else (match_operator 3 "less_comparison_operator"
6749 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6750 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6751 (match_operand 0 "target_operand" "b")
6754 "b%o3%' %N2, %N1, %0%>"
6755 [(set_attr "type" "cbranch_media")])
6757 (define_insn "*blt_media_i32"
6759 (if_then_else (match_operator 3 "less_comparison_operator"
6760 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6761 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6762 (match_operand 0 "target_operand" "b")
6765 "b%o3%' %N2, %N1, %0%>"
6766 [(set_attr "type" "cbranch_media")])
6768 (define_expand "beq"
6770 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6771 (label_ref (match_operand 0 "" ""))
6778 enum machine_mode mode = GET_MODE (sh_compare_op0);
6780 if (mode != DImode && mode != SImode)
6782 rtx tmp = gen_reg_rtx (DImode);
6784 emit_insn (gen_seq (tmp));
6785 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6789 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6790 if (CONSTANT_P (sh_compare_op1)
6791 && (GET_CODE (sh_compare_op1) != CONST_INT
6792 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6793 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6794 emit_jump_insn (gen_beq_media (operands[0],
6795 sh_compare_op0, sh_compare_op1));
6799 from_compare (operands, EQ);
6802 (define_expand "bne"
6804 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6805 (label_ref (match_operand 0 "" ""))
6812 enum machine_mode mode = GET_MODE (sh_compare_op0);
6814 if (mode != DImode && mode != SImode)
6816 rtx tmp = gen_reg_rtx (DImode);
6818 emit_insn (gen_seq (tmp));
6819 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6823 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6824 if (CONSTANT_P (sh_compare_op1)
6825 && (GET_CODE (sh_compare_op1) != CONST_INT
6826 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6827 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6828 emit_jump_insn (gen_bne_media (operands[0],
6829 sh_compare_op0, sh_compare_op1));
6833 from_compare (operands, EQ);
6836 (define_expand "bgt"
6838 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6839 (label_ref (match_operand 0 "" ""))
6846 enum machine_mode mode = GET_MODE (sh_compare_op0);
6848 if (mode != DImode && mode != SImode)
6850 rtx tmp = gen_reg_rtx (DImode);
6852 emit_insn (gen_sgt (tmp));
6853 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6857 if (sh_compare_op0 != const0_rtx)
6858 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6859 if (sh_compare_op1 != const0_rtx)
6860 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6861 emit_jump_insn (gen_bgt_media (operands[0],
6862 sh_compare_op0, sh_compare_op1));
6866 from_compare (operands, GT);
6869 (define_expand "blt"
6871 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6872 (label_ref (match_operand 0 "" ""))
6879 enum machine_mode mode = GET_MODE (sh_compare_op0);
6881 if (mode != DImode && mode != SImode)
6883 rtx tmp = gen_reg_rtx (DImode);
6885 emit_insn (gen_slt (tmp));
6886 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6890 if (sh_compare_op0 != const0_rtx)
6891 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6892 if (sh_compare_op1 != const0_rtx)
6893 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6894 emit_jump_insn (gen_bgt_media (operands[0],
6895 sh_compare_op1, sh_compare_op0));
6899 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6901 rtx tmp = sh_compare_op0;
6902 sh_compare_op0 = sh_compare_op1;
6903 sh_compare_op1 = tmp;
6904 emit_insn (gen_bgt (operands[0]));
6907 from_compare (operands, GE);
6910 (define_expand "ble"
6912 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6913 (label_ref (match_operand 0 "" ""))
6920 enum machine_mode mode = GET_MODE (sh_compare_op0);
6922 if (mode != DImode && mode != SImode)
6924 rtx tmp = gen_reg_rtx (DImode);
6926 emit_insn (gen_sle (tmp));
6927 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6931 if (sh_compare_op0 != const0_rtx)
6932 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6933 if (sh_compare_op1 != const0_rtx)
6934 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6935 emit_jump_insn (gen_bge_media (operands[0],
6936 sh_compare_op1, sh_compare_op0));
6942 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6944 rtx tmp = sh_compare_op0;
6945 sh_compare_op0 = sh_compare_op1;
6946 sh_compare_op1 = tmp;
6947 emit_insn (gen_bge (operands[0]));
6950 from_compare (operands, GT);
6953 (define_expand "bge"
6955 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6956 (label_ref (match_operand 0 "" ""))
6963 enum machine_mode mode = GET_MODE (sh_compare_op0);
6965 if (mode != DImode && mode != SImode)
6967 rtx tmp = gen_reg_rtx (DImode);
6969 emit_insn (gen_sge (tmp));
6970 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6974 if (sh_compare_op0 != const0_rtx)
6975 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6976 if (sh_compare_op1 != const0_rtx)
6977 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6978 emit_jump_insn (gen_bge_media (operands[0],
6979 sh_compare_op0, sh_compare_op1));
6985 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6987 rtx tmp = sh_compare_op0;
6988 sh_compare_op0 = sh_compare_op1;
6989 sh_compare_op1 = tmp;
6990 emit_insn (gen_ble (operands[0]));
6993 from_compare (operands, GE);
6996 (define_expand "bgtu"
6998 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6999 (label_ref (match_operand 0 "" ""))
7006 enum machine_mode mode = GET_MODE (sh_compare_op0);
7008 if (sh_compare_op0 != const0_rtx)
7009 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7010 if (sh_compare_op1 != const0_rtx)
7011 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7012 emit_jump_insn (gen_bgtu_media (operands[0],
7013 sh_compare_op0, sh_compare_op1));
7017 from_compare (operands, GTU);
7020 (define_expand "bltu"
7022 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7023 (label_ref (match_operand 0 "" ""))
7030 enum machine_mode mode = GET_MODE (sh_compare_op0);
7032 if (sh_compare_op0 != const0_rtx)
7033 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7034 if (sh_compare_op1 != const0_rtx)
7035 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7036 emit_jump_insn (gen_bgtu_media (operands[0],
7037 sh_compare_op1, sh_compare_op0));
7041 from_compare (operands, GEU);
7044 (define_expand "bgeu"
7046 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7047 (label_ref (match_operand 0 "" ""))
7054 enum machine_mode mode = GET_MODE (sh_compare_op0);
7056 if (sh_compare_op0 != const0_rtx)
7057 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7058 if (sh_compare_op1 != const0_rtx)
7059 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7060 emit_jump_insn (gen_bgeu_media (operands[0],
7061 sh_compare_op0, sh_compare_op1));
7065 from_compare (operands, GEU);
7068 (define_expand "bleu"
7070 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7071 (label_ref (match_operand 0 "" ""))
7078 enum machine_mode mode = GET_MODE (sh_compare_op0);
7080 if (sh_compare_op0 != const0_rtx)
7081 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7082 if (sh_compare_op1 != const0_rtx)
7083 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7084 emit_jump_insn (gen_bgeu_media (operands[0],
7085 sh_compare_op1, sh_compare_op0));
7089 from_compare (operands, GTU);
7092 (define_expand "bunordered"
7093 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7095 (if_then_else (ne (match_dup 1) (const_int 0))
7096 (match_operand 0 "" "")
7101 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7102 operands[1] = gen_reg_rtx (DImode);
7103 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7104 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7107 ;; combiner splitter for test-and-branch on single bit in register. This
7108 ;; is endian dependent because the non-paradoxical subreg looks different
7113 (match_operator 3 "equality_comparison_operator"
7114 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7115 "extend_reg_operand" "")
7119 "const_int_operand" "")) 0)
7121 (match_operand 0 "target_operand" "")
7123 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7124 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7125 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7126 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7130 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7131 operands[6] = (GET_CODE (operands[3]) == EQ
7132 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7133 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7136 ;; ------------------------------------------------------------------------
7137 ;; Jump and linkage insns
7138 ;; ------------------------------------------------------------------------
7140 (define_insn "jump_compact"
7142 (label_ref (match_operand 0 "" "")))]
7146 /* The length is 16 if the delay slot is unfilled. */
7147 if (get_attr_length(insn) > 4)
7148 return output_far_jump(insn, operands[0]);
7150 return \"bra %l0%#\";
7152 [(set_attr "type" "jump")
7153 (set_attr "needs_delay_slot" "yes")])
7155 ;; ??? It would be much saner to explicitly use the scratch register
7156 ;; in the jump insn, and have indirect_jump_scratch only set it,
7157 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7158 ;; from the target then, as it uses simplejump_p.
7159 ;;(define_insn "jump_compact_far"
7161 ;; (label_ref (match_operand 0 "" "")))
7162 ;; (use (match_operand 1 "register_operand" "r")]
7164 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7165 ;; [(set_attr "type" "jump")
7166 ;; (set_attr "needs_delay_slot" "yes")])
7168 (define_insn "jump_media"
7170 (match_operand 0 "target_operand" "b"))]
7173 [(set_attr "type" "jump_media")])
7175 (define_expand "jump"
7177 (label_ref (match_operand 0 "" "")))]
7182 emit_jump_insn (gen_jump_compact (operands[0]));
7183 else if (TARGET_SHMEDIA)
7185 if (reload_in_progress || reload_completed)
7187 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7193 (define_insn "force_mode_for_call"
7194 [(use (reg:PSI FPSCR_REG))]
7197 [(set_attr "length" "0")
7198 (set (attr "fp_mode")
7199 (if_then_else (eq_attr "fpu_single" "yes")
7200 (const_string "single") (const_string "double")))])
7202 (define_insn "calli"
7203 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7204 (match_operand 1 "" ""))
7205 (use (reg:PSI FPSCR_REG))
7206 (clobber (reg:SI PR_REG))]
7209 [(set_attr "type" "call")
7210 (set (attr "fp_mode")
7211 (if_then_else (eq_attr "fpu_single" "yes")
7212 (const_string "single") (const_string "double")))
7213 (set_attr "needs_delay_slot" "yes")
7214 (set_attr "fp_set" "unknown")])
7216 ;; This is a pc-rel call, using bsrf, for use with PIC.
7218 (define_insn "calli_pcrel"
7219 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7220 (match_operand 1 "" ""))
7221 (use (reg:PSI FPSCR_REG))
7222 (use (reg:SI PIC_REG))
7223 (use (match_operand 2 "" ""))
7224 (clobber (reg:SI PR_REG))]
7227 [(set_attr "type" "call")
7228 (set (attr "fp_mode")
7229 (if_then_else (eq_attr "fpu_single" "yes")
7230 (const_string "single") (const_string "double")))
7231 (set_attr "needs_delay_slot" "yes")
7232 (set_attr "fp_set" "unknown")])
7234 (define_insn_and_split "call_pcrel"
7235 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7236 (match_operand 1 "" ""))
7237 (use (reg:PSI FPSCR_REG))
7238 (use (reg:SI PIC_REG))
7239 (clobber (reg:SI PR_REG))
7240 (clobber (match_scratch:SI 2 "=r"))]
7247 rtx lab = PATTERN (gen_call_site ());
7249 if (SYMBOL_REF_LOCAL_P (operands[0]))
7250 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7252 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7253 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7256 [(set_attr "type" "call")
7257 (set (attr "fp_mode")
7258 (if_then_else (eq_attr "fpu_single" "yes")
7259 (const_string "single") (const_string "double")))
7260 (set_attr "needs_delay_slot" "yes")
7261 (set_attr "fp_set" "unknown")])
7263 (define_insn "call_compact"
7264 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7265 (match_operand 1 "" ""))
7266 (match_operand 2 "immediate_operand" "n")
7267 (use (reg:SI R0_REG))
7268 (use (reg:SI R1_REG))
7269 (use (reg:PSI FPSCR_REG))
7270 (clobber (reg:SI PR_REG))]
7271 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7273 [(set_attr "type" "call")
7274 (set (attr "fp_mode")
7275 (if_then_else (eq_attr "fpu_single" "yes")
7276 (const_string "single") (const_string "double")))
7277 (set_attr "needs_delay_slot" "yes")])
7279 (define_insn "call_compact_rettramp"
7280 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7281 (match_operand 1 "" ""))
7282 (match_operand 2 "immediate_operand" "n")
7283 (use (reg:SI R0_REG))
7284 (use (reg:SI R1_REG))
7285 (use (reg:PSI FPSCR_REG))
7286 (clobber (reg:SI R10_REG))
7287 (clobber (reg:SI PR_REG))]
7288 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7290 [(set_attr "type" "call")
7291 (set (attr "fp_mode")
7292 (if_then_else (eq_attr "fpu_single" "yes")
7293 (const_string "single") (const_string "double")))
7294 (set_attr "needs_delay_slot" "yes")])
7296 (define_insn "call_media"
7297 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7298 (match_operand 1 "" ""))
7299 (clobber (reg:DI PR_MEDIA_REG))]
7302 [(set_attr "type" "jump_media")])
7304 (define_insn "call_valuei"
7305 [(set (match_operand 0 "" "=rf")
7306 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7307 (match_operand 2 "" "")))
7308 (use (reg:PSI FPSCR_REG))
7309 (clobber (reg:SI PR_REG))]
7312 [(set_attr "type" "call")
7313 (set (attr "fp_mode")
7314 (if_then_else (eq_attr "fpu_single" "yes")
7315 (const_string "single") (const_string "double")))
7316 (set_attr "needs_delay_slot" "yes")
7317 (set_attr "fp_set" "unknown")])
7319 (define_insn "call_valuei_pcrel"
7320 [(set (match_operand 0 "" "=rf")
7321 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7322 (match_operand 2 "" "")))
7323 (use (reg:PSI FPSCR_REG))
7324 (use (reg:SI PIC_REG))
7325 (use (match_operand 3 "" ""))
7326 (clobber (reg:SI PR_REG))]
7329 [(set_attr "type" "call")
7330 (set (attr "fp_mode")
7331 (if_then_else (eq_attr "fpu_single" "yes")
7332 (const_string "single") (const_string "double")))
7333 (set_attr "needs_delay_slot" "yes")
7334 (set_attr "fp_set" "unknown")])
7336 (define_insn_and_split "call_value_pcrel"
7337 [(set (match_operand 0 "" "=rf")
7338 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7339 (match_operand 2 "" "")))
7340 (use (reg:PSI FPSCR_REG))
7341 (use (reg:SI PIC_REG))
7342 (clobber (reg:SI PR_REG))
7343 (clobber (match_scratch:SI 3 "=r"))]
7350 rtx lab = PATTERN (gen_call_site ());
7352 if (SYMBOL_REF_LOCAL_P (operands[1]))
7353 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7355 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7356 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7360 [(set_attr "type" "call")
7361 (set (attr "fp_mode")
7362 (if_then_else (eq_attr "fpu_single" "yes")
7363 (const_string "single") (const_string "double")))
7364 (set_attr "needs_delay_slot" "yes")
7365 (set_attr "fp_set" "unknown")])
7367 (define_insn "call_value_compact"
7368 [(set (match_operand 0 "" "=rf")
7369 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7370 (match_operand 2 "" "")))
7371 (match_operand 3 "immediate_operand" "n")
7372 (use (reg:SI R0_REG))
7373 (use (reg:SI R1_REG))
7374 (use (reg:PSI FPSCR_REG))
7375 (clobber (reg:SI PR_REG))]
7376 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7378 [(set_attr "type" "call")
7379 (set (attr "fp_mode")
7380 (if_then_else (eq_attr "fpu_single" "yes")
7381 (const_string "single") (const_string "double")))
7382 (set_attr "needs_delay_slot" "yes")])
7384 (define_insn "call_value_compact_rettramp"
7385 [(set (match_operand 0 "" "=rf")
7386 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7387 (match_operand 2 "" "")))
7388 (match_operand 3 "immediate_operand" "n")
7389 (use (reg:SI R0_REG))
7390 (use (reg:SI R1_REG))
7391 (use (reg:PSI FPSCR_REG))
7392 (clobber (reg:SI R10_REG))
7393 (clobber (reg:SI PR_REG))]
7394 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7396 [(set_attr "type" "call")
7397 (set (attr "fp_mode")
7398 (if_then_else (eq_attr "fpu_single" "yes")
7399 (const_string "single") (const_string "double")))
7400 (set_attr "needs_delay_slot" "yes")])
7402 (define_insn "call_value_media"
7403 [(set (match_operand 0 "" "=rf")
7404 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7405 (match_operand 2 "" "")))
7406 (clobber (reg:DI PR_MEDIA_REG))]
7409 [(set_attr "type" "jump_media")])
7411 (define_expand "call"
7412 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7413 (match_operand 1 "" ""))
7414 (match_operand 2 "" "")
7415 (use (reg:PSI FPSCR_REG))
7416 (clobber (reg:SI PR_REG))])]
7422 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7423 emit_call_insn (gen_call_media (operands[0], operands[1]));
7426 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7428 rtx cookie_rtx = operands[2];
7429 long cookie = INTVAL (cookie_rtx);
7430 rtx func = XEXP (operands[0], 0);
7435 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7437 rtx reg = gen_reg_rtx (Pmode);
7439 emit_insn (gen_symGOTPLT2reg (reg, func));
7443 func = legitimize_pic_address (func, Pmode, 0);
7446 r0 = gen_rtx_REG (SImode, R0_REG);
7447 r1 = gen_rtx_REG (SImode, R1_REG);
7449 /* Since such a call function may use all call-clobbered
7450 registers, we force a mode switch earlier, so that we don't
7451 run out of registers when adjusting fpscr for the call. */
7452 emit_insn (gen_force_mode_for_call ());
7455 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7457 operands[0] = force_reg (SImode, operands[0]);
7459 emit_move_insn (r0, func);
7460 emit_move_insn (r1, cookie_rtx);
7462 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7463 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7466 emit_call_insn (gen_call_compact (operands[0], operands[1],
7471 else if (TARGET_SHCOMPACT && flag_pic
7472 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7473 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7475 rtx reg = gen_reg_rtx (Pmode);
7477 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7478 XEXP (operands[0], 0) = reg;
7480 if (flag_pic && TARGET_SH2
7481 && GET_CODE (operands[0]) == MEM
7482 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7484 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7489 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7490 operands[1] = operands[2];
7493 emit_call_insn (gen_calli (operands[0], operands[1]));
7497 (define_insn "call_pop_compact"
7498 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7499 (match_operand 1 "" ""))
7500 (match_operand 2 "immediate_operand" "n")
7501 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7502 (match_operand 3 "immediate_operand" "n")))
7503 (use (reg:SI R0_REG))
7504 (use (reg:SI R1_REG))
7505 (use (reg:PSI FPSCR_REG))
7506 (clobber (reg:SI PR_REG))]
7507 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7509 [(set_attr "type" "call")
7510 (set (attr "fp_mode")
7511 (if_then_else (eq_attr "fpu_single" "yes")
7512 (const_string "single") (const_string "double")))
7513 (set_attr "needs_delay_slot" "yes")])
7515 (define_insn "call_pop_compact_rettramp"
7516 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7517 (match_operand 1 "" ""))
7518 (match_operand 2 "immediate_operand" "n")
7519 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7520 (match_operand 3 "immediate_operand" "n")))
7521 (use (reg:SI R0_REG))
7522 (use (reg:SI R1_REG))
7523 (use (reg:PSI FPSCR_REG))
7524 (clobber (reg:SI R10_REG))
7525 (clobber (reg:SI PR_REG))]
7526 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7528 [(set_attr "type" "call")
7529 (set (attr "fp_mode")
7530 (if_then_else (eq_attr "fpu_single" "yes")
7531 (const_string "single") (const_string "double")))
7532 (set_attr "needs_delay_slot" "yes")])
7534 (define_expand "call_pop"
7535 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7536 (match_operand 1 "" ""))
7537 (match_operand 2 "" "")
7538 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7539 (match_operand 3 "" "")))])]
7548 gcc_assert (operands[2] && INTVAL (operands[2]));
7549 cookie_rtx = operands[2];
7550 cookie = INTVAL (cookie_rtx);
7551 func = XEXP (operands[0], 0);
7555 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7557 rtx reg = gen_reg_rtx (Pmode);
7558 emit_insn (gen_symGOTPLT2reg (reg, func));
7562 func = legitimize_pic_address (func, Pmode, 0);
7565 r0 = gen_rtx_REG (SImode, R0_REG);
7566 r1 = gen_rtx_REG (SImode, R1_REG);
7568 /* Since such a call function may use all call-clobbered
7569 registers, we force a mode switch earlier, so that we don't
7570 run out of registers when adjusting fpscr for the call. */
7571 emit_insn (gen_force_mode_for_call ());
7573 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7575 operands[0] = force_reg (SImode, operands[0]);
7577 emit_move_insn (r0, func);
7578 emit_move_insn (r1, cookie_rtx);
7580 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7581 emit_call_insn (gen_call_pop_compact_rettramp
7582 (operands[0], operands[1], operands[2], operands[3]));
7584 emit_call_insn (gen_call_pop_compact
7585 (operands[0], operands[1], operands[2], operands[3]));
7590 (define_expand "call_value"
7591 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7592 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7593 (match_operand 2 "" "")))
7594 (match_operand 3 "" "")
7595 (use (reg:PSI FPSCR_REG))
7596 (clobber (reg:SI PR_REG))])]
7602 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7603 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7607 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7609 rtx cookie_rtx = operands[3];
7610 long cookie = INTVAL (cookie_rtx);
7611 rtx func = XEXP (operands[1], 0);
7616 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7618 rtx reg = gen_reg_rtx (Pmode);
7620 emit_insn (gen_symGOTPLT2reg (reg, func));
7624 func = legitimize_pic_address (func, Pmode, 0);
7627 r0 = gen_rtx_REG (SImode, R0_REG);
7628 r1 = gen_rtx_REG (SImode, R1_REG);
7630 /* Since such a call function may use all call-clobbered
7631 registers, we force a mode switch earlier, so that we don't
7632 run out of registers when adjusting fpscr for the call. */
7633 emit_insn (gen_force_mode_for_call ());
7636 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7638 operands[1] = force_reg (SImode, operands[1]);
7640 emit_move_insn (r0, func);
7641 emit_move_insn (r1, cookie_rtx);
7643 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7644 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7649 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7650 operands[2], operands[3]));
7654 else if (TARGET_SHCOMPACT && flag_pic
7655 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7656 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7658 rtx reg = gen_reg_rtx (Pmode);
7660 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7661 XEXP (operands[1], 0) = reg;
7663 if (flag_pic && TARGET_SH2
7664 && GET_CODE (operands[1]) == MEM
7665 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7667 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7672 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7674 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7678 (define_insn "sibcalli"
7679 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7680 (match_operand 1 "" ""))
7681 (use (reg:PSI FPSCR_REG))
7685 [(set_attr "needs_delay_slot" "yes")
7686 (set (attr "fp_mode")
7687 (if_then_else (eq_attr "fpu_single" "yes")
7688 (const_string "single") (const_string "double")))
7689 (set_attr "type" "jump_ind")])
7691 (define_insn "sibcalli_pcrel"
7692 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7693 (match_operand 1 "" ""))
7694 (use (match_operand 2 "" ""))
7695 (use (reg:PSI FPSCR_REG))
7699 [(set_attr "needs_delay_slot" "yes")
7700 (set (attr "fp_mode")
7701 (if_then_else (eq_attr "fpu_single" "yes")
7702 (const_string "single") (const_string "double")))
7703 (set_attr "type" "jump_ind")])
7705 ;; This uses an unspec to describe that the symbol_ref is very close.
7706 (define_insn "sibcalli_thunk"
7707 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7709 (match_operand 1 "" ""))
7710 (use (reg:PSI FPSCR_REG))
7714 [(set_attr "needs_delay_slot" "yes")
7715 (set (attr "fp_mode")
7716 (if_then_else (eq_attr "fpu_single" "yes")
7717 (const_string "single") (const_string "double")))
7718 (set_attr "type" "jump")
7719 (set_attr "length" "2")])
7721 (define_insn_and_split "sibcall_pcrel"
7722 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7723 (match_operand 1 "" ""))
7724 (use (reg:PSI FPSCR_REG))
7725 (clobber (match_scratch:SI 2 "=k"))
7733 rtx lab = PATTERN (gen_call_site ());
7736 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7737 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7739 SIBLING_CALL_P (call_insn) = 1;
7742 [(set_attr "needs_delay_slot" "yes")
7743 (set (attr "fp_mode")
7744 (if_then_else (eq_attr "fpu_single" "yes")
7745 (const_string "single") (const_string "double")))
7746 (set_attr "type" "jump_ind")])
7748 (define_insn "sibcall_compact"
7749 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7750 (match_operand 1 "" ""))
7752 (use (match_operand:SI 2 "register_operand" "z,x"))
7753 (use (reg:SI R1_REG))
7754 (use (reg:PSI FPSCR_REG))
7755 ;; We want to make sure the `x' above will only match MACH_REG
7756 ;; because sibcall_epilogue may clobber MACL_REG.
7757 (clobber (reg:SI MACL_REG))]
7761 jmp @%0\\n sts %2, r0"
7762 [(set_attr "needs_delay_slot" "yes,no")
7763 (set_attr "length" "2,4")
7764 (set (attr "fp_mode") (const_string "single"))
7765 (set_attr "type" "jump_ind")])
7767 (define_insn "sibcall_media"
7768 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7769 (match_operand 1 "" ""))
7770 (use (reg:SI PR_MEDIA_REG))
7774 [(set_attr "type" "jump_media")])
7776 (define_expand "sibcall"
7778 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7779 (match_operand 1 "" ""))
7780 (match_operand 2 "" "")
7781 (use (reg:PSI FPSCR_REG))
7788 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7789 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7792 else if (TARGET_SHCOMPACT && operands[2]
7793 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7795 rtx cookie_rtx = operands[2];
7796 long cookie = INTVAL (cookie_rtx);
7797 rtx func = XEXP (operands[0], 0);
7802 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7804 rtx reg = gen_reg_rtx (Pmode);
7806 emit_insn (gen_symGOT2reg (reg, func));
7810 func = legitimize_pic_address (func, Pmode, 0);
7813 /* FIXME: if we could tell whether all argument registers are
7814 already taken, we could decide whether to force the use of
7815 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7816 simple way to tell. We could use the CALL_COOKIE, but we
7817 can't currently tell a register used for regular argument
7818 passing from one that is unused. If we leave it up to reload
7819 to decide which register to use, it seems to always choose
7820 R0_REG, which leaves no available registers in SIBCALL_REGS
7821 to hold the address of the trampoline. */
7822 mach = gen_rtx_REG (SImode, MACH_REG);
7823 r1 = gen_rtx_REG (SImode, R1_REG);
7825 /* Since such a call function may use all call-clobbered
7826 registers, we force a mode switch earlier, so that we don't
7827 run out of registers when adjusting fpscr for the call. */
7828 emit_insn (gen_force_mode_for_call ());
7831 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7833 operands[0] = force_reg (SImode, operands[0]);
7835 /* We don't need a return trampoline, since the callee will
7836 return directly to the upper caller. */
7837 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7839 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7840 cookie_rtx = GEN_INT (cookie);
7843 emit_move_insn (mach, func);
7844 emit_move_insn (r1, cookie_rtx);
7846 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7849 else if (TARGET_SHCOMPACT && flag_pic
7850 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7851 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7853 rtx reg = gen_reg_rtx (Pmode);
7855 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7856 XEXP (operands[0], 0) = reg;
7858 if (flag_pic && TARGET_SH2
7859 && GET_CODE (operands[0]) == MEM
7860 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7861 /* The PLT needs the PIC register, but the epilogue would have
7862 to restore it, so we can only use PC-relative PIC calls for
7863 static functions. */
7864 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7866 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7870 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7872 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7876 (define_expand "sibcall_value"
7877 [(set (match_operand 0 "" "")
7878 (call (match_operand 1 "" "")
7879 (match_operand 2 "" "")))
7880 (match_operand 3 "" "")]
7884 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7888 (define_insn "call_value_pop_compact"
7889 [(set (match_operand 0 "" "=rf")
7890 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7891 (match_operand 2 "" "")))
7892 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7893 (match_operand 4 "immediate_operand" "n")))
7894 (match_operand 3 "immediate_operand" "n")
7895 (use (reg:SI R0_REG))
7896 (use (reg:SI R1_REG))
7897 (use (reg:PSI FPSCR_REG))
7898 (clobber (reg:SI PR_REG))]
7899 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7901 [(set_attr "type" "call")
7902 (set (attr "fp_mode")
7903 (if_then_else (eq_attr "fpu_single" "yes")
7904 (const_string "single") (const_string "double")))
7905 (set_attr "needs_delay_slot" "yes")])
7907 (define_insn "call_value_pop_compact_rettramp"
7908 [(set (match_operand 0 "" "=rf")
7909 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7910 (match_operand 2 "" "")))
7911 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7912 (match_operand 4 "immediate_operand" "n")))
7913 (match_operand 3 "immediate_operand" "n")
7914 (use (reg:SI R0_REG))
7915 (use (reg:SI R1_REG))
7916 (use (reg:PSI FPSCR_REG))
7917 (clobber (reg:SI R10_REG))
7918 (clobber (reg:SI PR_REG))]
7919 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7921 [(set_attr "type" "call")
7922 (set (attr "fp_mode")
7923 (if_then_else (eq_attr "fpu_single" "yes")
7924 (const_string "single") (const_string "double")))
7925 (set_attr "needs_delay_slot" "yes")])
7927 (define_expand "call_value_pop"
7928 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7929 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7930 (match_operand 2 "" "")))
7931 (match_operand 3 "" "")
7932 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7933 (match_operand 4 "" "")))])]
7942 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7943 cookie_rtx = operands[3];
7944 cookie = INTVAL (cookie_rtx);
7945 func = XEXP (operands[1], 0);
7949 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7951 rtx reg = gen_reg_rtx (Pmode);
7953 emit_insn (gen_symGOTPLT2reg (reg, func));
7957 func = legitimize_pic_address (func, Pmode, 0);
7960 r0 = gen_rtx_REG (SImode, R0_REG);
7961 r1 = gen_rtx_REG (SImode, R1_REG);
7963 /* Since such a call function may use all call-clobbered
7964 registers, we force a mode switch earlier, so that we don't
7965 run out of registers when adjusting fpscr for the call. */
7966 emit_insn (gen_force_mode_for_call ());
7968 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7970 operands[1] = force_reg (SImode, operands[1]);
7972 emit_move_insn (r0, func);
7973 emit_move_insn (r1, cookie_rtx);
7975 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7976 emit_call_insn (gen_call_value_pop_compact_rettramp
7977 (operands[0], operands[1], operands[2],
7978 operands[3], operands[4]));
7980 emit_call_insn (gen_call_value_pop_compact
7981 (operands[0], operands[1], operands[2],
7982 operands[3], operands[4]));
7987 (define_expand "sibcall_epilogue"
7992 sh_expand_epilogue (1);
7993 if (TARGET_SHCOMPACT)
7997 /* If epilogue clobbers r0, preserve it in macl. */
7998 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7999 if ((set = single_set (insn))
8000 && GET_CODE (SET_DEST (set)) == REG
8001 && REGNO (SET_DEST (set)) == R0_REG)
8003 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8004 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8007 /* We can't tell at this point whether the sibcall is a
8008 sibcall_compact and, if it is, whether it uses r0 or
8009 mach as operand 2, so let the instructions that
8010 preserve r0 be optimized away if r0 turns out to be
8012 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8013 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8015 i = emit_move_insn (r0, tmp);
8016 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8024 (define_insn "indirect_jump_compact"
8026 (match_operand:SI 0 "arith_reg_operand" "r"))]
8029 [(set_attr "needs_delay_slot" "yes")
8030 (set_attr "type" "jump_ind")])
8032 (define_expand "indirect_jump"
8034 (match_operand 0 "register_operand" ""))]
8038 if (GET_MODE (operands[0]) != Pmode)
8039 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8042 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8043 ;; which can be present in structured code from indirect jumps which can not
8044 ;; be present in structured code. This allows -fprofile-arcs to work.
8046 ;; For SH1 processors.
8047 (define_insn "casesi_jump_1"
8049 (match_operand:SI 0 "register_operand" "r"))
8050 (use (label_ref (match_operand 1 "" "")))]
8053 [(set_attr "needs_delay_slot" "yes")
8054 (set_attr "type" "jump_ind")])
8056 ;; For all later processors.
8057 (define_insn "casesi_jump_2"
8058 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8059 (label_ref (match_operand 1 "" ""))))
8060 (use (label_ref (match_operand 2 "" "")))]
8062 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8064 [(set_attr "needs_delay_slot" "yes")
8065 (set_attr "type" "jump_ind")])
8067 (define_insn "casesi_jump_media"
8068 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8069 (use (label_ref (match_operand 1 "" "")))]
8072 [(set_attr "type" "jump_media")])
8074 ;; Call subroutine returning any type.
8075 ;; ??? This probably doesn't work.
8077 (define_expand "untyped_call"
8078 [(parallel [(call (match_operand 0 "" "")
8080 (match_operand 1 "" "")
8081 (match_operand 2 "" "")])]
8082 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8087 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8089 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8091 rtx set = XVECEXP (operands[2], 0, i);
8092 emit_move_insn (SET_DEST (set), SET_SRC (set));
8095 /* The optimizer does not know that the call sets the function value
8096 registers we stored in the result block. We avoid problems by
8097 claiming that all hard registers are used and clobbered at this
8099 emit_insn (gen_blockage ());
8104 ;; ------------------------------------------------------------------------
8106 ;; ------------------------------------------------------------------------
8109 [(set (reg:SI T_REG)
8110 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8111 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8114 [(set_attr "type" "arith")])
8121 ;; Load address of a label. This is only generated by the casesi expand,
8122 ;; and by machine_dependent_reorg (fixing up fp moves).
8123 ;; This must use unspec, because this only works for labels that are
8127 [(set (reg:SI R0_REG)
8128 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8131 [(set_attr "in_delay_slot" "no")
8132 (set_attr "type" "arith")])
8134 ;; machine_dependent_reorg will make this a `mova'.
8135 (define_insn "mova_const"
8136 [(set (reg:SI R0_REG)
8137 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8140 [(set_attr "in_delay_slot" "no")
8141 (set_attr "type" "arith")])
8143 (define_expand "GOTaddr2picreg"
8144 [(set (reg:SI R0_REG)
8145 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8147 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8148 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8151 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8152 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8156 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8157 rtx pic = operands[0];
8158 rtx lab = PATTERN (gen_call_site ());
8161 equiv = operands[1];
8162 operands[1] = gen_rtx_MINUS (Pmode,
8166 gen_rtx_MINUS (Pmode,
8167 gen_rtx_CONST (Pmode,
8170 operands[1] = gen_sym2PIC (operands[1]);
8171 PUT_MODE (operands[1], Pmode);
8173 if (Pmode == SImode)
8175 emit_insn (gen_movsi_const (pic, operands[1]));
8176 emit_insn (gen_ptrel_si (tr, pic, lab));
8180 emit_insn (gen_movdi_const (pic, operands[1]));
8181 emit_insn (gen_ptrel_di (tr, pic, lab));
8184 insn = emit_move_insn (operands[0], tr);
8186 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8195 [(set (match_operand 0 "target_reg_operand" "=b")
8196 (const (unspec [(match_operand 1 "" "Csy")]
8197 UNSPEC_DATALABEL)))]
8198 "TARGET_SHMEDIA && flag_pic
8199 && EXTRA_CONSTRAINT_Csy (operands[1])"
8200 "ptb/u datalabel %1, %0"
8201 [(set_attr "type" "ptabs_media")
8202 (set_attr "length" "*")])
8204 (define_insn "ptrel_si"
8205 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8206 (plus:SI (match_operand:SI 1 "register_operand" "r")
8208 (match_operand:SI 2 "" "")]
8210 "%O2: ptrel/u %1, %0"
8211 [(set_attr "type" "ptabs_media")])
8213 (define_insn "ptrel_di"
8214 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8215 (plus:DI (match_operand:DI 1 "register_operand" "r")
8217 (match_operand:DI 2 "" "")]
8219 "%O2: ptrel/u %1, %0"
8220 [(set_attr "type" "ptabs_media")])
8222 (define_expand "builtin_setjmp_receiver"
8223 [(match_operand 0 "" "")]
8227 emit_insn (gen_GOTaddr2picreg ());
8231 (define_expand "call_site"
8232 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8236 static HOST_WIDE_INT i = 0;
8237 operands[0] = GEN_INT (i);
8241 (define_expand "sym_label2reg"
8242 [(set (match_operand:SI 0 "" "")
8245 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8248 (match_operand:SI 2 "" "")
8252 (define_expand "symGOT_load"
8253 [(set (match_dup 2) (match_operand 1 "" ""))
8254 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8255 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8261 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8262 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8266 rtx reg = operands[2];
8268 if (Pmode == DImode)
8271 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8273 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8278 emit_insn (gen_movsi_const (reg, operands[1]));
8280 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8284 emit_move_insn (operands[2], operands[1]);
8286 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8288 gen_rtx_REG (Pmode, PIC_REG)));
8290 /* When stack protector inserts codes after the result is set to
8291 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8292 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8293 when rX is a GOT address for the guard symbol. Ugly but doesn't
8294 matter because this is a rare situation. */
8296 && flag_stack_protect
8297 && GET_CODE (operands[1]) == CONST
8298 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8299 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8300 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8301 \"__stack_chk_guard\") == 0)
8302 emit_insn (gen_blockage ());
8304 /* N.B. This is not constant for a GOTPLT relocation. */
8305 mem = gen_rtx_MEM (Pmode, operands[3]);
8306 MEM_NOTRAP_P (mem) = 1;
8307 /* ??? Should we have a special alias set for the GOT? */
8308 insn = emit_move_insn (operands[0], mem);
8310 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8317 (define_expand "sym2GOT"
8318 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8322 (define_expand "symGOT2reg"
8323 [(match_operand 0 "" "") (match_operand 1 "" "")]
8329 gotsym = gen_sym2GOT (operands[1]);
8330 PUT_MODE (gotsym, Pmode);
8331 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8333 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8338 (define_expand "sym2GOTPLT"
8339 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8343 (define_expand "symGOTPLT2reg"
8344 [(match_operand 0 "" "") (match_operand 1 "" "")]
8348 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8352 (define_expand "sym2GOTOFF"
8353 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8357 (define_expand "symGOTOFF2reg"
8358 [(match_operand 0 "" "") (match_operand 1 "" "")]
8362 rtx gotoffsym, insn;
8363 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8365 gotoffsym = gen_sym2GOTOFF (operands[1]);
8366 PUT_MODE (gotoffsym, Pmode);
8367 emit_move_insn (t, gotoffsym);
8368 insn = emit_move_insn (operands[0],
8369 gen_rtx_PLUS (Pmode, t,
8370 gen_rtx_REG (Pmode, PIC_REG)));
8372 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8378 (define_expand "symPLT_label2reg"
8379 [(set (match_operand:SI 0 "" "")
8382 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8386 (match_operand:SI 2 "" "")
8388 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8389 ;; Even though the PIC register is not really used by the call
8390 ;; sequence in which this is expanded, the PLT code assumes the PIC
8391 ;; register is set, so we must not skip its initialization. Since
8392 ;; we only use this expand as part of calling sequences, and never
8393 ;; to take the address of a function, this is the best point to
8394 ;; insert the (use). Using the PLT to take the address of a
8395 ;; function would be wrong, not only because the PLT entry could
8396 ;; then be called from a function that doesn't initialize the PIC
8397 ;; register to the proper GOT, but also because pointers to the
8398 ;; same function might not compare equal, should they be set by
8399 ;; different shared libraries.
8400 (use (reg:SI PIC_REG))]
8404 (define_expand "sym2PIC"
8405 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8409 ;; TLS code generation.
8410 ;; ??? this should be a define_insn_and_split
8411 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8412 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8415 (define_insn "tls_global_dynamic"
8416 [(set (match_operand:SI 0 "register_operand" "=&z")
8417 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8420 (use (reg:PSI FPSCR_REG))
8421 (use (reg:SI PIC_REG))
8422 (clobber (reg:SI PR_REG))
8423 (clobber (scratch:SI))]
8429 \\tmova\\t2f,r0\\n\\
8430 \\tmov.l\\t2f,r1\\n\\
8433 \\tadd\\tr12,r4\\n\\
8437 1:\\t.long\\t%a1@TLSGD\\n\\
8438 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8441 [(set_attr "type" "tls_load")
8442 (set_attr "length" "26")])
8444 (define_insn "tls_local_dynamic"
8445 [(set (match_operand:SI 0 "register_operand" "=&z")
8446 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8449 (use (reg:PSI FPSCR_REG))
8450 (use (reg:SI PIC_REG))
8451 (clobber (reg:SI PR_REG))
8452 (clobber (scratch:SI))]
8458 \\tmova\\t2f,r0\\n\\
8459 \\tmov.l\\t2f,r1\\n\\
8462 \\tadd\\tr12,r4\\n\\
8466 1:\\t.long\\t%a1@TLSLDM\\n\\
8467 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8470 [(set_attr "type" "tls_load")
8471 (set_attr "length" "26")])
8473 (define_expand "sym2DTPOFF"
8474 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8478 (define_expand "symDTPOFF2reg"
8479 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8483 rtx dtpoffsym, insn;
8484 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8486 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8487 PUT_MODE (dtpoffsym, Pmode);
8488 emit_move_insn (t, dtpoffsym);
8489 insn = emit_move_insn (operands[0],
8490 gen_rtx_PLUS (Pmode, t, operands[2]));
8494 (define_expand "sym2GOTTPOFF"
8495 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8499 (define_insn "tls_initial_exec"
8500 [(set (match_operand:SI 0 "register_operand" "=&r")
8501 (unspec:SI [(match_operand:SI 1 "" "")]
8503 (use (reg:SI GBR_REG))
8504 (use (reg:SI PIC_REG))
8505 (clobber (reg:SI R0_REG))]
8511 \\tstc\\tgbr,%0\\n\\
8512 \\tmov.l\\t@(r0,r12),r0\\n\\
8516 1:\\t.long\\t%a1\\n\\
8519 [(set_attr "type" "tls_load")
8520 (set_attr "length" "16")])
8522 (define_expand "sym2TPOFF"
8523 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8527 (define_expand "symTPOFF2reg"
8528 [(match_operand 0 "" "") (match_operand 1 "" "")]
8534 tpoffsym = gen_sym2TPOFF (operands[1]);
8535 PUT_MODE (tpoffsym, Pmode);
8536 insn = emit_move_insn (operands[0], tpoffsym);
8540 (define_insn "load_gbr"
8541 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8542 (use (reg:SI GBR_REG))]
8545 [(set_attr "type" "tls_load")])
8547 ;; case instruction for switch statements.
8549 ;; Operand 0 is index
8550 ;; operand 1 is the minimum bound
8551 ;; operand 2 is the maximum bound - minimum bound + 1
8552 ;; operand 3 is CODE_LABEL for the table;
8553 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8555 (define_expand "casesi"
8556 [(match_operand:SI 0 "arith_reg_operand" "")
8557 (match_operand:SI 1 "arith_reg_operand" "")
8558 (match_operand:SI 2 "arith_reg_operand" "")
8559 (match_operand 3 "" "") (match_operand 4 "" "")]
8563 rtx reg = gen_reg_rtx (SImode);
8564 rtx reg2 = gen_reg_rtx (SImode);
8567 rtx reg = gen_reg_rtx (DImode);
8568 rtx reg2 = gen_reg_rtx (DImode);
8569 rtx reg3 = gen_reg_rtx (Pmode);
8570 rtx reg4 = gen_reg_rtx (Pmode);
8571 rtx reg5 = gen_reg_rtx (Pmode);
8574 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8575 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8576 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8578 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8579 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8580 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8581 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8582 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8583 (Pmode, operands[3])));
8584 /* Messy: can we subreg to clean this up? */
8585 if (Pmode == DImode)
8586 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8588 load = gen_casesi_load_media (reg4,
8589 gen_rtx_SUBREG (DImode, reg3, 0),
8591 PUT_MODE (SET_SRC (load), Pmode);
8593 /* ??? The following add could be eliminated if we used ptrel. */
8594 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8595 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8599 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8600 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8601 /* If optimizing, casesi_worker depends on the mode of the instruction
8602 before label it 'uses' - operands[3]. */
8603 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8605 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8607 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8609 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8610 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8611 operands[3], but to lab. We will fix this up in
8612 machine_dependent_reorg. */
8617 (define_expand "casesi_0"
8618 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8619 (set (match_dup 4) (minus:SI (match_dup 4)
8620 (match_operand:SI 1 "arith_operand" "")))
8622 (gtu:SI (match_dup 4)
8623 (match_operand:SI 2 "arith_reg_operand" "")))
8625 (if_then_else (ne (reg:SI T_REG)
8627 (label_ref (match_operand 3 "" ""))
8632 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8633 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8634 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8636 (define_insn "casesi_worker_0"
8637 [(set (match_operand:SI 0 "register_operand" "=r,r")
8638 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8639 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8640 (clobber (match_scratch:SI 3 "=X,1"))
8641 (clobber (match_scratch:SI 4 "=&z,z"))]
8646 [(set (match_operand:SI 0 "register_operand" "")
8647 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8648 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8649 (clobber (match_scratch:SI 3 ""))
8650 (clobber (match_scratch:SI 4 ""))]
8651 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8652 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8653 (parallel [(set (match_dup 0)
8654 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8655 (label_ref (match_dup 2))] UNSPEC_CASESI))
8656 (clobber (match_dup 3))])
8657 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8658 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8661 [(set (match_operand:SI 0 "register_operand" "")
8662 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8663 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8664 (clobber (match_scratch:SI 3 ""))
8665 (clobber (match_scratch:SI 4 ""))]
8666 "TARGET_SH2 && reload_completed"
8667 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8668 (parallel [(set (match_dup 0)
8669 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8670 (label_ref (match_dup 2))] UNSPEC_CASESI))
8671 (clobber (match_dup 3))])]
8672 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8674 (define_insn "casesi_worker_1"
8675 [(set (match_operand:SI 0 "register_operand" "=r,r")
8676 (unspec:SI [(reg:SI R0_REG)
8677 (match_operand:SI 1 "register_operand" "0,r")
8678 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8679 (clobber (match_scratch:SI 3 "=X,1"))]
8683 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8685 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8687 switch (GET_MODE (diff_vec))
8690 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8692 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8694 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8695 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8696 return \"mov.b @(r0,%1),%0\";
8701 [(set_attr "length" "4")])
8703 (define_insn "casesi_worker_2"
8704 [(set (match_operand:SI 0 "register_operand" "=r,r")
8705 (unspec:SI [(reg:SI R0_REG)
8706 (match_operand:SI 1 "register_operand" "0,r")
8707 (label_ref (match_operand 2 "" ""))
8708 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8709 (clobber (match_operand:SI 4 "" "=X,1"))]
8710 "TARGET_SH2 && reload_completed && flag_pic"
8713 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8716 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8718 switch (GET_MODE (diff_vec))
8721 output_asm_insn (\"shll2 %1\", operands);
8722 load = \"mov.l @(r0,%1),%0\"; break;
8724 output_asm_insn (\"add %1,%1\", operands);
8725 load = \"mov.w @(r0,%1),%0\"; break;
8727 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8728 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8730 load = \"mov.b @(r0,%1),%0\";
8735 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8738 [(set_attr "length" "8")])
8740 (define_insn "casesi_shift_media"
8741 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8742 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8743 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8748 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8750 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8752 switch (GET_MODE (diff_vec))
8755 return \"shlli %1, 2, %0\";
8757 return \"shlli %1, 1, %0\";
8759 if (rtx_equal_p (operands[0], operands[1]))
8761 return \"add %1, r63, %0\";
8766 [(set_attr "type" "arith_media")])
8768 (define_insn "casesi_load_media"
8769 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8770 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8771 (match_operand:DI 2 "arith_reg_operand" "r")
8772 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8776 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8778 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8780 switch (GET_MODE (diff_vec))
8783 return \"ldx.l %1, %2, %0\";
8786 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8787 return \"ldx.uw %1, %2, %0\";
8789 return \"ldx.w %1, %2, %0\";
8791 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8792 return \"ldx.ub %1, %2, %0\";
8793 return \"ldx.b %1, %2, %0\";
8798 [(set_attr "type" "load_media")])
8800 (define_expand "return"
8802 "reload_completed && ! sh_need_epilogue ()"
8807 emit_jump_insn (gen_return_media ());
8811 if (TARGET_SHCOMPACT
8812 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8814 emit_jump_insn (gen_shcompact_return_tramp ());
8819 (define_insn "*return_i"
8821 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8822 && (current_function_args_info.call_cookie
8823 & CALL_COOKIE_RET_TRAMP (1)))
8825 && sh_cfun_trap_exit_p ()"
8827 [(set_attr "type" "return")
8828 (set_attr "needs_delay_slot" "yes")])
8830 ;; trapa has no delay slot.
8831 (define_insn "*return_trapa"
8833 "TARGET_SH1 && !TARGET_SHCOMPACT
8834 && reload_completed"
8836 [(set_attr "type" "return")])
8838 (define_expand "shcompact_return_tramp"
8841 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8844 rtx reg = gen_rtx_REG (Pmode, R0_REG);
8846 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8847 emit_jump_insn (gen_shcompact_return_tramp_i ());
8851 (define_insn "shcompact_return_tramp_i"
8852 [(parallel [(return) (use (reg:SI R0_REG))])]
8854 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8856 [(set_attr "type" "jump_ind")
8857 (set_attr "needs_delay_slot" "yes")])
8859 (define_insn "return_media_i"
8860 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8861 "TARGET_SHMEDIA && reload_completed"
8863 [(set_attr "type" "jump_media")])
8865 (define_insn "return_media_rte"
8867 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8869 [(set_attr "type" "jump_media")])
8871 (define_expand "return_media"
8873 "TARGET_SHMEDIA && reload_completed"
8876 int tr_regno = sh_media_register_for_return ();
8879 if (current_function_interrupt)
8881 emit_jump_insn (gen_return_media_rte ());
8886 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8888 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8890 tr = gen_rtx_REG (Pmode, tr_regno);
8891 emit_move_insn (tr, r18);
8894 tr = gen_rtx_REG (Pmode, tr_regno);
8896 emit_jump_insn (gen_return_media_i (tr));
8900 (define_insn "shcompact_preserve_incoming_args"
8901 [(set (match_operand:SI 0 "register_operand" "+r")
8902 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8905 [(set_attr "length" "0")])
8907 (define_insn "shcompact_incoming_args"
8908 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8909 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8910 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8911 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8912 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8913 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8914 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8915 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8916 (set (mem:BLK (reg:SI MACL_REG))
8917 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8918 (use (reg:SI R0_REG))
8919 (clobber (reg:SI R0_REG))
8920 (clobber (reg:SI MACL_REG))
8921 (clobber (reg:SI MACH_REG))
8922 (clobber (reg:SI PR_REG))]
8925 [(set_attr "needs_delay_slot" "yes")])
8927 (define_insn "shmedia_save_restore_regs_compact"
8928 [(set (reg:SI SP_REG)
8929 (plus:SI (reg:SI SP_REG)
8930 (match_operand:SI 0 "immediate_operand" "i")))
8931 (use (reg:SI R0_REG))
8932 (clobber (reg:SI PR_REG))]
8934 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8935 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8937 [(set_attr "needs_delay_slot" "yes")])
8939 (define_expand "prologue"
8942 "sh_expand_prologue (); DONE;")
8944 (define_expand "epilogue"
8949 sh_expand_epilogue (0);
8950 emit_jump_insn (gen_return ());
8954 (define_expand "eh_return"
8955 [(use (match_operand 0 "register_operand" ""))]
8958 rtx ra = operands[0];
8960 if (TARGET_SHMEDIA64)
8961 emit_insn (gen_eh_set_ra_di (ra));
8963 emit_insn (gen_eh_set_ra_si (ra));
8968 ;; Clobber the return address on the stack. We can't expand this
8969 ;; until we know where it will be put in the stack frame.
8971 (define_insn "eh_set_ra_si"
8972 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8973 (clobber (match_scratch:SI 1 "=&r"))]
8974 "! TARGET_SHMEDIA64"
8977 (define_insn "eh_set_ra_di"
8978 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8979 (clobber (match_scratch:DI 1 "=&r"))]
8984 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8985 (clobber (match_scratch 1 ""))]
8990 sh_set_return_address (operands[0], operands[1]);
8994 (define_insn "blockage"
8995 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8998 [(set_attr "length" "0")])
9000 ;; ------------------------------------------------------------------------
9002 ;; ------------------------------------------------------------------------
9005 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9006 (eq:SI (reg:SI T_REG) (const_int 1)))]
9009 [(set_attr "type" "arith")])
9011 (define_expand "seq"
9012 [(set (match_operand:SI 0 "arith_reg_dest" "")
9019 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9020 if (sh_compare_op1 != const0_rtx)
9021 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9022 ? GET_MODE (sh_compare_op0)
9023 : GET_MODE (sh_compare_op1),
9025 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9027 if (GET_MODE (operands[0]) != SImode)
9028 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9030 switch (GET_MODE (sh_compare_op0))
9033 emit_insn (gen_cmpsieqsi_media (operands[0],
9034 sh_compare_op0, sh_compare_op1));
9038 emit_insn (gen_cmpsieqdi_media (operands[0],
9039 sh_compare_op0, sh_compare_op1));
9043 if (! TARGET_SHMEDIA_FPU)
9045 emit_insn (gen_cmpsieqsf_media (operands[0],
9046 sh_compare_op0, sh_compare_op1));
9050 if (! TARGET_SHMEDIA_FPU)
9052 emit_insn (gen_cmpsieqdf_media (operands[0],
9053 sh_compare_op0, sh_compare_op1));
9062 if (GET_MODE (operands[0]) != DImode)
9063 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9065 switch (GET_MODE (sh_compare_op0))
9068 emit_insn (gen_cmpeqsi_media (operands[0],
9069 sh_compare_op0, sh_compare_op1));
9073 emit_insn (gen_cmpeqdi_media (operands[0],
9074 sh_compare_op0, sh_compare_op1));
9078 if (! TARGET_SHMEDIA_FPU)
9080 emit_insn (gen_cmpeqsf_media (operands[0],
9081 sh_compare_op0, sh_compare_op1));
9085 if (! TARGET_SHMEDIA_FPU)
9087 emit_insn (gen_cmpeqdf_media (operands[0],
9088 sh_compare_op0, sh_compare_op1));
9096 if (sh_expand_t_scc (EQ, operands[0]))
9098 if (! currently_expanding_to_rtl)
9100 operands[1] = prepare_scc_operands (EQ);
9103 (define_expand "slt"
9104 [(set (match_operand:SI 0 "arith_reg_operand" "")
9111 if (GET_MODE (operands[0]) != DImode)
9112 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9113 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9114 if (sh_compare_op1 != const0_rtx)
9115 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9116 ? GET_MODE (sh_compare_op0)
9117 : GET_MODE (sh_compare_op1),
9120 switch (GET_MODE (sh_compare_op0))
9123 emit_insn (gen_cmpgtsi_media (operands[0],
9124 sh_compare_op1, sh_compare_op0));
9128 emit_insn (gen_cmpgtdi_media (operands[0],
9129 sh_compare_op1, sh_compare_op0));
9133 if (! TARGET_SHMEDIA_FPU)
9135 emit_insn (gen_cmpgtsf_media (operands[0],
9136 sh_compare_op1, sh_compare_op0));
9140 if (! TARGET_SHMEDIA_FPU)
9142 emit_insn (gen_cmpgtdf_media (operands[0],
9143 sh_compare_op1, sh_compare_op0));
9151 if (! currently_expanding_to_rtl)
9153 operands[1] = prepare_scc_operands (LT);
9156 (define_expand "sle"
9157 [(match_operand:SI 0 "arith_reg_operand" "")]
9161 rtx tmp = sh_compare_op0;
9165 if (GET_MODE (operands[0]) != DImode)
9166 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9167 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9168 if (sh_compare_op1 != const0_rtx)
9169 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9170 ? GET_MODE (sh_compare_op0)
9171 : GET_MODE (sh_compare_op1),
9174 switch (GET_MODE (sh_compare_op0))
9178 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9180 emit_insn (gen_cmpgtsi_media (tmp,
9181 sh_compare_op0, sh_compare_op1));
9182 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9188 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9190 emit_insn (gen_cmpgtdi_media (tmp,
9191 sh_compare_op0, sh_compare_op1));
9192 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9197 if (! TARGET_SHMEDIA_FPU)
9199 emit_insn (gen_cmpgesf_media (operands[0],
9200 sh_compare_op1, sh_compare_op0));
9204 if (! TARGET_SHMEDIA_FPU)
9206 emit_insn (gen_cmpgedf_media (operands[0],
9207 sh_compare_op1, sh_compare_op0));
9216 sh_compare_op0 = sh_compare_op1;
9217 sh_compare_op1 = tmp;
9218 emit_insn (gen_sge (operands[0]));
9222 (define_expand "sgt"
9223 [(set (match_operand:SI 0 "arith_reg_operand" "")
9230 if (GET_MODE (operands[0]) != DImode)
9231 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9232 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9233 if (sh_compare_op1 != const0_rtx)
9234 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9235 ? GET_MODE (sh_compare_op0)
9236 : GET_MODE (sh_compare_op1),
9239 switch (GET_MODE (sh_compare_op0))
9242 emit_insn (gen_cmpgtsi_media (operands[0],
9243 sh_compare_op0, sh_compare_op1));
9247 emit_insn (gen_cmpgtdi_media (operands[0],
9248 sh_compare_op0, sh_compare_op1));
9252 if (! TARGET_SHMEDIA_FPU)
9254 emit_insn (gen_cmpgtsf_media (operands[0],
9255 sh_compare_op0, sh_compare_op1));
9259 if (! TARGET_SHMEDIA_FPU)
9261 emit_insn (gen_cmpgtdf_media (operands[0],
9262 sh_compare_op0, sh_compare_op1));
9270 if (! currently_expanding_to_rtl)
9272 operands[1] = prepare_scc_operands (GT);
9275 (define_expand "sge"
9276 [(set (match_operand:SI 0 "arith_reg_operand" "")
9283 enum machine_mode mode = GET_MODE (sh_compare_op0);
9285 if ((mode) == VOIDmode)
9286 mode = GET_MODE (sh_compare_op1);
9287 if (GET_MODE (operands[0]) != DImode)
9288 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9289 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9290 if (sh_compare_op1 != const0_rtx)
9291 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9297 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9299 emit_insn (gen_cmpgtsi_media (tmp,
9300 sh_compare_op1, sh_compare_op0));
9301 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9307 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9309 emit_insn (gen_cmpgtdi_media (tmp,
9310 sh_compare_op1, sh_compare_op0));
9311 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9316 if (! TARGET_SHMEDIA_FPU)
9318 emit_insn (gen_cmpgesf_media (operands[0],
9319 sh_compare_op0, sh_compare_op1));
9323 if (! TARGET_SHMEDIA_FPU)
9325 emit_insn (gen_cmpgedf_media (operands[0],
9326 sh_compare_op0, sh_compare_op1));
9335 if (! currently_expanding_to_rtl)
9337 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9341 rtx lab = gen_label_rtx ();
9342 prepare_scc_operands (EQ);
9343 emit_jump_insn (gen_branch_true (lab));
9344 prepare_scc_operands (GT);
9346 emit_insn (gen_movt (operands[0]));
9349 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9352 operands[1] = prepare_scc_operands (GE);
9355 (define_expand "sgtu"
9356 [(set (match_operand:SI 0 "arith_reg_operand" "")
9363 if (GET_MODE (operands[0]) != DImode)
9364 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9365 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9366 if (sh_compare_op1 != const0_rtx)
9367 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9368 ? GET_MODE (sh_compare_op0)
9369 : GET_MODE (sh_compare_op1),
9372 emit_insn (gen_cmpgtudi_media (operands[0],
9373 sh_compare_op0, sh_compare_op1));
9376 if (! currently_expanding_to_rtl)
9378 operands[1] = prepare_scc_operands (GTU);
9381 (define_expand "sltu"
9382 [(set (match_operand:SI 0 "arith_reg_operand" "")
9389 if (GET_MODE (operands[0]) != DImode)
9390 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9391 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9392 if (sh_compare_op1 != const0_rtx)
9393 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9394 ? GET_MODE (sh_compare_op0)
9395 : GET_MODE (sh_compare_op1),
9398 emit_insn (gen_cmpgtudi_media (operands[0],
9399 sh_compare_op1, sh_compare_op0));
9402 if (! currently_expanding_to_rtl)
9404 operands[1] = prepare_scc_operands (LTU);
9407 (define_expand "sleu"
9408 [(set (match_operand:SI 0 "arith_reg_operand" "")
9417 if (GET_MODE (operands[0]) != DImode)
9418 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9419 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9420 if (sh_compare_op1 != const0_rtx)
9421 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9422 ? GET_MODE (sh_compare_op0)
9423 : GET_MODE (sh_compare_op1),
9426 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9428 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9429 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9433 if (! currently_expanding_to_rtl)
9435 operands[1] = prepare_scc_operands (LEU);
9438 (define_expand "sgeu"
9439 [(set (match_operand:SI 0 "arith_reg_operand" "")
9448 if (GET_MODE (operands[0]) != DImode)
9449 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9450 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9451 if (sh_compare_op1 != const0_rtx)
9452 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9453 ? GET_MODE (sh_compare_op0)
9454 : GET_MODE (sh_compare_op1),
9457 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9459 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9460 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9465 if (! currently_expanding_to_rtl)
9467 operands[1] = prepare_scc_operands (GEU);
9470 ;; sne moves the complement of the T reg to DEST like this:
9474 ;; This is better than xoring compare result with 1 because it does
9475 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9478 (define_expand "sne"
9479 [(set (match_dup 2) (const_int -1))
9480 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9481 (neg:SI (plus:SI (match_dup 1)
9484 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9493 if (GET_MODE (operands[0]) != DImode)
9494 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9496 if (! TARGET_SHMEDIA_FPU
9497 && GET_MODE (sh_compare_op0) != DImode
9498 && GET_MODE (sh_compare_op0) != SImode)
9501 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9502 if (sh_compare_op1 != const0_rtx)
9503 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9504 ? GET_MODE (sh_compare_op0)
9505 : GET_MODE (sh_compare_op1),
9508 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9510 emit_insn (gen_seq (tmp));
9511 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9516 if (sh_expand_t_scc (NE, operands[0]))
9518 if (! currently_expanding_to_rtl)
9520 operands[1] = prepare_scc_operands (EQ);
9521 operands[2] = gen_reg_rtx (SImode);
9524 (define_expand "sunordered"
9525 [(set (match_operand:DI 0 "arith_reg_operand" "")
9526 (unordered:DI (match_dup 1) (match_dup 2)))]
9527 "TARGET_SHMEDIA_FPU"
9530 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9531 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9534 ;; Use the same trick for FP sle / sge
9536 ;; Apart from the constant use and the T setting, this is like movt,
9537 ;; except that it uses the logically negated value of T, i.e.
9538 ;; operand[0] := T ? 0 : 1.
9539 (define_expand "movnegt"
9540 [(set (match_dup 2) (const_int -1))
9541 (parallel [(set (match_operand 0 "" "")
9542 (neg:SI (plus:SI (match_dup 1)
9545 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9548 "operands[2] = gen_reg_rtx (SImode);")
9550 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9551 ;; This prevents a regression that occurred when we switched from xor to
9555 [(set (match_operand:SI 0 "arith_reg_dest" "")
9556 (plus:SI (reg:SI T_REG)
9559 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9560 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9563 ;; -------------------------------------------------------------------------
9564 ;; Instructions to cope with inline literal tables
9565 ;; -------------------------------------------------------------------------
9567 ; 2 byte integer in line
9569 (define_insn "consttable_2"
9570 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9571 (match_operand 1 "" "")]
9576 if (operands[1] != const0_rtx)
9577 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9580 [(set_attr "length" "2")
9581 (set_attr "in_delay_slot" "no")])
9583 ; 4 byte integer in line
9585 (define_insn "consttable_4"
9586 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9587 (match_operand 1 "" "")]
9592 if (operands[1] != const0_rtx)
9593 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9596 [(set_attr "length" "4")
9597 (set_attr "in_delay_slot" "no")])
9599 ; 8 byte integer in line
9601 (define_insn "consttable_8"
9602 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9603 (match_operand 1 "" "")]
9608 if (operands[1] != const0_rtx)
9609 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9612 [(set_attr "length" "8")
9613 (set_attr "in_delay_slot" "no")])
9615 ; 4 byte floating point
9617 (define_insn "consttable_sf"
9618 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9619 (match_operand 1 "" "")]
9624 if (operands[1] != const0_rtx)
9627 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9628 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9632 [(set_attr "length" "4")
9633 (set_attr "in_delay_slot" "no")])
9635 ; 8 byte floating point
9637 (define_insn "consttable_df"
9638 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9639 (match_operand 1 "" "")]
9644 if (operands[1] != const0_rtx)
9647 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9648 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9652 [(set_attr "length" "8")
9653 (set_attr "in_delay_slot" "no")])
9655 ;; Alignment is needed for some constant tables; it may also be added for
9656 ;; Instructions at the start of loops, or after unconditional branches.
9657 ;; ??? We would get more accurate lengths if we did instruction
9658 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9659 ;; here is too conservative.
9661 ; align to a two byte boundary
9663 (define_expand "align_2"
9664 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9668 ; align to a four byte boundary
9669 ;; align_4 and align_log are instructions for the starts of loops, or
9670 ;; after unconditional branches, which may take up extra room.
9672 (define_expand "align_4"
9673 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9677 ; align to a cache line boundary
9679 (define_insn "align_log"
9680 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9683 [(set_attr "length" "0")
9684 (set_attr "in_delay_slot" "no")])
9686 ; emitted at the end of the literal table, used to emit the
9687 ; 32bit branch labels if needed.
9689 (define_insn "consttable_end"
9690 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9692 "* return output_jump_label_table ();"
9693 [(set_attr "in_delay_slot" "no")])
9695 ; emitted at the end of the window in the literal table.
9697 (define_insn "consttable_window_end"
9698 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9701 [(set_attr "length" "0")
9702 (set_attr "in_delay_slot" "no")])
9704 ;; -------------------------------------------------------------------------
9706 ;; -------------------------------------------------------------------------
9708 ;; String/block move insn.
9710 (define_expand "movmemsi"
9711 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9712 (mem:BLK (match_operand:BLK 1 "" "")))
9713 (use (match_operand:SI 2 "nonmemory_operand" ""))
9714 (use (match_operand:SI 3 "immediate_operand" ""))
9715 (clobber (reg:SI PR_REG))
9716 (clobber (reg:SI R4_REG))
9717 (clobber (reg:SI R5_REG))
9718 (clobber (reg:SI R0_REG))])]
9719 "TARGET_SH1 && ! TARGET_SH5"
9722 if(expand_block_move (operands))
9727 (define_insn "block_move_real"
9728 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9729 (mem:BLK (reg:SI R5_REG)))
9730 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9731 (clobber (reg:SI PR_REG))
9732 (clobber (reg:SI R0_REG))])]
9733 "TARGET_SH1 && ! TARGET_HARD_SH4"
9735 [(set_attr "type" "sfunc")
9736 (set_attr "needs_delay_slot" "yes")])
9738 (define_insn "block_lump_real"
9739 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9740 (mem:BLK (reg:SI R5_REG)))
9741 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9742 (use (reg:SI R6_REG))
9743 (clobber (reg:SI PR_REG))
9744 (clobber (reg:SI T_REG))
9745 (clobber (reg:SI R4_REG))
9746 (clobber (reg:SI R5_REG))
9747 (clobber (reg:SI R6_REG))
9748 (clobber (reg:SI R0_REG))])]
9749 "TARGET_SH1 && ! TARGET_HARD_SH4"
9751 [(set_attr "type" "sfunc")
9752 (set_attr "needs_delay_slot" "yes")])
9754 (define_insn "block_move_real_i4"
9755 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9756 (mem:BLK (reg:SI R5_REG)))
9757 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9758 (clobber (reg:SI PR_REG))
9759 (clobber (reg:SI R0_REG))
9760 (clobber (reg:SI R1_REG))
9761 (clobber (reg:SI R2_REG))])]
9764 [(set_attr "type" "sfunc")
9765 (set_attr "needs_delay_slot" "yes")])
9767 (define_insn "block_lump_real_i4"
9768 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9769 (mem:BLK (reg:SI R5_REG)))
9770 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9771 (use (reg:SI R6_REG))
9772 (clobber (reg:SI PR_REG))
9773 (clobber (reg:SI T_REG))
9774 (clobber (reg:SI R4_REG))
9775 (clobber (reg:SI R5_REG))
9776 (clobber (reg:SI R6_REG))
9777 (clobber (reg:SI R0_REG))
9778 (clobber (reg:SI R1_REG))
9779 (clobber (reg:SI R2_REG))
9780 (clobber (reg:SI R3_REG))])]
9783 [(set_attr "type" "sfunc")
9784 (set_attr "needs_delay_slot" "yes")])
9786 ;; -------------------------------------------------------------------------
9787 ;; Floating point instructions.
9788 ;; -------------------------------------------------------------------------
9790 ;; ??? All patterns should have a type attribute.
9792 (define_expand "movpsi"
9793 [(set (match_operand:PSI 0 "register_operand" "")
9794 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9795 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9798 ;; The c / m alternative is a fake to guide reload to load directly into
9799 ;; fpscr, since reload doesn't know how to use post-increment.
9800 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9801 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9802 ;; predicate after reload.
9803 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9804 ;; like a mac -> gpr move.
9805 (define_insn "fpu_switch"
9806 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9807 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9809 && (! reload_completed
9810 || true_regnum (operands[0]) != FPSCR_REG
9811 || GET_CODE (operands[1]) != MEM
9812 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9814 ! precision stays the same
9823 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9824 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9827 [(set (reg:PSI FPSCR_REG)
9828 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9829 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9832 rtx fpscr, mem, new_insn;
9834 fpscr = SET_DEST (PATTERN (curr_insn));
9835 mem = SET_SRC (PATTERN (curr_insn));
9836 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9838 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9839 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9844 [(set (reg:PSI FPSCR_REG)
9845 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9846 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9847 && (flag_peephole2 ? flow2_completed : reload_completed)"
9850 rtx fpscr, mem, new_insn;
9852 fpscr = SET_DEST (PATTERN (curr_insn));
9853 mem = SET_SRC (PATTERN (curr_insn));
9854 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9856 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9857 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9859 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9860 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9864 ;; ??? This uses the fp unit, but has no type indicating that.
9865 ;; If we did that, this would either give a bogus latency or introduce
9866 ;; a bogus FIFO constraint.
9867 ;; Since this insn is currently only used for prologues/epilogues,
9868 ;; it is probably best to claim no function unit, which matches the
9870 (define_insn "toggle_sz"
9871 [(set (reg:PSI FPSCR_REG)
9872 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9873 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9875 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9877 ;; There's no way we can use it today, since optimize mode switching
9878 ;; doesn't enable us to know from which mode we're switching to the
9879 ;; mode it requests, to tell whether we can use a relative mode switch
9880 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9882 (define_insn "toggle_pr"
9883 [(set (reg:PSI FPSCR_REG)
9884 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9885 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9887 [(set_attr "type" "fp")])
9889 (define_expand "addsf3"
9890 [(set (match_operand:SF 0 "arith_reg_operand" "")
9891 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9892 (match_operand:SF 2 "arith_reg_operand" "")))]
9893 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9898 expand_sf_binop (&gen_addsf3_i, operands);
9903 (define_insn "*addsf3_media"
9904 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9905 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9906 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9907 "TARGET_SHMEDIA_FPU"
9909 [(set_attr "type" "fparith_media")])
9911 (define_insn_and_split "unary_sf_op"
9912 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9917 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9918 (match_operator:SF 2 "unary_float_operator"
9919 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9920 (parallel [(match_operand 4
9921 "const_int_operand" "n")]))]))
9922 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9923 "TARGET_SHMEDIA_FPU"
9925 "TARGET_SHMEDIA_FPU && reload_completed"
9926 [(set (match_dup 5) (match_dup 6))]
9929 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9930 rtx op1 = gen_rtx_REG (SFmode,
9931 (true_regnum (operands[1])
9932 + (INTVAL (operands[4]) ^ endian)));
9934 operands[7] = gen_rtx_REG (SFmode,
9935 (true_regnum (operands[0])
9936 + (INTVAL (operands[3]) ^ endian)));
9937 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9939 [(set_attr "type" "fparith_media")])
9941 (define_insn_and_split "binary_sf_op"
9942 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9947 (parallel [(match_operand 7 "const_int_operand" "n")]))
9948 (match_operator:SF 3 "binary_float_operator"
9949 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9950 (parallel [(match_operand 5
9951 "const_int_operand" "n")]))
9952 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9953 (parallel [(match_operand 6
9954 "const_int_operand" "n")]))]))
9955 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9956 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9958 "&& reload_completed"
9959 [(set (match_dup 8) (match_dup 9))]
9962 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9963 rtx op1 = gen_rtx_REG (SFmode,
9964 (true_regnum (operands[1])
9965 + (INTVAL (operands[5]) ^ endian)));
9966 rtx op2 = gen_rtx_REG (SFmode,
9967 (true_regnum (operands[2])
9968 + (INTVAL (operands[6]) ^ endian)));
9970 operands[8] = gen_rtx_REG (SFmode,
9971 (true_regnum (operands[0])
9972 + (INTVAL (operands[4]) ^ endian)));
9973 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9975 [(set_attr "type" "fparith_media")])
9977 (define_insn "addsf3_i"
9978 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9979 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9980 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9981 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9984 [(set_attr "type" "fp")
9985 (set_attr "fp_mode" "single")])
9987 (define_expand "subsf3"
9988 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9989 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9990 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9991 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9996 expand_sf_binop (&gen_subsf3_i, operands);
10001 (define_insn "*subsf3_media"
10002 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10003 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10004 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10005 "TARGET_SHMEDIA_FPU"
10006 "fsub.s %1, %2, %0"
10007 [(set_attr "type" "fparith_media")])
10009 (define_insn "subsf3_i"
10010 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10011 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10012 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10013 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10016 [(set_attr "type" "fp")
10017 (set_attr "fp_mode" "single")])
10019 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10020 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
10021 ;; mixed-precision SH4 targets. To allow it to be still generated for the
10022 ;; SH3E, we use a separate insn for SH3E mulsf3.
10024 (define_expand "mulsf3"
10025 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10026 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10027 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10028 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10031 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10032 expand_sf_binop (&gen_mulsf3_i4, operands);
10033 else if (TARGET_SH2E)
10034 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10035 if (! TARGET_SHMEDIA)
10039 (define_insn "*mulsf3_media"
10040 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10041 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10042 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10043 "TARGET_SHMEDIA_FPU"
10044 "fmul.s %1, %2, %0"
10045 [(set_attr "type" "fparith_media")])
10047 (define_insn "mulsf3_i4"
10048 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10049 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10050 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10051 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10054 [(set_attr "type" "fp")
10055 (set_attr "fp_mode" "single")])
10057 (define_insn "mulsf3_ie"
10058 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10059 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10060 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10061 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10063 [(set_attr "type" "fp")])
10065 (define_insn "mac_media"
10066 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10067 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10068 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10069 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10070 "TARGET_SHMEDIA_FPU"
10071 "fmac.s %1, %2, %0"
10072 [(set_attr "type" "fparith_media")])
10074 (define_insn "*macsf3"
10075 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10076 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10077 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10078 (match_operand:SF 3 "arith_reg_operand" "0")))
10079 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10080 "TARGET_SH2E && ! TARGET_SH4"
10082 [(set_attr "type" "fp")
10083 (set_attr "fp_mode" "single")])
10085 (define_expand "divsf3"
10086 [(set (match_operand:SF 0 "arith_reg_operand" "")
10087 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10088 (match_operand:SF 2 "arith_reg_operand" "")))]
10089 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10094 expand_sf_binop (&gen_divsf3_i, operands);
10099 (define_insn "*divsf3_media"
10100 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10101 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10102 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10103 "TARGET_SHMEDIA_FPU"
10104 "fdiv.s %1, %2, %0"
10105 [(set_attr "type" "fdiv_media")])
10107 (define_insn "divsf3_i"
10108 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10109 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10110 (match_operand:SF 2 "arith_reg_operand" "f")))
10111 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10114 [(set_attr "type" "fdiv")
10115 (set_attr "fp_mode" "single")])
10117 (define_insn "floatdisf2"
10118 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10119 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10120 "TARGET_SHMEDIA_FPU"
10122 [(set_attr "type" "fpconv_media")])
10124 (define_expand "floatsisf2"
10125 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10126 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10127 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10130 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10132 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10137 (define_insn "*floatsisf2_media"
10138 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10139 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10140 "TARGET_SHMEDIA_FPU"
10142 [(set_attr "type" "fpconv_media")])
10144 (define_insn "floatsisf2_i4"
10145 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10146 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10147 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10148 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10150 [(set_attr "type" "fp")
10151 (set_attr "fp_mode" "single")])
10153 (define_insn "*floatsisf2_ie"
10154 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10155 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10156 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10158 [(set_attr "type" "fp")])
10160 (define_insn "fix_truncsfdi2"
10161 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10162 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10163 "TARGET_SHMEDIA_FPU"
10165 [(set_attr "type" "fpconv_media")])
10167 (define_expand "fix_truncsfsi2"
10168 [(set (match_operand:SI 0 "fpul_operand" "=y")
10169 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10170 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10173 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10175 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10180 (define_insn "*fix_truncsfsi2_media"
10181 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10182 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10183 "TARGET_SHMEDIA_FPU"
10185 [(set_attr "type" "fpconv_media")])
10187 (define_insn "fix_truncsfsi2_i4"
10188 [(set (match_operand:SI 0 "fpul_operand" "=y")
10189 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10190 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10191 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10193 [(set_attr "type" "ftrc_s")
10194 (set_attr "fp_mode" "single")])
10196 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10197 ;; fix_truncsfsi2_i4.
10198 ;; (define_insn "fix_truncsfsi2_i4_2"
10199 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10200 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10201 ;; (use (reg:PSI FPSCR_REG))
10202 ;; (clobber (reg:SI FPUL_REG))]
10205 ;; [(set_attr "length" "4")
10206 ;; (set_attr "fp_mode" "single")])
10209 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10210 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10211 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10212 ;; (clobber (reg:SI FPUL_REG))]
10214 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10215 ;; (use (match_dup 2))])
10216 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10218 (define_insn "*fixsfsi"
10219 [(set (match_operand:SI 0 "fpul_operand" "=y")
10220 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10221 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10223 [(set_attr "type" "fp")])
10225 (define_insn "cmpgtsf_t"
10226 [(set (reg:SI T_REG)
10227 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10228 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10229 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10231 [(set_attr "type" "fp")
10232 (set_attr "fp_mode" "single")])
10234 (define_insn "cmpeqsf_t"
10235 [(set (reg:SI T_REG)
10236 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10237 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10238 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10240 [(set_attr "type" "fp")
10241 (set_attr "fp_mode" "single")])
10243 (define_insn "ieee_ccmpeqsf_t"
10244 [(set (reg:SI T_REG)
10245 (ior:SI (reg:SI T_REG)
10246 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10247 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10248 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10249 "* return output_ieee_ccmpeq (insn, operands);"
10250 [(set_attr "length" "4")])
10253 (define_insn "cmpgtsf_t_i4"
10254 [(set (reg:SI T_REG)
10255 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10256 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10257 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10258 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10260 [(set_attr "type" "fp")
10261 (set_attr "fp_mode" "single")])
10263 (define_insn "cmpeqsf_t_i4"
10264 [(set (reg:SI T_REG)
10265 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10266 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10267 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10268 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10270 [(set_attr "type" "fp")
10271 (set_attr "fp_mode" "single")])
10273 (define_insn "*ieee_ccmpeqsf_t_4"
10274 [(set (reg:SI T_REG)
10275 (ior:SI (reg:SI T_REG)
10276 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10277 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10278 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10279 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10280 "* return output_ieee_ccmpeq (insn, operands);"
10281 [(set_attr "length" "4")
10282 (set_attr "fp_mode" "single")])
10284 (define_insn "cmpeqsf_media"
10285 [(set (match_operand:DI 0 "register_operand" "=r")
10286 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10287 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10288 "TARGET_SHMEDIA_FPU"
10289 "fcmpeq.s %1, %2, %0"
10290 [(set_attr "type" "fcmp_media")])
10292 (define_insn "cmpsieqsf_media"
10293 [(set (match_operand:SI 0 "register_operand" "=r")
10294 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10295 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10296 "TARGET_SHMEDIA_FPU"
10297 "fcmpeq.s %1, %2, %0"
10298 [(set_attr "type" "fcmp_media")])
10300 (define_insn "cmpgtsf_media"
10301 [(set (match_operand:DI 0 "register_operand" "=r")
10302 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10303 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10304 "TARGET_SHMEDIA_FPU"
10305 "fcmpgt.s %1, %2, %0"
10306 [(set_attr "type" "fcmp_media")])
10308 (define_insn "cmpgesf_media"
10309 [(set (match_operand:DI 0 "register_operand" "=r")
10310 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10311 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10312 "TARGET_SHMEDIA_FPU"
10313 "fcmpge.s %1, %2, %0"
10314 [(set_attr "type" "fcmp_media")])
10316 (define_insn "cmpunsf_media"
10317 [(set (match_operand:DI 0 "register_operand" "=r")
10318 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10319 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10320 "TARGET_SHMEDIA_FPU"
10321 "fcmpun.s %1, %2, %0"
10322 [(set_attr "type" "fcmp_media")])
10324 (define_expand "cmpsf"
10325 [(set (reg:SI T_REG)
10326 (compare (match_operand:SF 0 "arith_operand" "")
10327 (match_operand:SF 1 "arith_operand" "")))]
10328 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10331 sh_compare_op0 = operands[0];
10332 sh_compare_op1 = operands[1];
10336 (define_expand "negsf2"
10337 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10338 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10339 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10344 expand_sf_unop (&gen_negsf2_i, operands);
10349 (define_insn "*negsf2_media"
10350 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10351 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10352 "TARGET_SHMEDIA_FPU"
10354 [(set_attr "type" "fmove_media")])
10356 (define_insn "negsf2_i"
10357 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10358 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10359 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10362 [(set_attr "type" "fmove")
10363 (set_attr "fp_mode" "single")])
10365 (define_expand "sqrtsf2"
10366 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10367 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10368 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10373 expand_sf_unop (&gen_sqrtsf2_i, operands);
10378 (define_insn "*sqrtsf2_media"
10379 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10380 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10381 "TARGET_SHMEDIA_FPU"
10383 [(set_attr "type" "fdiv_media")])
10385 (define_insn "sqrtsf2_i"
10386 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10387 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10388 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10391 [(set_attr "type" "fdiv")
10392 (set_attr "fp_mode" "single")])
10394 (define_insn "rsqrtsf2"
10395 [(set (match_operand:SF 0 "register_operand" "=f")
10396 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10397 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10398 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10399 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10400 && operands[1] == CONST1_RTX (SFmode)"
10402 [(set_attr "type" "fsrra")
10403 (set_attr "fp_mode" "single")])
10405 (define_insn "fsca"
10406 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10408 (unspec:SF [(mult:SF
10409 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10410 (match_operand:SF 2 "immediate_operand" "i"))
10412 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10414 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10415 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10416 && operands[2] == sh_fsca_int2sf ()"
10418 [(set_attr "type" "fsca")
10419 (set_attr "fp_mode" "single")])
10421 (define_expand "sinsf2"
10422 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10423 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10425 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10428 rtx scaled = gen_reg_rtx (SFmode);
10429 rtx truncated = gen_reg_rtx (SImode);
10430 rtx fsca = gen_reg_rtx (V2SFmode);
10431 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10433 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10434 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10435 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10436 get_fpscr_rtx ()));
10437 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10441 (define_expand "cossf2"
10442 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10443 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10445 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10448 rtx scaled = gen_reg_rtx (SFmode);
10449 rtx truncated = gen_reg_rtx (SImode);
10450 rtx fsca = gen_reg_rtx (V2SFmode);
10451 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10453 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10454 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10455 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10456 get_fpscr_rtx ()));
10457 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10461 (define_expand "sindf2"
10462 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10463 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10465 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10468 rtx scaled = gen_reg_rtx (DFmode);
10469 rtx truncated = gen_reg_rtx (SImode);
10470 rtx fsca = gen_reg_rtx (V2SFmode);
10471 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10472 rtx sfresult = gen_reg_rtx (SFmode);
10474 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10475 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10476 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10477 get_fpscr_rtx ()));
10478 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10479 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10483 (define_expand "cosdf2"
10484 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10485 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10487 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10490 rtx scaled = gen_reg_rtx (DFmode);
10491 rtx truncated = gen_reg_rtx (SImode);
10492 rtx fsca = gen_reg_rtx (V2SFmode);
10493 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10494 rtx sfresult = gen_reg_rtx (SFmode);
10496 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10497 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10498 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10499 get_fpscr_rtx ()));
10500 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10501 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10505 (define_expand "abssf2"
10506 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10507 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10508 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10513 expand_sf_unop (&gen_abssf2_i, operands);
10518 (define_insn "*abssf2_media"
10519 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10520 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10521 "TARGET_SHMEDIA_FPU"
10523 [(set_attr "type" "fmove_media")])
10525 (define_insn "abssf2_i"
10526 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10527 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10528 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10531 [(set_attr "type" "fmove")
10532 (set_attr "fp_mode" "single")])
10534 (define_expand "adddf3"
10535 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10536 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10537 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10538 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10541 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10543 expand_df_binop (&gen_adddf3_i, operands);
10548 (define_insn "*adddf3_media"
10549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10550 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10551 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10552 "TARGET_SHMEDIA_FPU"
10553 "fadd.d %1, %2, %0"
10554 [(set_attr "type" "dfparith_media")])
10556 (define_insn "adddf3_i"
10557 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10558 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10559 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10560 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10561 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10563 [(set_attr "type" "dfp_arith")
10564 (set_attr "fp_mode" "double")])
10566 (define_expand "subdf3"
10567 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10568 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10569 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10570 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10573 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10575 expand_df_binop (&gen_subdf3_i, operands);
10580 (define_insn "*subdf3_media"
10581 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10582 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10583 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10584 "TARGET_SHMEDIA_FPU"
10585 "fsub.d %1, %2, %0"
10586 [(set_attr "type" "dfparith_media")])
10588 (define_insn "subdf3_i"
10589 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10590 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10591 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10592 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10593 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10595 [(set_attr "type" "dfp_arith")
10596 (set_attr "fp_mode" "double")])
10598 (define_expand "muldf3"
10599 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10600 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10601 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10602 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10605 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10607 expand_df_binop (&gen_muldf3_i, operands);
10612 (define_insn "*muldf3_media"
10613 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10614 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10615 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10616 "TARGET_SHMEDIA_FPU"
10617 "fmul.d %1, %2, %0"
10618 [(set_attr "type" "dfmul_media")])
10620 (define_insn "muldf3_i"
10621 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10622 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10623 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10624 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10625 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10627 [(set_attr "type" "dfp_arith")
10628 (set_attr "fp_mode" "double")])
10630 (define_expand "divdf3"
10631 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10632 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10633 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10634 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10637 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10639 expand_df_binop (&gen_divdf3_i, operands);
10644 (define_insn "*divdf3_media"
10645 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10646 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10647 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10648 "TARGET_SHMEDIA_FPU"
10649 "fdiv.d %1, %2, %0"
10650 [(set_attr "type" "dfdiv_media")])
10652 (define_insn "divdf3_i"
10653 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10654 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10655 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10656 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10657 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10659 [(set_attr "type" "dfdiv")
10660 (set_attr "fp_mode" "double")])
10662 (define_insn "floatdidf2"
10663 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10664 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10665 "TARGET_SHMEDIA_FPU"
10667 [(set_attr "type" "dfpconv_media")])
10669 (define_expand "floatsidf2"
10670 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10671 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10672 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10675 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10677 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10678 get_fpscr_rtx ()));
10683 (define_insn "*floatsidf2_media"
10684 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10685 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10686 "TARGET_SHMEDIA_FPU"
10688 [(set_attr "type" "dfpconv_media")])
10690 (define_insn "floatsidf2_i"
10691 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10692 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10693 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10694 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10696 [(set_attr "type" "dfp_conv")
10697 (set_attr "fp_mode" "double")])
10699 (define_insn "fix_truncdfdi2"
10700 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10701 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10702 "TARGET_SHMEDIA_FPU"
10704 [(set_attr "type" "dfpconv_media")])
10706 (define_expand "fix_truncdfsi2"
10707 [(set (match_operand:SI 0 "fpul_operand" "")
10708 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10709 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10712 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10714 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10715 get_fpscr_rtx ()));
10720 (define_insn "*fix_truncdfsi2_media"
10721 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10722 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10723 "TARGET_SHMEDIA_FPU"
10725 [(set_attr "type" "dfpconv_media")])
10727 (define_insn "fix_truncdfsi2_i"
10728 [(set (match_operand:SI 0 "fpul_operand" "=y")
10729 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10730 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10731 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10733 [(set_attr "type" "dfp_conv")
10734 (set_attr "dfp_comp" "no")
10735 (set_attr "fp_mode" "double")])
10737 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10738 ;; fix_truncdfsi2_i.
10739 ;; (define_insn "fix_truncdfsi2_i4"
10740 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10741 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10742 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10743 ;; (clobber (reg:SI FPUL_REG))]
10746 ;; [(set_attr "length" "4")
10747 ;; (set_attr "fp_mode" "double")])
10750 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10751 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10752 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10753 ;; (clobber (reg:SI FPUL_REG))]
10755 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10756 ;; (use (match_dup 2))])
10757 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10759 (define_insn "cmpgtdf_t"
10760 [(set (reg:SI T_REG)
10761 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10762 (match_operand:DF 1 "arith_reg_operand" "f")))
10763 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10764 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10766 [(set_attr "type" "dfp_cmp")
10767 (set_attr "fp_mode" "double")])
10769 (define_insn "cmpeqdf_t"
10770 [(set (reg:SI T_REG)
10771 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10772 (match_operand:DF 1 "arith_reg_operand" "f")))
10773 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10774 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10776 [(set_attr "type" "dfp_cmp")
10777 (set_attr "fp_mode" "double")])
10779 (define_insn "*ieee_ccmpeqdf_t"
10780 [(set (reg:SI T_REG)
10781 (ior:SI (reg:SI T_REG)
10782 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10783 (match_operand:DF 1 "arith_reg_operand" "f"))))
10784 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10785 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10786 "* return output_ieee_ccmpeq (insn, operands);"
10787 [(set_attr "length" "4")
10788 (set_attr "fp_mode" "double")])
10790 (define_insn "cmpeqdf_media"
10791 [(set (match_operand:DI 0 "register_operand" "=r")
10792 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10793 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10794 "TARGET_SHMEDIA_FPU"
10795 "fcmpeq.d %1,%2,%0"
10796 [(set_attr "type" "fcmp_media")])
10798 (define_insn "cmpsieqdf_media"
10799 [(set (match_operand:SI 0 "register_operand" "=r")
10800 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10801 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10802 "TARGET_SHMEDIA_FPU"
10803 "fcmpeq.d %1,%2,%0"
10804 [(set_attr "type" "fcmp_media")])
10806 (define_insn "cmpgtdf_media"
10807 [(set (match_operand:DI 0 "register_operand" "=r")
10808 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10809 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10810 "TARGET_SHMEDIA_FPU"
10811 "fcmpgt.d %1,%2,%0"
10812 [(set_attr "type" "fcmp_media")])
10814 (define_insn "cmpgedf_media"
10815 [(set (match_operand:DI 0 "register_operand" "=r")
10816 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10817 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10818 "TARGET_SHMEDIA_FPU"
10819 "fcmpge.d %1,%2,%0"
10820 [(set_attr "type" "fcmp_media")])
10822 (define_insn "cmpundf_media"
10823 [(set (match_operand:DI 0 "register_operand" "=r")
10824 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10825 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10826 "TARGET_SHMEDIA_FPU"
10827 "fcmpun.d %1,%2,%0"
10828 [(set_attr "type" "fcmp_media")])
10830 (define_expand "cmpdf"
10831 [(set (reg:SI T_REG)
10832 (compare (match_operand:DF 0 "arith_operand" "")
10833 (match_operand:DF 1 "arith_operand" "")))]
10834 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10837 sh_compare_op0 = operands[0];
10838 sh_compare_op1 = operands[1];
10842 (define_expand "negdf2"
10843 [(set (match_operand:DF 0 "arith_reg_operand" "")
10844 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10845 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10848 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10850 expand_df_unop (&gen_negdf2_i, operands);
10855 (define_insn "*negdf2_media"
10856 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10857 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10858 "TARGET_SHMEDIA_FPU"
10860 [(set_attr "type" "fmove_media")])
10862 (define_insn "negdf2_i"
10863 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10864 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10865 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10866 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10868 [(set_attr "type" "fmove")
10869 (set_attr "fp_mode" "double")])
10871 (define_expand "sqrtdf2"
10872 [(set (match_operand:DF 0 "arith_reg_operand" "")
10873 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10874 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10877 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10879 expand_df_unop (&gen_sqrtdf2_i, operands);
10884 (define_insn "*sqrtdf2_media"
10885 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10886 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10887 "TARGET_SHMEDIA_FPU"
10889 [(set_attr "type" "dfdiv_media")])
10891 (define_insn "sqrtdf2_i"
10892 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10893 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10894 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10895 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10897 [(set_attr "type" "dfdiv")
10898 (set_attr "fp_mode" "double")])
10900 (define_expand "absdf2"
10901 [(set (match_operand:DF 0 "arith_reg_operand" "")
10902 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10903 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10906 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10908 expand_df_unop (&gen_absdf2_i, operands);
10913 (define_insn "*absdf2_media"
10914 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10915 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10916 "TARGET_SHMEDIA_FPU"
10918 [(set_attr "type" "fmove_media")])
10920 (define_insn "absdf2_i"
10921 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10922 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10923 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10924 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10926 [(set_attr "type" "fmove")
10927 (set_attr "fp_mode" "double")])
10929 (define_expand "extendsfdf2"
10930 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10931 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10932 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10935 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10937 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10938 get_fpscr_rtx ()));
10943 (define_insn "*extendsfdf2_media"
10944 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10945 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10946 "TARGET_SHMEDIA_FPU"
10948 [(set_attr "type" "dfpconv_media")])
10950 (define_insn "extendsfdf2_i4"
10951 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10952 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10953 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10954 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10956 [(set_attr "type" "fp")
10957 (set_attr "fp_mode" "double")])
10959 (define_expand "truncdfsf2"
10960 [(set (match_operand:SF 0 "fpul_operand" "")
10961 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10962 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10965 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10967 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10968 get_fpscr_rtx ()));
10973 (define_insn "*truncdfsf2_media"
10974 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10975 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10976 "TARGET_SHMEDIA_FPU"
10978 [(set_attr "type" "dfpconv_media")])
10980 (define_insn "truncdfsf2_i4"
10981 [(set (match_operand:SF 0 "fpul_operand" "=y")
10982 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10983 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10984 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10986 [(set_attr "type" "fp")
10987 (set_attr "fp_mode" "double")])
10989 ;; Bit field extract patterns. These give better code for packed bitfields,
10990 ;; because they allow auto-increment addresses to be generated.
10992 (define_expand "insv"
10993 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10994 (match_operand:SI 1 "immediate_operand" "")
10995 (match_operand:SI 2 "immediate_operand" ""))
10996 (match_operand:SI 3 "general_operand" ""))]
10997 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11000 rtx addr_target, orig_address, shift_reg, qi_val;
11001 HOST_WIDE_INT bitsize, size, v = 0;
11002 rtx x = operands[3];
11004 /* ??? expmed doesn't care for non-register predicates. */
11005 if (! memory_operand (operands[0], VOIDmode)
11006 || ! immediate_operand (operands[1], VOIDmode)
11007 || ! immediate_operand (operands[2], VOIDmode)
11008 || ! general_operand (x, VOIDmode))
11010 /* If this isn't a 16 / 24 / 32 bit field, or if
11011 it doesn't start on a byte boundary, then fail. */
11012 bitsize = INTVAL (operands[1]);
11013 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11014 || (INTVAL (operands[2]) % 8) != 0)
11017 size = bitsize / 8;
11018 orig_address = XEXP (operands[0], 0);
11019 shift_reg = gen_reg_rtx (SImode);
11020 if (GET_CODE (x) == CONST_INT)
11023 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11027 emit_insn (gen_movsi (shift_reg, operands[3]));
11028 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11030 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11032 operands[0] = replace_equiv_address (operands[0], addr_target);
11033 emit_insn (gen_movqi (operands[0], qi_val));
11037 if (GET_CODE (x) == CONST_INT)
11039 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11042 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11043 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11045 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11046 emit_insn (gen_movqi (operands[0], qi_val));
11052 (define_insn "movua"
11053 [(set (match_operand:SI 0 "register_operand" "=z")
11054 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11055 (const_int 32) (const_int 0)))]
11058 [(set_attr "type" "movua")])
11060 ;; We shouldn't need this, but cse replaces increments with references
11061 ;; to other regs before flow has a chance to create post_inc
11062 ;; addressing modes, and only postreload's cse_move2add brings the
11063 ;; increments back to a usable form.
11065 [(set (match_operand:SI 0 "register_operand" "")
11066 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11067 (const_int 32) (const_int 0)))
11068 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11069 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11070 [(set (match_operand:SI 0 "register_operand" "")
11071 (sign_extract:SI (mem:SI (post_inc:SI
11072 (match_operand:SI 1 "register_operand" "")))
11073 (const_int 32) (const_int 0)))]
11076 (define_expand "extv"
11077 [(set (match_operand:SI 0 "register_operand" "")
11078 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11079 (match_operand 2 "const_int_operand" "")
11080 (match_operand 3 "const_int_operand" "")))]
11083 if (TARGET_SH4A_ARCH
11084 && INTVAL (operands[2]) == 32
11085 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11086 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11088 emit_insn (gen_movua (operands[0],
11089 adjust_address (operands[1], SImode, 0)));
11096 (define_expand "extzv"
11097 [(set (match_operand:SI 0 "register_operand" "")
11098 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11099 (match_operand 2 "const_int_operand" "")
11100 (match_operand 3 "const_int_operand" "")))]
11103 if (TARGET_SH4A_ARCH
11104 && INTVAL (operands[2]) == 32
11105 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11106 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11108 emit_insn (gen_movua (operands[0],
11109 adjust_address (operands[1], SImode, 0)));
11117 ;; -------------------------------------------------------------------------
11119 ;; -------------------------------------------------------------------------
11121 ;; This matches cases where a stack pointer increment at the start of the
11122 ;; epilogue combines with a stack slot read loading the return value.
11125 [(set (match_operand:SI 0 "arith_reg_operand" "")
11126 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11127 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11128 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11131 ;; See the comment on the dt combiner pattern above.
11134 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11135 (plus:SI (match_dup 0)
11137 (set (reg:SI T_REG)
11138 (eq:SI (match_dup 0)
11143 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11144 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11145 ;; reload when the constant is too large for a reg+offset address.
11147 ;; ??? We would get much better code if this was done in reload. This would
11148 ;; require modifying find_reloads_address to recognize that if the constant
11149 ;; is out-of-range for an immediate add, then we get better code by reloading
11150 ;; the constant into a register than by reloading the sum into a register,
11151 ;; since the former is one instruction shorter if the address does not need
11152 ;; to be offsettable. Unfortunately this does not work, because there is
11153 ;; only one register, r0, that can be used as an index register. This register
11154 ;; is also the function return value register. So, if we try to force reload
11155 ;; to use double-reg addresses, then we end up with some instructions that
11156 ;; need to use r0 twice. The only way to fix this is to change the calling
11157 ;; convention so that r0 is not used to return values.
11160 [(set (match_operand:SI 0 "register_operand" "=r")
11161 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11162 (set (mem:SI (match_dup 0))
11163 (match_operand:SI 2 "general_movsrc_operand" ""))]
11164 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11165 "mov.l %2,@(%0,%1)")
11168 [(set (match_operand:SI 0 "register_operand" "=r")
11169 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11170 (set (match_operand:SI 2 "general_movdst_operand" "")
11171 (mem:SI (match_dup 0)))]
11172 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11173 "mov.l @(%0,%1),%2")
11176 [(set (match_operand:SI 0 "register_operand" "=r")
11177 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11178 (set (mem:HI (match_dup 0))
11179 (match_operand:HI 2 "general_movsrc_operand" ""))]
11180 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11181 "mov.w %2,@(%0,%1)")
11184 [(set (match_operand:SI 0 "register_operand" "=r")
11185 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11186 (set (match_operand:HI 2 "general_movdst_operand" "")
11187 (mem:HI (match_dup 0)))]
11188 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11189 "mov.w @(%0,%1),%2")
11192 [(set (match_operand:SI 0 "register_operand" "=r")
11193 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11194 (set (mem:QI (match_dup 0))
11195 (match_operand:QI 2 "general_movsrc_operand" ""))]
11196 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11197 "mov.b %2,@(%0,%1)")
11200 [(set (match_operand:SI 0 "register_operand" "=r")
11201 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11202 (set (match_operand:QI 2 "general_movdst_operand" "")
11203 (mem:QI (match_dup 0)))]
11204 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11205 "mov.b @(%0,%1),%2")
11208 [(set (match_operand:SI 0 "register_operand" "=r")
11209 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11210 (set (mem:SF (match_dup 0))
11211 (match_operand:SF 2 "general_movsrc_operand" ""))]
11212 "TARGET_SH1 && REGNO (operands[0]) == 0
11213 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11214 || (GET_CODE (operands[2]) == SUBREG
11215 && REGNO (SUBREG_REG (operands[2])) < 16))
11216 && reg_unused_after (operands[0], insn)"
11217 "mov.l %2,@(%0,%1)")
11220 [(set (match_operand:SI 0 "register_operand" "=r")
11221 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11222 (set (match_operand:SF 2 "general_movdst_operand" "")
11224 (mem:SF (match_dup 0)))]
11225 "TARGET_SH1 && REGNO (operands[0]) == 0
11226 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11227 || (GET_CODE (operands[2]) == SUBREG
11228 && REGNO (SUBREG_REG (operands[2])) < 16))
11229 && reg_unused_after (operands[0], insn)"
11230 "mov.l @(%0,%1),%2")
11233 [(set (match_operand:SI 0 "register_operand" "=r")
11234 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11235 (set (mem:SF (match_dup 0))
11236 (match_operand:SF 2 "general_movsrc_operand" ""))]
11237 "TARGET_SH2E && REGNO (operands[0]) == 0
11238 && ((GET_CODE (operands[2]) == REG
11239 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11240 || (GET_CODE (operands[2]) == SUBREG
11241 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11242 && reg_unused_after (operands[0], insn)"
11243 "fmov{.s|} %2,@(%0,%1)")
11246 [(set (match_operand:SI 0 "register_operand" "=r")
11247 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11248 (set (match_operand:SF 2 "general_movdst_operand" "")
11250 (mem:SF (match_dup 0)))]
11251 "TARGET_SH2E && REGNO (operands[0]) == 0
11252 && ((GET_CODE (operands[2]) == REG
11253 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11254 || (GET_CODE (operands[2]) == SUBREG
11255 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11256 && reg_unused_after (operands[0], insn)"
11257 "fmov{.s|} @(%0,%1),%2")
11259 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11260 (define_insn "sp_switch_1"
11261 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11265 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11266 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11267 return \"mov r0,r15\";
11269 [(set_attr "length" "10")])
11271 ;; Switch back to the original stack for interrupt functions with the
11272 ;; sp_switch attribute. */
11273 (define_insn "sp_switch_2"
11276 "mov.l @r15+,r15\;mov.l @r15+,r0"
11277 [(set_attr "length" "4")])
11279 ;; Integer vector moves
11281 (define_expand "movv8qi"
11282 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11283 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11285 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11287 (define_insn "movv8qi_i"
11288 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11289 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11291 && (register_operand (operands[0], V8QImode)
11292 || sh_register_operand (operands[1], V8QImode))"
11299 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11300 (set_attr "length" "4,4,16,4,4")])
11303 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11304 (subreg:V8QI (const_int 0) 0))]
11306 [(set (match_dup 0)
11307 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11308 (const_int 0) (const_int 0) (const_int 0)
11309 (const_int 0) (const_int 0)]))])
11312 [(set (match_operand 0 "arith_reg_dest" "")
11313 (match_operand 1 "sh_rep_vec" ""))]
11314 "TARGET_SHMEDIA && reload_completed
11315 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11316 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11317 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11318 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11319 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11320 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11321 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11322 [(set (match_dup 0) (match_dup 1))
11326 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11327 rtx elt1 = XVECEXP (operands[1], 0, 1);
11330 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11334 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11335 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11337 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11338 operands[1] = XVECEXP (operands[1], 0, 0);
11341 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11343 = GEN_INT (TARGET_LITTLE_ENDIAN
11344 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11345 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11348 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11350 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11356 [(set (match_operand 0 "arith_reg_dest" "")
11357 (match_operand 1 "sh_const_vec" ""))]
11358 "TARGET_SHMEDIA && reload_completed
11359 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11360 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11361 [(set (match_dup 0) (match_dup 1))]
11364 rtx v = operands[1];
11365 enum machine_mode new_mode
11366 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11368 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11370 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11373 (define_expand "movv2hi"
11374 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11375 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11377 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11379 (define_insn "movv2hi_i"
11380 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11381 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11383 && (register_operand (operands[0], V2HImode)
11384 || sh_register_operand (operands[1], V2HImode))"
11391 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11392 (set_attr "length" "4,4,16,4,4")
11393 (set (attr "highpart")
11394 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11395 (const_string "user")]
11396 (const_string "ignore")))])
11398 (define_expand "movv4hi"
11399 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11400 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11402 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11404 (define_insn "movv4hi_i"
11405 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11406 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11408 && (register_operand (operands[0], V4HImode)
11409 || sh_register_operand (operands[1], V4HImode))"
11416 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11417 (set_attr "length" "4,4,16,4,4")
11418 (set_attr "highpart" "depend")])
11420 (define_expand "movv2si"
11421 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11422 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11424 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11426 (define_insn "movv2si_i"
11427 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11428 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11430 && (register_operand (operands[0], V2SImode)
11431 || sh_register_operand (operands[1], V2SImode))"
11438 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11439 (set_attr "length" "4,4,16,4,4")
11440 (set_attr "highpart" "depend")])
11442 ;; Multimedia Intrinsics
11444 (define_insn "absv2si2"
11445 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11446 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11449 [(set_attr "type" "mcmp_media")
11450 (set_attr "highpart" "depend")])
11452 (define_insn "absv4hi2"
11453 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11454 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11457 [(set_attr "type" "mcmp_media")
11458 (set_attr "highpart" "depend")])
11460 (define_insn "addv2si3"
11461 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11462 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11463 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11465 "madd.l %1, %2, %0"
11466 [(set_attr "type" "arith_media")
11467 (set_attr "highpart" "depend")])
11469 (define_insn "addv4hi3"
11470 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11471 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11472 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11474 "madd.w %1, %2, %0"
11475 [(set_attr "type" "arith_media")
11476 (set_attr "highpart" "depend")])
11478 (define_insn_and_split "addv2hi3"
11479 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11480 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11481 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11488 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11489 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11490 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11491 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11492 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11494 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11495 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11498 [(set_attr "highpart" "must_split")])
11500 (define_insn "ssaddv2si3"
11501 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11502 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11503 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11505 "madds.l %1, %2, %0"
11506 [(set_attr "type" "mcmp_media")
11507 (set_attr "highpart" "depend")])
11509 (define_insn "usaddv8qi3"
11510 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11511 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11512 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11514 "madds.ub %1, %2, %0"
11515 [(set_attr "type" "mcmp_media")
11516 (set_attr "highpart" "depend")])
11518 (define_insn "ssaddv4hi3"
11519 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11520 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11521 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11523 "madds.w %1, %2, %0"
11524 [(set_attr "type" "mcmp_media")
11525 (set_attr "highpart" "depend")])
11527 (define_insn "negcmpeqv8qi"
11528 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11529 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11530 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11532 "mcmpeq.b %N1, %N2, %0"
11533 [(set_attr "type" "mcmp_media")
11534 (set_attr "highpart" "depend")])
11536 (define_insn "negcmpeqv2si"
11537 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11538 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11539 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11541 "mcmpeq.l %N1, %N2, %0"
11542 [(set_attr "type" "mcmp_media")
11543 (set_attr "highpart" "depend")])
11545 (define_insn "negcmpeqv4hi"
11546 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11547 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11548 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11550 "mcmpeq.w %N1, %N2, %0"
11551 [(set_attr "type" "mcmp_media")
11552 (set_attr "highpart" "depend")])
11554 (define_insn "negcmpgtuv8qi"
11555 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11556 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11557 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11559 "mcmpgt.ub %N1, %N2, %0"
11560 [(set_attr "type" "mcmp_media")
11561 (set_attr "highpart" "depend")])
11563 (define_insn "negcmpgtv2si"
11564 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11565 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11566 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11568 "mcmpgt.l %N1, %N2, %0"
11569 [(set_attr "type" "mcmp_media")
11570 (set_attr "highpart" "depend")])
11572 (define_insn "negcmpgtv4hi"
11573 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11574 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11575 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11577 "mcmpgt.w %N1, %N2, %0"
11578 [(set_attr "type" "mcmp_media")
11579 (set_attr "highpart" "depend")])
11581 (define_insn "mcmv"
11582 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11583 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11584 (match_operand:DI 2 "arith_reg_operand" "r"))
11585 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11586 (not:DI (match_dup 2)))))]
11589 [(set_attr "type" "arith_media")
11590 (set_attr "highpart" "depend")])
11592 (define_insn "mcnvs_lw"
11593 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11595 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11596 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11598 "mcnvs.lw %N1, %N2, %0"
11599 [(set_attr "type" "mcmp_media")])
11601 (define_insn "mcnvs_wb"
11602 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11604 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11605 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11607 "mcnvs.wb %N1, %N2, %0"
11608 [(set_attr "type" "mcmp_media")])
11610 (define_insn "mcnvs_wub"
11611 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11613 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11614 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11616 "mcnvs.wub %N1, %N2, %0"
11617 [(set_attr "type" "mcmp_media")])
11619 (define_insn "mextr_rl"
11620 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11621 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11622 (match_operand:HI 3 "mextr_bit_offset" "i"))
11623 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11624 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11625 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11628 static char templ[21];
11630 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11631 (int) INTVAL (operands[3]) >> 3);
11634 [(set_attr "type" "arith_media")])
11636 (define_insn "*mextr_lr"
11637 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11638 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11639 (match_operand:HI 3 "mextr_bit_offset" "i"))
11640 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11641 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11642 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11645 static char templ[21];
11647 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11648 (int) INTVAL (operands[4]) >> 3);
11651 [(set_attr "type" "arith_media")])
11653 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11654 ; vector then varies depending on endianness.
11655 (define_expand "mextr1"
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 (1 * 8), GEN_INT (7 * 8)));
11667 (define_expand "mextr2"
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 (2 * 8), GEN_INT (6 * 8)));
11679 (define_expand "mextr3"
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 (3 * 8), GEN_INT (5 * 8)));
11691 (define_expand "mextr4"
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 (4 * 8), GEN_INT (4 * 8)));
11703 (define_expand "mextr5"
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 (5 * 8), GEN_INT (3 * 8)));
11715 (define_expand "mextr6"
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 (6 * 8), GEN_INT (2 * 8)));
11727 (define_expand "mextr7"
11728 [(match_operand:DI 0 "arith_reg_dest" "")
11729 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11730 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11734 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11735 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11739 (define_expand "mmacfx_wl"
11740 [(match_operand:V2SI 0 "arith_reg_dest" "")
11741 (match_operand:V2HI 1 "extend_reg_operand" "")
11742 (match_operand:V2HI 2 "extend_reg_operand" "")
11743 (match_operand:V2SI 3 "arith_reg_operand" "")]
11747 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11748 operands[1], operands[2]));
11752 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11754 (define_insn "mmacfx_wl_i"
11755 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11757 (match_operand:V2SI 1 "arith_reg_operand" "0")
11762 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11763 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11766 "mmacfx.wl %2, %3, %0"
11767 [(set_attr "type" "mac_media")
11768 (set_attr "highpart" "depend")])
11770 (define_expand "mmacnfx_wl"
11771 [(match_operand:V2SI 0 "arith_reg_dest" "")
11772 (match_operand:V2HI 1 "extend_reg_operand" "")
11773 (match_operand:V2HI 2 "extend_reg_operand" "")
11774 (match_operand:V2SI 3 "arith_reg_operand" "")]
11778 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11779 operands[1], operands[2]));
11783 (define_insn "mmacnfx_wl_i"
11784 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11786 (match_operand:V2SI 1 "arith_reg_operand" "0")
11791 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11792 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11795 "mmacnfx.wl %2, %3, %0"
11796 [(set_attr "type" "mac_media")
11797 (set_attr "highpart" "depend")])
11799 (define_insn "mulv2si3"
11800 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11801 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11802 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11804 "mmul.l %1, %2, %0"
11805 [(set_attr "type" "d2mpy_media")
11806 (set_attr "highpart" "depend")])
11808 (define_insn "mulv4hi3"
11809 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11810 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11811 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11813 "mmul.w %1, %2, %0"
11814 [(set_attr "type" "dmpy_media")
11815 (set_attr "highpart" "depend")])
11817 (define_insn "mmulfx_l"
11818 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11822 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11823 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11826 "mmulfx.l %1, %2, %0"
11827 [(set_attr "type" "d2mpy_media")
11828 (set_attr "highpart" "depend")])
11830 (define_insn "mmulfx_w"
11831 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11835 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11836 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11839 "mmulfx.w %1, %2, %0"
11840 [(set_attr "type" "dmpy_media")
11841 (set_attr "highpart" "depend")])
11843 (define_insn "mmulfxrp_w"
11844 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11849 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11850 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11854 "mmulfxrp.w %1, %2, %0"
11855 [(set_attr "type" "dmpy_media")
11856 (set_attr "highpart" "depend")])
11859 (define_expand "mmulhi_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_mmul23_wl : gen_mmul01_wl)
11867 (operands[0], operands[1], operands[2]));
11871 (define_expand "mmullo_wl"
11872 [(match_operand:V2SI 0 "arith_reg_dest" "")
11873 (match_operand:V4HI 1 "arith_reg_operand" "")
11874 (match_operand:V4HI 2 "arith_reg_operand" "")]
11878 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11879 (operands[0], operands[1], operands[2]));
11883 (define_insn "mmul23_wl"
11884 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11887 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11888 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11889 (parallel [(const_int 2) (const_int 3)])))]
11891 "* return (TARGET_LITTLE_ENDIAN
11892 ? \"mmulhi.wl %1, %2, %0\"
11893 : \"mmullo.wl %1, %2, %0\");"
11894 [(set_attr "type" "dmpy_media")
11895 (set (attr "highpart")
11896 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11897 (const_string "user")))])
11899 (define_insn "mmul01_wl"
11900 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11903 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11904 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11905 (parallel [(const_int 0) (const_int 1)])))]
11907 "* return (TARGET_LITTLE_ENDIAN
11908 ? \"mmullo.wl %1, %2, %0\"
11909 : \"mmulhi.wl %1, %2, %0\");"
11910 [(set_attr "type" "dmpy_media")
11911 (set (attr "highpart")
11912 (cond [(eq_attr "endian" "little") (const_string "ignore")]
11913 (const_string "user")))])
11916 (define_expand "mmulsum_wq"
11917 [(match_operand:DI 0 "arith_reg_dest" "")
11918 (match_operand:V4HI 1 "arith_reg_operand" "")
11919 (match_operand:V4HI 2 "arith_reg_operand" "")
11920 (match_operand:DI 3 "arith_reg_operand" "")]
11924 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11925 operands[1], operands[2]));
11929 (define_insn "mmulsum_wq_i"
11930 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11931 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11936 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11937 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11938 (parallel [(const_int 0)]))
11939 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11940 (sign_extend:V4DI (match_dup 3)))
11941 (parallel [(const_int 1)])))
11943 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11944 (sign_extend:V4DI (match_dup 3)))
11945 (parallel [(const_int 2)]))
11946 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11947 (sign_extend:V4DI (match_dup 3)))
11948 (parallel [(const_int 3)]))))))]
11950 "mmulsum.wq %2, %3, %0"
11951 [(set_attr "type" "mac_media")])
11953 (define_expand "mperm_w"
11954 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11955 (match_operand:V4HI 1 "arith_reg_operand" "r")
11956 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11960 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11961 (operands[0], operands[1], operands[2]));
11965 ; This use of vec_select isn't exactly correct according to rtl.texi
11966 ; (because not constant), but it seems a straightforward extension.
11967 (define_insn "mperm_w_little"
11968 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11970 (match_operand:V4HI 1 "arith_reg_operand" "r")
11972 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11973 (const_int 2) (const_int 0))
11974 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11975 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11976 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11977 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11978 "mperm.w %1, %N2, %0"
11979 [(set_attr "type" "arith_media")])
11981 (define_insn "mperm_w_big"
11982 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11984 (match_operand:V4HI 1 "arith_reg_operand" "r")
11986 [(zero_extract:QI (not:QI (match_operand:QI 2
11987 "extend_reg_or_0_operand" "rZ"))
11988 (const_int 2) (const_int 0))
11989 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11990 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11991 (zero_extract:QI (not:QI (match_dup 2))
11992 (const_int 2) (const_int 6))])))]
11993 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11994 "mperm.w %1, %N2, %0"
11995 [(set_attr "type" "arith_media")])
11997 (define_insn "mperm_w0"
11998 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11999 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12000 "trunc_hi_operand" "r"))))]
12002 "mperm.w %1, r63, %0"
12003 [(set_attr "type" "arith_media")
12004 (set_attr "highpart" "ignore")])
12006 (define_expand "msad_ubq"
12007 [(match_operand:DI 0 "arith_reg_dest" "")
12008 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12009 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12010 (match_operand:DI 3 "arith_reg_operand" "")]
12014 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12015 operands[1], operands[2]));
12019 (define_insn "msad_ubq_i"
12020 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12025 (match_operand:DI 1 "arith_reg_operand" "0")
12026 (abs:DI (vec_select:DI
12029 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12031 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12032 (parallel [(const_int 0)]))))
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 1)]))))
12037 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12038 (zero_extend:V8DI (match_dup 3)))
12039 (parallel [(const_int 2)])))
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 3)])))))
12045 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12046 (zero_extend:V8DI (match_dup 3)))
12047 (parallel [(const_int 4)])))
12048 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12049 (zero_extend:V8DI (match_dup 3)))
12050 (parallel [(const_int 5)]))))
12052 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12053 (zero_extend:V8DI (match_dup 3)))
12054 (parallel [(const_int 6)])))
12055 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12056 (zero_extend:V8DI (match_dup 3)))
12057 (parallel [(const_int 7)])))))))]
12059 "msad.ubq %N2, %N3, %0"
12060 [(set_attr "type" "mac_media")])
12062 (define_insn "mshalds_l"
12063 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12066 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12067 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12068 (const_int 31)))))]
12070 "mshalds.l %1, %2, %0"
12071 [(set_attr "type" "mcmp_media")
12072 (set_attr "highpart" "depend")])
12074 (define_insn "mshalds_w"
12075 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12078 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12079 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12080 (const_int 15)))))]
12082 "mshalds.w %1, %2, %0"
12083 [(set_attr "type" "mcmp_media")
12084 (set_attr "highpart" "depend")])
12086 (define_insn "ashrv2si3"
12087 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12088 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12089 (match_operand:DI 2 "arith_reg_operand" "r")))]
12091 "mshard.l %1, %2, %0"
12092 [(set_attr "type" "arith_media")
12093 (set_attr "highpart" "depend")])
12095 (define_insn "ashrv4hi3"
12096 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12097 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12098 (match_operand:DI 2 "arith_reg_operand" "r")))]
12100 "mshard.w %1, %2, %0"
12101 [(set_attr "type" "arith_media")
12102 (set_attr "highpart" "depend")])
12104 (define_insn "mshards_q"
12105 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12107 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12108 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12110 "mshards.q %1, %N2, %0"
12111 [(set_attr "type" "mcmp_media")])
12113 (define_expand "mshfhi_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_mshf4_b : gen_mshf0_b)
12121 (operands[0], operands[1], operands[2]));
12125 (define_expand "mshflo_b"
12126 [(match_operand:V8QI 0 "arith_reg_dest" "")
12127 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12128 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12132 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12133 (operands[0], operands[1], operands[2]));
12137 (define_insn "mshf4_b"
12139 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12141 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12142 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12143 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12144 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12146 "* return (TARGET_LITTLE_ENDIAN
12147 ? \"mshfhi.b %N1, %N2, %0\"
12148 : \"mshflo.b %N1, %N2, %0\");"
12149 [(set_attr "type" "arith_media")
12150 (set (attr "highpart")
12151 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12152 (const_string "user")))])
12154 (define_insn "mshf0_b"
12156 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12158 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12159 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12160 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12161 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12163 "* return (TARGET_LITTLE_ENDIAN
12164 ? \"mshflo.b %N1, %N2, %0\"
12165 : \"mshfhi.b %N1, %N2, %0\");"
12166 [(set_attr "type" "arith_media")
12167 (set (attr "highpart")
12168 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12169 (const_string "user")))])
12171 (define_expand "mshfhi_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_mshf4_l : gen_mshf0_l)
12179 (operands[0], operands[1], operands[2]));
12183 (define_expand "mshflo_l"
12184 [(match_operand:V2SI 0 "arith_reg_dest" "")
12185 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12186 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12190 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12191 (operands[0], operands[1], operands[2]));
12195 (define_insn "mshf4_l"
12196 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12198 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12199 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12200 (parallel [(const_int 1) (const_int 3)])))]
12202 "* return (TARGET_LITTLE_ENDIAN
12203 ? \"mshfhi.l %N1, %N2, %0\"
12204 : \"mshflo.l %N1, %N2, %0\");"
12205 [(set_attr "type" "arith_media")
12206 (set (attr "highpart")
12207 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12208 (const_string "user")))])
12210 (define_insn "mshf0_l"
12211 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12213 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12214 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12215 (parallel [(const_int 0) (const_int 2)])))]
12217 "* return (TARGET_LITTLE_ENDIAN
12218 ? \"mshflo.l %N1, %N2, %0\"
12219 : \"mshfhi.l %N1, %N2, %0\");"
12220 [(set_attr "type" "arith_media")
12221 (set (attr "highpart")
12222 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12223 (const_string "user")))])
12225 (define_expand "mshfhi_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_mshf4_w : gen_mshf0_w)
12233 (operands[0], operands[1], operands[2]));
12237 (define_expand "mshflo_w"
12238 [(match_operand:V4HI 0 "arith_reg_dest" "")
12239 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12240 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12244 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12245 (operands[0], operands[1], operands[2]));
12249 (define_insn "mshf4_w"
12250 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12252 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12253 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12254 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12256 "* return (TARGET_LITTLE_ENDIAN
12257 ? \"mshfhi.w %N1, %N2, %0\"
12258 : \"mshflo.w %N1, %N2, %0\");"
12259 [(set_attr "type" "arith_media")
12260 (set (attr "highpart")
12261 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12262 (const_string "user")))])
12264 (define_insn "mshf0_w"
12265 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12267 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12268 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12269 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12271 "* return (TARGET_LITTLE_ENDIAN
12272 ? \"mshflo.w %N1, %N2, %0\"
12273 : \"mshfhi.w %N1, %N2, %0\");"
12274 [(set_attr "type" "arith_media")
12275 (set (attr "highpart")
12276 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12277 (const_string "user")))])
12279 (define_insn "mshflo_w_x"
12280 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12282 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12283 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12284 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12286 "mshflo.w %N1, %N2, %0"
12287 [(set_attr "type" "arith_media")
12288 (set_attr "highpart" "ignore")])
12290 /* These are useful to expand ANDs and as combiner patterns. */
12291 (define_insn_and_split "mshfhi_l_di"
12292 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12293 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12295 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12296 (const_int -4294967296))))]
12299 mshfhi.l %N1, %N2, %0
12301 "TARGET_SHMEDIA && reload_completed
12302 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12303 [(set (match_dup 3) (match_dup 4))
12304 (set (match_dup 5) (match_dup 6))]
12307 operands[3] = gen_lowpart (SImode, operands[0]);
12308 operands[4] = gen_highpart (SImode, operands[1]);
12309 operands[5] = gen_highpart (SImode, operands[0]);
12310 operands[6] = gen_highpart (SImode, operands[2]);
12312 [(set_attr "type" "arith_media")])
12314 (define_insn "*mshfhi_l_di_rev"
12315 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12316 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12317 (const_int -4294967296))
12318 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12321 "mshfhi.l %N2, %N1, %0"
12322 [(set_attr "type" "arith_media")])
12325 [(set (match_operand:DI 0 "arith_reg_dest" "")
12326 (ior:DI (zero_extend:DI (match_operand:SI 1
12327 "extend_reg_or_0_operand" ""))
12328 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12329 (const_int -4294967296))))
12330 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12335 emit_insn (gen_ashldi3_media (operands[3],
12336 simplify_gen_subreg (DImode, operands[1],
12339 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12343 (define_insn "mshflo_l_di"
12344 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12345 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12346 (const_int 4294967295))
12347 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12351 "mshflo.l %N1, %N2, %0"
12352 [(set_attr "type" "arith_media")
12353 (set_attr "highpart" "ignore")])
12355 (define_insn "*mshflo_l_di_rev"
12356 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12357 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12359 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12360 (const_int 4294967295))))]
12363 "mshflo.l %N2, %N1, %0"
12364 [(set_attr "type" "arith_media")
12365 (set_attr "highpart" "ignore")])
12367 ;; Combiner pattern for trampoline initialization.
12368 (define_insn_and_split "*double_shori"
12369 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12370 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12372 (match_operand:DI 2 "const_int_operand" "n")))]
12374 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12376 "rtx_equal_p (operands[0], operands[1])"
12380 HOST_WIDE_INT v = INTVAL (operands[2]);
12382 emit_insn (gen_shori_media (operands[0], operands[0],
12383 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12384 emit_insn (gen_shori_media (operands[0], operands[0],
12385 gen_int_mode (v, HImode)));
12388 [(set_attr "highpart" "ignore")])
12391 (define_insn "*mshflo_l_di_x"
12392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12393 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12395 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12399 "mshflo.l %N1, %N2, %0"
12400 [(set_attr "type" "arith_media")
12401 (set_attr "highpart" "ignore")])
12403 (define_insn_and_split "concat_v2sf"
12404 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12405 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12406 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12407 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12411 mshflo.l %N1, %N2, %0
12414 "TARGET_SHMEDIA && reload_completed
12415 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12416 [(set (match_dup 3) (match_dup 1))
12417 (set (match_dup 4) (match_dup 2))]
12420 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12421 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12423 [(set_attr "type" "arith_media")
12424 (set_attr "highpart" "ignore")])
12426 (define_insn "*mshflo_l_di_x_rev"
12427 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12428 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12430 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12433 "mshflo.l %N2, %N1, %0"
12434 [(set_attr "type" "arith_media")
12435 (set_attr "highpart" "ignore")])
12437 (define_insn "ashlv2si3"
12438 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12439 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12440 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12442 "mshlld.l %1, %2, %0"
12443 [(set_attr "type" "arith_media")
12444 (set_attr "highpart" "depend")])
12447 [(set (match_operand 0 "any_register_operand" "")
12448 (match_operator 3 "shift_operator"
12449 [(match_operand 1 "any_register_operand" "")
12450 (match_operand 2 "shift_count_reg_operand" "")]))]
12451 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12452 [(set (match_dup 0) (match_dup 3))]
12455 rtx count = operands[2];
12456 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12458 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12459 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12460 || GET_CODE (count) == TRUNCATE)
12461 count = XEXP (count, 0);
12462 inner_mode = GET_MODE (count);
12463 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12464 subreg_lowpart_offset (outer_mode, inner_mode));
12465 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12466 operands[1], count);
12469 (define_insn "ashlv4hi3"
12470 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12471 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12472 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12474 "mshlld.w %1, %2, %0"
12475 [(set_attr "type" "arith_media")
12476 (set_attr "highpart" "depend")])
12478 (define_insn "lshrv2si3"
12479 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12480 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12481 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12483 "mshlrd.l %1, %2, %0"
12484 [(set_attr "type" "arith_media")
12485 (set_attr "highpart" "depend")])
12487 (define_insn "lshrv4hi3"
12488 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12489 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12490 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12492 "mshlrd.w %1, %2, %0"
12493 [(set_attr "type" "arith_media")
12494 (set_attr "highpart" "depend")])
12496 (define_insn "subv2si3"
12497 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12498 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12499 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12501 "msub.l %N1, %2, %0"
12502 [(set_attr "type" "arith_media")
12503 (set_attr "highpart" "depend")])
12505 (define_insn "subv4hi3"
12506 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12507 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12508 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12510 "msub.w %N1, %2, %0"
12511 [(set_attr "type" "arith_media")
12512 (set_attr "highpart" "depend")])
12514 (define_insn_and_split "subv2hi3"
12515 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12516 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12517 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12524 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12525 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12526 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12527 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12528 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12530 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12531 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12534 [(set_attr "highpart" "must_split")])
12536 (define_insn "sssubv2si3"
12537 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12538 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12539 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12541 "msubs.l %N1, %2, %0"
12542 [(set_attr "type" "mcmp_media")
12543 (set_attr "highpart" "depend")])
12545 (define_insn "ussubv8qi3"
12546 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12547 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12548 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12550 "msubs.ub %N1, %2, %0"
12551 [(set_attr "type" "mcmp_media")
12552 (set_attr "highpart" "depend")])
12554 (define_insn "sssubv4hi3"
12555 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12556 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12557 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12559 "msubs.w %N1, %2, %0"
12560 [(set_attr "type" "mcmp_media")
12561 (set_attr "highpart" "depend")])
12563 ;; Floating Point Intrinsics
12565 (define_insn "fcosa_s"
12566 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12567 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12571 [(set_attr "type" "atrans_media")])
12573 (define_insn "fsina_s"
12574 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12575 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12579 [(set_attr "type" "atrans_media")])
12581 (define_insn "fipr"
12582 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12583 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12584 "fp_arith_reg_operand" "f")
12585 (match_operand:V4SF 2
12586 "fp_arith_reg_operand" "f"))
12587 (parallel [(const_int 0)]))
12588 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12589 (parallel [(const_int 1)])))
12590 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12591 (parallel [(const_int 2)]))
12592 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12593 (parallel [(const_int 3)])))))]
12595 "fipr.s %1, %2, %0"
12596 [(set_attr "type" "fparith_media")])
12598 (define_insn "fsrra_s"
12599 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12600 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12604 [(set_attr "type" "atrans_media")])
12606 (define_insn "ftrv"
12607 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12611 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12612 (parallel [(const_int 0) (const_int 5)
12613 (const_int 10) (const_int 15)]))
12614 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12616 (vec_select:V4SF (match_dup 1)
12617 (parallel [(const_int 4) (const_int 9)
12618 (const_int 14) (const_int 3)]))
12619 (vec_select:V4SF (match_dup 2)
12620 (parallel [(const_int 1) (const_int 2)
12621 (const_int 3) (const_int 0)]))))
12624 (vec_select:V4SF (match_dup 1)
12625 (parallel [(const_int 8) (const_int 13)
12626 (const_int 2) (const_int 7)]))
12627 (vec_select:V4SF (match_dup 2)
12628 (parallel [(const_int 2) (const_int 3)
12629 (const_int 0) (const_int 1)])))
12631 (vec_select:V4SF (match_dup 1)
12632 (parallel [(const_int 12) (const_int 1)
12633 (const_int 6) (const_int 11)]))
12634 (vec_select:V4SF (match_dup 2)
12635 (parallel [(const_int 3) (const_int 0)
12636 (const_int 1) (const_int 2)]))))))]
12638 "ftrv.s %1, %2, %0"
12639 [(set_attr "type" "fparith_media")])
12641 (define_insn "ldhi_l"
12642 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12644 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12647 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12651 [(set_attr "type" "load_media")])
12653 (define_insn "ldhi_q"
12654 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12656 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12659 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12663 [(set_attr "type" "load_media")])
12665 (define_insn_and_split "*ldhi_q_comb0"
12666 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12668 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12669 "register_operand" "r")
12670 (match_operand:SI 2
12671 "ua_offset" "I06"))
12674 (plus:SI (and:SI (match_dup 1) (const_int 7))
12677 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12681 "emit_insn (gen_ldhi_q (operands[0],
12682 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12686 (define_insn_and_split "*ldhi_q_comb1"
12687 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12689 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12690 "register_operand" "r")
12691 (match_operand:SI 2
12692 "ua_offset" "I06"))
12695 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12696 "ua_offset" "I06"))
12700 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12701 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12705 "emit_insn (gen_ldhi_q (operands[0],
12706 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12710 (define_insn "ldlo_l"
12711 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12713 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12715 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12716 (and:SI (match_dup 1) (const_int 3))))]
12719 [(set_attr "type" "load_media")])
12721 (define_insn "ldlo_q"
12722 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12724 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12726 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12727 (and:SI (match_dup 1) (const_int 7))))]
12730 [(set_attr "type" "load_media")])
12732 (define_insn_and_split "*ldlo_q_comb0"
12733 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12735 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12736 (match_operand:SI 2 "ua_offset" "I06"))
12738 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12739 (and:SI (match_dup 1) (const_int 7))))]
12740 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12744 "emit_insn (gen_ldlo_q (operands[0],
12745 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12748 (define_insn_and_split "*ldlo_q_comb1"
12749 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12751 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12752 (match_operand:SI 2 "ua_offset" "I06"))
12754 (minus:SI (const_int 8)
12755 (and:SI (plus:SI (match_dup 1)
12756 (match_operand:SI 3 "ua_offset" "I06"))
12758 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12759 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12760 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12764 "emit_insn (gen_ldlo_q (operands[0],
12765 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12768 (define_insn "sthi_l"
12769 [(set (zero_extract:SI
12770 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12773 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12775 (match_operand:SI 1 "arith_reg_operand" "r"))]
12778 [(set_attr "type" "ustore_media")])
12780 ;; All unaligned stores are considered to be 'narrow' because they typically
12781 ;; operate on less that a quadword, and when they operate on a full quadword,
12782 ;; the vanilla store high / store low sequence will cause a stall if not
12783 ;; scheduled apart.
12784 (define_insn "sthi_q"
12785 [(set (zero_extract:DI
12786 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12789 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12791 (match_operand:DI 1 "arith_reg_operand" "r"))]
12794 [(set_attr "type" "ustore_media")])
12796 (define_insn_and_split "*sthi_q_comb0"
12797 [(set (zero_extract:DI
12798 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12799 "register_operand" "r")
12800 (match_operand:SI 1 "ua_offset"
12804 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12806 (match_operand:DI 2 "arith_reg_operand" "r"))]
12807 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12811 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12815 (define_insn_and_split "*sthi_q_comb1"
12816 [(set (zero_extract:DI
12817 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12818 "register_operand" "r")
12819 (match_operand:SI 1 "ua_offset"
12823 (plus:SI (and:SI (plus:SI (match_dup 0)
12824 (match_operand:SI 2 "ua_offset" "I06"))
12828 (match_operand:DI 3 "arith_reg_operand" "r"))]
12829 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12830 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12834 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12838 ;; This is highpart user because the address is used as full 64 bit.
12839 (define_insn "stlo_l"
12840 [(set (zero_extract:SI
12841 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12843 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12844 (and:SI (match_dup 0) (const_int 3)))
12845 (match_operand:SI 1 "arith_reg_operand" "r"))]
12848 [(set_attr "type" "ustore_media")])
12850 (define_insn "stlo_q"
12851 [(set (zero_extract:DI
12852 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
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 1 "arith_reg_operand" "r"))]
12859 [(set_attr "type" "ustore_media")])
12861 (define_insn_and_split "*stlo_q_comb0"
12862 [(set (zero_extract:DI
12863 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12864 (match_operand:SI 1 "ua_offset" "I06"))
12866 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12867 (and:SI (match_dup 0) (const_int 7)))
12868 (match_operand:DI 2 "arith_reg_operand" "r"))]
12869 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12873 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12877 (define_insn_and_split "*stlo_q_comb1"
12878 [(set (zero_extract:DI
12879 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12880 (match_operand:SI 1 "ua_offset" "I06"))
12882 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12883 (match_operand:SI 2
12884 "ua_offset" "I06"))
12886 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12887 (match_operand:DI 3 "arith_reg_operand" "r"))]
12888 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12892 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12896 (define_insn "ldhi_l64"
12897 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12899 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12902 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12906 [(set_attr "type" "load_media")])
12908 (define_insn "ldhi_q64"
12909 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12911 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12914 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12918 [(set_attr "type" "load_media")])
12920 (define_insn "ldlo_l64"
12921 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12923 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12925 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12926 (and:DI (match_dup 1) (const_int 3))))]
12929 [(set_attr "type" "load_media")])
12931 (define_insn "ldlo_q64"
12932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12934 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12936 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12937 (and:DI (match_dup 1) (const_int 7))))]
12940 [(set_attr "type" "load_media")])
12942 (define_insn "sthi_l64"
12943 [(set (zero_extract:SI
12944 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12947 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12949 (match_operand:SI 1 "arith_reg_operand" "r"))]
12952 [(set_attr "type" "ustore_media")])
12954 (define_insn "sthi_q64"
12955 [(set (zero_extract:DI
12956 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12959 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12961 (match_operand:DI 1 "arith_reg_operand" "r"))]
12964 [(set_attr "type" "ustore_media")])
12966 (define_insn "stlo_l64"
12967 [(set (zero_extract:SI
12968 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12970 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12971 (and:DI (match_dup 0) (const_int 3)))
12972 (match_operand:SI 1 "arith_reg_operand" "r"))]
12975 [(set_attr "type" "ustore_media")])
12977 (define_insn "stlo_q64"
12978 [(set (zero_extract:DI
12979 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12981 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12982 (and:DI (match_dup 0) (const_int 7)))
12983 (match_operand:DI 1 "arith_reg_operand" "r"))]
12986 [(set_attr "type" "ustore_media")])
12989 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12990 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12994 [(set_attr "type" "arith_media")])
12996 (define_insn "nsbsi"
12997 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12999 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13003 [(set_attr "type" "arith_media")])
13005 (define_insn "nsbdi"
13006 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13008 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13012 [(set_attr "type" "arith_media")])
13014 (define_expand "ffsdi2"
13015 [(set (match_operand:DI 0 "arith_reg_dest" "")
13016 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13020 rtx scratch = gen_reg_rtx (DImode);
13023 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13024 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13025 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13026 emit_insn (gen_nsbdi (scratch, scratch));
13027 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13028 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13029 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13031 = gen_rtx_EXPR_LIST (REG_EQUAL,
13032 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13036 (define_expand "ffssi2"
13037 [(set (match_operand:SI 0 "arith_reg_dest" "")
13038 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13042 rtx scratch = gen_reg_rtx (SImode);
13043 rtx discratch = gen_reg_rtx (DImode);
13046 emit_insn (gen_adddi3 (discratch,
13047 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13049 emit_insn (gen_andcdi3 (discratch,
13050 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13052 emit_insn (gen_nsbsi (scratch, discratch));
13053 last = emit_insn (gen_subsi3 (operands[0],
13054 force_reg (SImode, GEN_INT (63)), scratch));
13056 = gen_rtx_EXPR_LIST (REG_EQUAL,
13057 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13061 (define_insn "byterev"
13062 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13063 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13064 (parallel [(const_int 7) (const_int 6) (const_int 5)
13065 (const_int 4) (const_int 3) (const_int 2)
13066 (const_int 1) (const_int 0)])))]
13069 [(set_attr "type" "arith_media")])
13071 (define_insn "*prefetch_media"
13072 [(prefetch (match_operand:QI 0 "address_operand" "p")
13073 (match_operand:SI 1 "const_int_operand" "n")
13074 (match_operand:SI 2 "const_int_operand" "n"))]
13078 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13079 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13082 [(set_attr "type" "other")])
13084 (define_insn "*prefetch_i4"
13085 [(prefetch (match_operand:SI 0 "register_operand" "r")
13086 (match_operand:SI 1 "const_int_operand" "n")
13087 (match_operand:SI 2 "const_int_operand" "n"))]
13088 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13091 return \"pref @%0\";
13093 [(set_attr "type" "other")])
13095 (define_expand "prefetch"
13096 [(prefetch (match_operand 0 "address_operand" "p")
13097 (match_operand:SI 1 "const_int_operand" "n")
13098 (match_operand:SI 2 "const_int_operand" "n"))]
13099 "TARGET_HARD_SH4 || TARGET_SH5"
13102 if (GET_MODE (operands[0]) != Pmode
13103 || GET_CODE (operands[1]) != CONST_INT
13104 || GET_CODE (operands[2]) != CONST_INT)
13106 if (! TARGET_SHMEDIA)
13107 operands[0] = force_reg (Pmode, operands[0]);
13110 (define_insn "alloco_i"
13111 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13112 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13118 if (GET_CODE (operands[0]) == PLUS)
13120 xops[0] = XEXP (operands[0], 0);
13121 xops[1] = XEXP (operands[0], 1);
13125 xops[0] = operands[0];
13126 xops[1] = const0_rtx;
13128 output_asm_insn (\"alloco %0, %1\", xops);
13131 [(set_attr "type" "other")])
13134 [(set (match_operand 0 "any_register_operand" "")
13135 (match_operand 1 "" ""))]
13136 "TARGET_SHMEDIA && reload_completed"
13137 [(set (match_dup 0) (match_dup 1))]
13142 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13147 ; Stack Protector Patterns
13149 (define_expand "stack_protect_set"
13150 [(set (match_operand 0 "memory_operand" "")
13151 (match_operand 1 "memory_operand" ""))]
13154 if (TARGET_SHMEDIA)
13156 if (TARGET_SHMEDIA64)
13157 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13159 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13162 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13167 (define_insn "stack_protect_set_si"
13168 [(set (match_operand:SI 0 "memory_operand" "=m")
13169 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13170 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13172 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13173 [(set_attr "type" "other")
13174 (set_attr "length" "6")])
13176 (define_insn "stack_protect_set_si_media"
13177 [(set (match_operand:SI 0 "memory_operand" "=m")
13178 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13179 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13181 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13182 [(set_attr "type" "other")
13183 (set_attr "length" "12")])
13185 (define_insn "stack_protect_set_di_media"
13186 [(set (match_operand:DI 0 "memory_operand" "=m")
13187 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13188 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13190 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13191 [(set_attr "type" "other")
13192 (set_attr "length" "12")])
13194 (define_expand "stack_protect_test"
13195 [(match_operand 0 "memory_operand" "")
13196 (match_operand 1 "memory_operand" "")
13197 (match_operand 2 "" "")]
13200 if (TARGET_SHMEDIA)
13202 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13204 if (TARGET_SHMEDIA64)
13205 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13208 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13211 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13215 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13216 emit_jump_insn (gen_branch_true (operands[2]));
13222 (define_insn "stack_protect_test_si"
13223 [(set (reg:SI T_REG)
13224 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13225 (match_operand:SI 1 "memory_operand" "m")]
13227 (set (match_scratch:SI 2 "=&r") (const_int 0))
13228 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13230 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13231 [(set_attr "type" "other")
13232 (set_attr "length" "10")])
13234 (define_insn "stack_protect_test_si_media"
13235 [(set (match_operand:SI 0 "register_operand" "=&r")
13236 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13237 (match_operand:SI 2 "memory_operand" "m")]
13239 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13241 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13242 [(set_attr "type" "other")
13243 (set_attr "length" "16")])
13245 (define_insn "stack_protect_test_di_media"
13246 [(set (match_operand:DI 0 "register_operand" "=&r")
13247 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13248 (match_operand:DI 2 "memory_operand" "m")]
13250 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13252 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13253 [(set_attr "type" "other")
13254 (set_attr "length" "16")])