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, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;; Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
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)
145 (UNSPEC_DIV_INV_M0 30)
146 (UNSPEC_DIV_INV_M1 31)
147 (UNSPEC_DIV_INV_M2 32)
148 (UNSPEC_DIV_INV_M3 33)
149 (UNSPEC_DIV_INV20 34)
150 (UNSPEC_DIV_INV_TABLE 37)
158 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160 (UNSPEC_EXTRACT_S16 43)
161 (UNSPEC_EXTRACT_U16 44)
163 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
166 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167 (UNSPEC_PCREL_SYMOFF 46)
169 ;; These are used with unspec_volatile.
175 (UNSPECV_WINDOW_END 10)
176 (UNSPECV_CONST_END 11)
177 (UNSPECV_EH_RETURN 12)
181 ;; -------------------------------------------------------------------------
183 ;; -------------------------------------------------------------------------
188 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
189 (const (symbol_ref "sh_cpu_attr")))
191 (define_attr "endian" "big,little"
192 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
193 (const_string "little") (const_string "big"))))
195 ;; Indicate if the default fpu mode is single precision.
196 (define_attr "fpu_single" "yes,no"
197 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
198 (const_string "yes") (const_string "no"))))
200 (define_attr "fmovd" "yes,no"
201 (const (if_then_else (symbol_ref "TARGET_FMOVD")
202 (const_string "yes") (const_string "no"))))
204 (define_attr "pipe_model" "sh1,sh4,sh5media"
206 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
207 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
208 (const_string "sh1"))))
210 ;; cbranch conditional branch instructions
211 ;; jump unconditional jumps
212 ;; arith ordinary arithmetic
213 ;; arith3 a compound insn that behaves similarly to a sequence of
214 ;; three insns of type arith
215 ;; arith3b like above, but might end with a redirected branch
217 ;; load_si Likewise, SImode variant for general register.
218 ;; fload Likewise, but load to fp register.
220 ;; fstore floating point register to memory
221 ;; move general purpose register to register
222 ;; movi8 8-bit immediate to general purpose register
223 ;; mt_group other sh4 mt instructions
224 ;; fmove register to register, floating point
225 ;; smpy word precision integer multiply
226 ;; dmpy longword or doublelongword precision integer multiply
228 ;; pload load of pr reg, which can't be put into delay slot of rts
229 ;; prset copy register to pr reg, ditto
230 ;; pstore store of pr reg, which can't be put into delay slot of jsr
231 ;; prget copy pr to register, ditto
232 ;; pcload pc relative load of constant value
233 ;; pcfload Likewise, but load to fp register.
234 ;; pcload_si Likewise, SImode variant for general register.
235 ;; rte return from exception
236 ;; sfunc special function call with known used registers
237 ;; call function call
239 ;; fpscr_toggle toggle a bit in the fpscr
240 ;; fdiv floating point divide (or square root)
241 ;; gp_fpul move from general purpose register to fpul
242 ;; fpul_gp move from fpul to general purpose register
243 ;; mac_gp move from mac[lh] to general purpose register
244 ;; gp_mac move from general purpose register to mac[lh]
245 ;; mac_mem move from mac[lh] to memory
246 ;; mem_mac move from memory to mac[lh]
247 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
248 ;; ftrc_s fix_truncsfsi2_i4
249 ;; dfdiv double precision floating point divide (or square root)
250 ;; cwb ic_invalidate_line_i
251 ;; movua SH4a unaligned load
252 ;; fsrra square root reciprocal approximate
253 ;; fsca sine and cosine approximate
254 ;; tls_load load TLS related address
255 ;; arith_media SHmedia arithmetic, logical, and shift instructions
256 ;; cbranch_media SHmedia conditional branch instructions
257 ;; cmp_media SHmedia compare instructions
258 ;; dfdiv_media SHmedia double precision divide and square root
259 ;; dfmul_media SHmedia double precision multiply instruction
260 ;; dfparith_media SHmedia double precision floating point arithmetic
261 ;; dfpconv_media SHmedia double precision floating point conversions
262 ;; dmpy_media SHmedia longword multiply
263 ;; fcmp_media SHmedia floating point compare instructions
264 ;; fdiv_media SHmedia single precision divide and square root
265 ;; fload_media SHmedia floating point register load instructions
266 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
267 ;; fparith_media SHmedia single precision floating point arithmetic
268 ;; fpconv_media SHmedia single precision floating point conversions
269 ;; fstore_media SHmedia floating point register store instructions
270 ;; gettr_media SHmedia gettr instruction
271 ;; invalidate_line_media SHmedia invalidate_line sequence
272 ;; jump_media SHmedia unconditional branch instructions
273 ;; load_media SHmedia general register load instructions
274 ;; pt_media SHmedia pt instruction (expanded by assembler)
275 ;; ptabs_media SHmedia ptabs instruction
276 ;; store_media SHmedia general register store instructions
277 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
278 ;; mac_media SHmedia mac-style fixed point operations
279 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
280 ;; atrans_media SHmedia approximate transcendental functions
281 ;; ustore_media SHmedia unaligned stores
282 ;; nil no-op move, will be deleted.
285 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
286 (const_string "other"))
288 ;; We define a new attribute namely "insn_class".We use
289 ;; this for the DFA based pipeline description.
291 ;; mt_group SH4 "mt" group instructions.
293 ;; ex_group SH4 "ex" group instructions.
295 ;; ls_group SH4 "ls" group instructions.
298 (define_attr "insn_class"
299 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
300 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
301 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
302 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
303 (eq_attr "type" "cbranch,jump") (const_string "br_group")
304 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
305 (const_string "fe_group")
306 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
307 (const_string "none")))
308 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
309 ;; so these do not belong in an insn group, although they are modeled
310 ;; with their own define_insn_reservations.
312 ;; Indicate what precision must be selected in fpscr for this insn, if any.
314 (define_attr "fp_mode" "single,double,none" (const_string "none"))
316 ;; Indicate if the fpu mode is set by this instruction
317 ;; "unknown" must have the value as "none" in fp_mode, and means
318 ;; that the instruction/abi has left the processor in an unknown
320 ;; "none" means that nothing has changed and no mode is set.
321 ;; This attribute is only used for the Renesas ABI.
322 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
324 ; If a conditional branch destination is within -252..258 bytes away
325 ; from the instruction it can be 2 bytes long. Something in the
326 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
327 ; branches are initially assumed to be 16 bytes long.
328 ; In machine_dependent_reorg, we split all branches that are longer than
331 ;; The maximum range used for SImode constant pool entries is 1018. A final
332 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
333 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
334 ;; instruction around the pool table, 2 bytes of alignment before the table,
335 ;; and 30 bytes of alignment after the table. That gives a maximum total
336 ;; pool size of 1058 bytes.
337 ;; Worst case code/pool content size ratio is 1:2 (using asms).
338 ;; Thus, in the worst case, there is one instruction in front of a maximum
339 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
340 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
341 ;; If we have a forward branch, the initial table will be put after the
342 ;; unconditional branch.
344 ;; ??? We could do much better by keeping track of the actual pcloads within
345 ;; the branch range and in the pcload range in front of the branch range.
347 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
349 (define_attr "short_cbranch_p" "no,yes"
350 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
354 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
358 ] (const_string "no")))
360 (define_attr "med_branch_p" "no,yes"
361 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
364 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
366 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
369 ] (const_string "no")))
371 (define_attr "med_cbranch_p" "no,yes"
372 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
375 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
380 ] (const_string "no")))
382 (define_attr "braf_branch_p" "no,yes"
383 (cond [(match_test "! TARGET_SH2")
385 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
388 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
390 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
393 ] (const_string "no")))
395 (define_attr "braf_cbranch_p" "no,yes"
396 (cond [(match_test "! TARGET_SH2")
398 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
401 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
403 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
406 ] (const_string "no")))
408 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
409 ; For wider ranges, we need a combination of a code and a data part.
410 ; If we can get a scratch register for a long range jump, the code
411 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
412 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
413 ; long; otherwise, it must be 6 bytes long.
415 ; All other instructions are two bytes long by default.
417 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
418 ;; but getattrtab doesn't understand this.
419 (define_attr "length" ""
420 (cond [(eq_attr "type" "cbranch")
421 (cond [(eq_attr "short_cbranch_p" "yes")
423 (eq_attr "med_cbranch_p" "yes")
425 (eq_attr "braf_cbranch_p" "yes")
427 ;; ??? using pc is not computed transitively.
428 (ne (match_dup 0) (match_dup 0))
430 (match_test "flag_pic")
433 (eq_attr "type" "jump")
434 (cond [(eq_attr "med_branch_p" "yes")
436 (and (match_test "prev_nonnote_insn (insn)")
437 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))") (symbol_ref "INSN"))
438 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))") (symbol_ref "code_for_indirect_jump_scratch"))))
439 (cond [(eq_attr "braf_branch_p" "yes")
441 (not (match_test "flag_pic"))
443 (match_test "TARGET_SH2")
444 (const_int 10)] (const_int 18))
445 (eq_attr "braf_branch_p" "yes")
447 ;; ??? using pc is not computed transitively.
448 (ne (match_dup 0) (match_dup 0))
450 (match_test "flag_pic")
453 (eq_attr "type" "pt_media")
454 (if_then_else (match_test "TARGET_SHMEDIA64")
455 (const_int 20) (const_int 12))
456 (and (eq_attr "type" "jump_media")
457 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
459 ] (if_then_else (match_test "TARGET_SHMEDIA")
463 ;; DFA descriptions for the pipelines
466 (include "shmedia.md")
469 (include "iterators.md")
470 (include "predicates.md")
471 (include "constraints.md")
473 ;; Definitions for filling delay slots
475 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
477 (define_attr "banked" "yes,no"
478 (cond [(match_test "sh_loads_bankedreg_p (insn)")
479 (const_string "yes")]
480 (const_string "no")))
482 ;; ??? This should be (nil) instead of (const_int 0)
483 (define_attr "hit_stack" "yes,no"
484 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
486 (const_string "yes")))
488 (define_attr "interrupt_function" "no,yes"
489 (const (symbol_ref "current_function_interrupt")))
491 (define_attr "in_delay_slot" "yes,no"
492 (cond [(eq_attr "type" "cbranch") (const_string "no")
493 (eq_attr "type" "pcload,pcload_si") (const_string "no")
494 (eq_attr "needs_delay_slot" "yes") (const_string "no")
495 (eq_attr "length" "2") (const_string "yes")
496 ] (const_string "no")))
498 (define_attr "cond_delay_slot" "yes,no"
499 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
500 ] (const_string "no")))
502 (define_attr "is_sfunc" ""
503 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
505 (define_attr "is_mac_media" ""
506 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
508 (define_attr "branch_zero" "yes,no"
509 (cond [(eq_attr "type" "!cbranch") (const_string "no")
510 (ne (symbol_ref "(next_active_insn (insn)\
511 == (prev_active_insn\
512 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
513 && get_attr_length (next_active_insn (insn)) == 2")
515 (const_string "yes")]
516 (const_string "no")))
518 ;; SH4 Double-precision computation with double-precision result -
519 ;; the two halves are ready at different times.
520 (define_attr "dfp_comp" "yes,no"
521 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
522 (const_string "no")))
524 ;; Insns for which the latency of a preceding fp insn is decreased by one.
525 (define_attr "late_fp_use" "yes,no" (const_string "no"))
526 ;; And feeding insns for which this relevant.
527 (define_attr "any_fp_comp" "yes,no"
528 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
529 (const_string "yes")]
530 (const_string "no")))
532 (define_attr "any_int_load" "yes,no"
533 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
534 (const_string "yes")]
535 (const_string "no")))
537 (define_attr "highpart" "user, ignore, extend, depend, must_split"
538 (const_string "user"))
541 (eq_attr "needs_delay_slot" "yes")
542 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
544 ;; Since a normal return (rts) implicitly uses the PR register,
545 ;; we can't allow PR register loads in an rts delay slot.
546 ;; On the SH1* and SH2*, the rte instruction reads the return pc from the
547 ;; stack, and thus we can't put a pop instruction in its delay slot.
548 ;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
549 ;; pop instruction can go in the delay slot, unless it references a banked
550 ;; register (the register bank is switched by rte).
552 (eq_attr "type" "return")
553 [(and (eq_attr "in_delay_slot" "yes")
554 (ior (and (eq_attr "interrupt_function" "no")
555 (eq_attr "type" "!pload,prset"))
556 (and (eq_attr "interrupt_function" "yes")
557 (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
558 (eq_attr "banked" "no"))))
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
565 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566 [(and (eq_attr "in_delay_slot" "yes")
567 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
577 (and (eq_attr "type" "cbranch")
578 (match_test "TARGET_SH2"))
579 ;; SH2e has a hardware bug that pretty much prohibits the use of
580 ;; annulled delay slots.
581 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582 (not (eq_attr "cpu" "sh2e"))) (nil)])
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
588 ;; Various patterns to generate the TST #imm, R0 instruction.
589 ;; Although this adds some pressure on the R0 register, it can potentially
590 ;; result in faster code, even if the operand has to be moved to R0 first.
591 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group
592 ;; instructions and thus will be executed in parallel. On SH4A TST #imm, R0
593 ;; is an EX group instruction but still can be executed in parallel with the
594 ;; MT group MOV Rm, Rn instruction.
596 ;; Usual TST #imm, R0 patterns for SI, HI and QI
597 ;; This is usually used for bit patterns other than contiguous bits
600 (define_insn "tstsi_t"
602 (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603 (match_operand:SI 1 "logical_operand" "K08,r"))
607 [(set_attr "type" "mt_group")])
609 (define_insn "tsthi_t"
611 (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612 (match_operand 1 "const_int_operand")) 0)
615 && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
617 [(set_attr "type" "mt_group")])
619 (define_insn "tstqi_t"
621 (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622 (match_operand 1 "const_int_operand")) 0)
625 && (CONST_OK_FOR_K08 (INTVAL (operands[1]))
626 || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
628 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
631 [(set_attr "type" "mt_group")])
633 ;; Test low QI subreg against zero.
634 ;; This avoids unnecessary zero extension before the test.
636 (define_insn "*tstqi_t_zero"
638 (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
641 [(set_attr "type" "mt_group")])
643 ;; This pattern might be risky because it also tests the upper bits and not
644 ;; only the subreg. However, it seems that combine will get to this only
645 ;; when testing sign/zero extended values. In this case the extended upper
646 ;; bits do not matter.
647 (define_insn "*tst<mode>_t_zero"
651 (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
652 (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>)
654 "TARGET_SH1 && TARGET_LITTLE_ENDIAN"
656 [(set_attr "type" "mt_group")])
658 (define_insn "*tst<mode>_t_zero"
662 (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
663 (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>)
665 "TARGET_SH1 && !TARGET_LITTLE_ENDIAN"
667 [(set_attr "type" "mt_group")])
669 ;; Extract LSB, negate and store in T bit.
671 (define_insn "tstsi_t_and_not"
673 (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
677 [(set_attr "type" "mt_group")])
679 ;; Extract contiguous bits and compare them against zero.
681 (define_insn "tstsi_t_zero_extract_eq"
683 (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
684 (match_operand:SI 1 "const_int_operand")
685 (match_operand:SI 2 "const_int_operand"))
688 && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
690 operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
693 [(set_attr "type" "mt_group")])
695 ;; This split is required when testing bits in a QI subreg.
699 (eq:SI (if_then_else:SI (zero_extract:SI
700 (match_operand 0 "logical_operand" "")
701 (match_operand 1 "const_int_operand")
702 (match_operand 2 "const_int_operand"))
703 (match_operand 3 "const_int_operand")
707 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
708 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
709 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
712 if (GET_MODE (operands[0]) == QImode)
713 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
716 ;; Extract single bit, negate and store it in the T bit.
717 ;; Not used for SH4A.
719 (define_insn "tstsi_t_zero_extract_xor"
721 (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
722 (match_operand:SI 3 "const_int_operand"))
723 (match_operand:SI 1 "const_int_operand")
724 (match_operand:SI 2 "const_int_operand")))]
726 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
727 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
729 [(set_attr "type" "mt_group")])
731 ;; Extract single bit, negate and store it in the T bit.
732 ;; Used for SH4A little endian.
734 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
737 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
738 (match_operand:SI 3 "const_int_operand")) 0)
739 (match_operand:SI 1 "const_int_operand")
740 (match_operand:SI 2 "const_int_operand")))]
741 "TARGET_SH1 && TARGET_LITTLE_ENDIAN
742 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
743 == (INTVAL (operands[3]) & 255)
744 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
746 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
749 [(set_attr "type" "mt_group")])
751 ;; Extract single bit, negate and store it in the T bit.
752 ;; Used for SH4A big endian.
754 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
757 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
758 (match_operand:SI 3 "const_int_operand")) 3)
759 (match_operand:SI 1 "const_int_operand")
760 (match_operand:SI 2 "const_int_operand")))]
761 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
762 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
763 == (INTVAL (operands[3]) & 255)
764 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
766 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
769 [(set_attr "type" "mt_group")])
771 (define_insn "cmpeqsi_t"
773 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
774 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
780 [(set_attr "type" "mt_group")])
782 ;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
783 ;; pattern by itself. What this actually does is:
784 ;; x == 0: (1 >> 0-0) & 1 = 1
785 ;; x != 0: (1 >> 0-x) & 1 = 0
786 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
787 (define_insn_and_split "*cmpeqsi_t"
791 (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
796 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
798 (define_insn "cmpgtsi_t"
800 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
801 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
806 [(set_attr "type" "mt_group")])
808 (define_insn "cmpgesi_t"
810 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
811 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
816 [(set_attr "type" "mt_group")])
818 ;; FIXME: This is actually wrong. There is no way to literally move a
819 ;; general reg to t reg. Luckily, it seems that this pattern will be only
820 ;; used when the general reg is known be either '0' or '1' during combine.
821 ;; What we actually need is reg != 0 -> T, but we have only reg == 0 -> T.
822 ;; Due to interactions with other patterns, combine fails to pick the latter
823 ;; and invert the dependent logic.
824 (define_insn "*negtstsi"
825 [(set (reg:SI T_REG) (match_operand:SI 0 "arith_reg_operand" "r"))]
828 [(set_attr "type" "mt_group")])
830 ;; Some integer sign comparison patterns can be realized with the div0s insn.
831 ;; div0s Rm,Rn T = (Rm >> 31) ^ (Rn >> 31)
832 (define_insn "cmp_div0s_0"
834 (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
835 (match_operand:SI 1 "arith_reg_operand" "r"))
839 [(set_attr "type" "arith")])
841 (define_insn "cmp_div0s_1"
843 (lt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
844 (match_operand:SI 1 "arith_reg_operand" "r"))
848 [(set_attr "type" "arith")])
850 (define_insn_and_split "*cmp_div0s_0"
851 [(set (match_operand:SI 0 "arith_reg_dest" "")
852 (lshiftrt:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
853 (match_operand:SI 2 "arith_reg_operand" ""))
855 (clobber (reg:SI T_REG))]
860 (lshiftrt:SI (xor:SI (match_dup 1) (match_dup 2)) (const_int 31)))
861 (set (match_dup 0) (reg:SI T_REG))])
863 (define_insn_and_split "*cmp_div0s_1"
864 [(set (match_operand:SI 0 "arith_reg_dest" "")
865 (ge:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
866 (match_operand:SI 2 "arith_reg_operand" ""))
868 (clobber (reg:SI T_REG))]
871 "&& can_create_pseudo_p ()"
873 ;; We have to go through the movnegt expander here which will handle the
874 ;; SH2A vs non-SH2A cases.
876 emit_insn (gen_cmp_div0s_1 (operands[1], operands[2]));
877 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
881 (define_insn_and_split "*cmp_div0s_1"
883 (ge:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
884 (match_operand:SI 1 "arith_reg_operand" ""))
888 "&& can_create_pseudo_p ()"
889 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
891 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
894 ;; -------------------------------------------------------------------------
895 ;; SImode compare and branch
896 ;; -------------------------------------------------------------------------
898 (define_expand "cbranchsi4"
900 (if_then_else (match_operator 0 "comparison_operator"
901 [(match_operand:SI 1 "arith_operand" "")
902 (match_operand:SI 2 "arith_operand" "")])
903 (label_ref (match_operand 3 "" ""))
905 (clobber (reg:SI T_REG))]
909 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
910 operands[2], operands[3]));
912 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
917 ;; Combine patterns to invert compare and branch operations for which we
918 ;; don't have actual comparison insns. These patterns are used in cases
919 ;; which appear after the initial cbranchsi expansion, which also does
920 ;; some condition inversion.
924 (if_then_else (ne (match_operand:SI 0 "arith_reg_operand" "")
925 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
926 (label_ref (match_operand 2))
928 (clobber (reg:SI T_REG))]
930 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (match_dup 1)))
931 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
932 (label_ref (match_dup 2))
935 ;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
936 ;; and SH2A combine fails to simplify this pattern by itself.
937 ;; What this actually does is:
938 ;; x == 0: (1 >> 0-0) & 1 = 1
939 ;; x != 0: (1 >> 0-x) & 1 = 0
940 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
944 (eq (and:SI (lshiftrt:SI
946 (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
949 (label_ref (match_operand 2))
951 (clobber (reg:SI T_REG))]
953 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
954 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
955 (label_ref (match_dup 2))
958 ;; FIXME: These could probably use code iterators for the compare op.
961 (if_then_else (le (match_operand:SI 0 "arith_reg_operand" "")
962 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
963 (label_ref (match_operand 2))
965 (clobber (reg:SI T_REG))]
967 [(set (reg:SI T_REG) (gt:SI (match_dup 0) (match_dup 1)))
968 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
969 (label_ref (match_dup 2))
974 (if_then_else (lt (match_operand:SI 0 "arith_reg_operand" "")
975 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
976 (label_ref (match_operand 2))
978 (clobber (reg:SI T_REG))]
980 [(set (reg:SI T_REG) (ge:SI (match_dup 0) (match_dup 1)))
981 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
982 (label_ref (match_dup 2))
987 (if_then_else (leu (match_operand:SI 0 "arith_reg_operand" "")
988 (match_operand:SI 1 "arith_reg_operand" ""))
989 (label_ref (match_operand 2))
991 (clobber (reg:SI T_REG))]
993 [(set (reg:SI T_REG) (gtu:SI (match_dup 0) (match_dup 1)))
994 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
995 (label_ref (match_dup 2))
1000 (if_then_else (ltu (match_operand:SI 0 "arith_reg_operand" "")
1001 (match_operand:SI 1 "arith_reg_operand" ""))
1002 (label_ref (match_operand 2))
1004 (clobber (reg:SI T_REG))]
1006 [(set (reg:SI T_REG) (geu:SI (match_dup 0) (match_dup 1)))
1007 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1008 (label_ref (match_dup 2))
1011 ;; Compare and branch combine patterns for div0s comparisons.
1012 (define_insn_and_split "*cbranch_div0s"
1014 (if_then_else (lt (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1015 (match_operand:SI 1 "arith_reg_operand" ""))
1017 (label_ref (match_operand 2))
1019 (clobber (reg:SI T_REG))]
1023 [(set (reg:SI T_REG)
1024 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1026 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1027 (label_ref (match_dup 2))
1030 (define_insn_and_split "*cbranch_div0s"
1032 (if_then_else (ge (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1033 (match_operand:SI 1 "arith_reg_operand" ""))
1035 (label_ref (match_operand 2))
1037 (clobber (reg:SI T_REG))]
1041 [(set (reg:SI T_REG)
1042 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1044 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1045 (label_ref (match_dup 2))
1048 ;; Conditional move combine pattern for div0s comparisons.
1049 ;; This is used when TARGET_PRETEND_CMOVE is in effect.
1050 (define_insn_and_split "*movsicc_div0s"
1051 [(set (match_operand:SI 0 "arith_reg_dest" "")
1052 (if_then_else:SI (ge (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
1053 (match_operand:SI 2 "arith_reg_operand" ""))
1055 (match_operand:SI 3 "arith_reg_operand" "")
1056 (match_operand:SI 4 "general_movsrc_operand" "")))
1057 (clobber (reg:SI T_REG))]
1058 "TARGET_PRETEND_CMOVE"
1061 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1064 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1068 ;; -------------------------------------------------------------------------
1069 ;; SImode unsigned integer comparisons
1070 ;; -------------------------------------------------------------------------
1072 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1073 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1074 ;; might remain and we have to handle them. If the '>= 0' case wasn't
1075 ;; handled here, something else would just load a '0' into the second operand
1076 ;; and do the comparison. We can do slightly better by just setting the
1078 (define_insn_and_split "cmpgeusi_t"
1079 [(set (reg:SI T_REG)
1080 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1081 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1084 "&& satisfies_constraint_Z (operands[1])"
1085 [(set (reg:SI T_REG) (const_int 1))]
1087 [(set_attr "type" "mt_group")])
1089 (define_insn "cmpgtusi_t"
1090 [(set (reg:SI T_REG)
1091 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1092 (match_operand:SI 1 "arith_reg_operand" "r")))]
1095 [(set_attr "type" "mt_group")])
1098 ;; -------------------------------------------------------------------------
1099 ;; DImode compare and branch
1100 ;; -------------------------------------------------------------------------
1103 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1104 ;; Therefore, we aim to have a set of three branches that go straight to the
1105 ;; destination, i.e. only one of them is taken at any one time.
1106 ;; This mechanism should also be slightly better for the sh4-200.
1108 (define_expand "cbranchdi4"
1110 (if_then_else (match_operator 0 "comparison_operator"
1111 [(match_operand:DI 1 "arith_operand" "")
1112 (match_operand:DI 2 "arith_operand" "")])
1113 (label_ref (match_operand 3 "" ""))
1115 (clobber (match_dup 4))
1116 (clobber (reg:SI T_REG))]
1117 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1119 enum rtx_code comparison;
1123 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1124 operands[2], operands[3]));
1128 else if (!TARGET_CBRANCHDI4)
1130 sh_emit_compare_and_branch (operands, DImode);
1136 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1139 comparison = prepare_cbranch_operands (operands, DImode,
1140 LAST_AND_UNUSED_RTX_CODE);
1141 if (comparison != GET_CODE (operands[0]))
1143 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1144 operands[4] = gen_rtx_SCRATCH (SImode);
1148 (define_insn_and_split "cbranchdi4_i"
1150 (if_then_else (match_operator 0 "comparison_operator"
1151 [(match_operand:DI 1 "arith_operand" "r,r")
1152 (match_operand:DI 2 "arith_operand" "rN,I08")])
1153 (label_ref (match_operand 3 "" ""))
1155 (clobber (match_scratch:SI 4 "=X,&r"))
1156 (clobber (reg:SI T_REG))]
1159 "&& reload_completed"
1162 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1167 ;; -------------------------------------------------------------------------
1168 ;; DImode signed integer comparisons
1169 ;; -------------------------------------------------------------------------
1172 [(set (reg:SI T_REG)
1173 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1174 (match_operand:DI 1 "arith_operand" "r"))
1178 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1181 [(set_attr "length" "6")
1182 (set_attr "type" "arith3b")])
1184 (define_insn "cmpeqdi_t"
1185 [(set (reg:SI T_REG)
1186 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1187 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1190 static const char* alt[] =
1197 "cmp/eq %S1,%S0" "\n"
1199 " cmp/eq %R1,%R0" "\n"
1202 return alt[which_alternative];
1204 [(set_attr "length" "6")
1205 (set_attr "type" "arith3b")])
1208 [(set (reg:SI T_REG)
1209 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1210 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1211 ;; If we applied this split when not optimizing, it would only be
1212 ;; applied during the machine-dependent reorg, when no new basic blocks
1214 "TARGET_SH1 && reload_completed && optimize"
1215 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1216 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1217 (label_ref (match_dup 6))
1219 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1222 operands[2] = gen_highpart (SImode, operands[0]);
1223 operands[3] = operands[1] == const0_rtx
1225 : gen_highpart (SImode, operands[1]);
1226 operands[4] = gen_lowpart (SImode, operands[0]);
1227 operands[5] = gen_lowpart (SImode, operands[1]);
1228 operands[6] = gen_label_rtx ();
1231 (define_insn "cmpgtdi_t"
1232 [(set (reg:SI T_REG)
1233 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1234 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1237 static const char* alt[] =
1239 "cmp/eq %S1,%S0" "\n"
1241 " cmp/gt %S1,%S0" "\n"
1242 " cmp/hi %R1,%R0" "\n"
1248 " cmp/hi %S0,%R0" "\n"
1251 return alt[which_alternative];
1253 [(set_attr "length" "8")
1254 (set_attr "type" "arith3")])
1256 (define_insn "cmpgedi_t"
1257 [(set (reg:SI T_REG)
1258 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1259 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1262 static const char* alt[] =
1264 "cmp/eq %S1,%S0" "\n"
1266 " cmp/ge %S1,%S0" "\n"
1267 " cmp/hs %R1,%R0" "\n"
1272 return alt[which_alternative];
1274 [(set_attr "length" "8,2")
1275 (set_attr "type" "arith3,mt_group")])
1277 ;; -------------------------------------------------------------------------
1278 ;; DImode unsigned integer comparisons
1279 ;; -------------------------------------------------------------------------
1281 (define_insn "cmpgeudi_t"
1282 [(set (reg:SI T_REG)
1283 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1284 (match_operand:DI 1 "arith_reg_operand" "r")))]
1287 return "cmp/eq %S1,%S0" "\n"
1289 " cmp/hs %S1,%S0" "\n"
1290 " cmp/hs %R1,%R0" "\n"
1293 [(set_attr "length" "8")
1294 (set_attr "type" "arith3")])
1296 (define_insn "cmpgtudi_t"
1297 [(set (reg:SI T_REG)
1298 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1299 (match_operand:DI 1 "arith_reg_operand" "r")))]
1302 return "cmp/eq %S1,%S0" "\n"
1304 " cmp/hi %S1,%S0" "\n"
1305 " cmp/hi %R1,%R0" "\n"
1308 [(set_attr "length" "8")
1309 (set_attr "type" "arith3")])
1311 (define_insn "cmpeqsi_media"
1312 [(set (match_operand:SI 0 "register_operand" "=r")
1313 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1314 (match_operand:SI 2 "cmp_operand" "Nr")))]
1317 [(set_attr "type" "cmp_media")])
1319 (define_insn "cmpeqdi_media"
1320 [(set (match_operand:SI 0 "register_operand" "=r")
1321 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1322 (match_operand:DI 2 "cmp_operand" "Nr")))]
1325 [(set_attr "type" "cmp_media")])
1327 (define_insn "cmpgtsi_media"
1328 [(set (match_operand:SI 0 "register_operand" "=r")
1329 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1330 (match_operand:SI 2 "cmp_operand" "rN")))]
1332 "cmpgt %N1, %N2, %0"
1333 [(set_attr "type" "cmp_media")])
1335 (define_insn "cmpgtdi_media"
1336 [(set (match_operand:SI 0 "register_operand" "=r")
1337 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1338 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1340 "cmpgt %N1, %N2, %0"
1341 [(set_attr "type" "cmp_media")])
1343 (define_insn "cmpgtusi_media"
1344 [(set (match_operand:SI 0 "register_operand" "=r")
1345 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1346 (match_operand:SI 2 "cmp_operand" "rN")))]
1348 "cmpgtu %N1, %N2, %0"
1349 [(set_attr "type" "cmp_media")])
1351 (define_insn "cmpgtudi_media"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1354 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1356 "cmpgtu %N1, %N2, %0"
1357 [(set_attr "type" "cmp_media")])
1359 ; This pattern is for combine.
1360 (define_insn "*cmpne0sisi_media"
1361 [(set (match_operand:SI 0 "register_operand" "=r")
1362 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1365 [(set_attr "type" "cmp_media")])
1367 ;; -------------------------------------------------------------------------
1368 ;; Conditional move instructions
1369 ;; -------------------------------------------------------------------------
1371 ;; The insn names may seem reversed, but note that cmveq performs the move
1372 ;; if op1 == 0, and cmvne does it if op1 != 0.
1374 (define_insn "movdicc_false"
1375 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1376 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1378 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1379 (match_operand:DI 3 "arith_reg_operand" "0")))]
1382 [(set_attr "type" "arith_media")])
1384 (define_insn "movdicc_true"
1385 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1386 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1388 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1389 (match_operand:DI 3 "arith_reg_operand" "0")))]
1392 [(set_attr "type" "arith_media")])
1395 [(set (match_operand:DI 0 "arith_reg_dest" "")
1396 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1397 [(match_operand:DI 1 "arith_reg_operand" "")
1399 (match_operand:DI 2 "arith_reg_dest" "")
1401 (set (match_dup 2) (match_dup 0))]
1402 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1404 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1406 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1407 VOIDmode, operands[1], CONST0_RTX (DImode));
1411 [(set (match_operand:DI 0 "general_movdst_operand" "")
1412 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1413 (set (match_operand:DI 2 "arith_reg_dest" "")
1414 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1415 [(match_operand:DI 3 "arith_reg_operand" "")
1419 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1421 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1424 (define_expand "movdicc"
1425 [(set (match_operand:DI 0 "register_operand" "")
1426 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1427 (match_operand:DI 2 "register_operand" "")
1428 (match_operand:DI 3 "register_operand" "")))]
1431 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1432 && GET_MODE (XEXP (operands[1], 0)) == DImode
1433 && XEXP (operands[1], 1) == const0_rtx)
1437 if (!can_create_pseudo_p ())
1440 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1441 GET_CODE (operands[1]),
1442 XEXP (operands[1], 0),
1443 XEXP (operands[1], 1));
1449 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1450 ;; SImode to DImode.
1451 (define_insn "movsicc_false"
1452 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1453 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1455 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1456 (match_operand:SI 3 "arith_reg_operand" "0")))]
1459 [(set_attr "type" "arith_media")])
1461 (define_insn "movsicc_true"
1462 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1463 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1465 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1466 (match_operand:SI 3 "arith_reg_operand" "0")))]
1469 [(set_attr "type" "arith_media")])
1472 [(set (match_operand:SI 0 "arith_reg_dest" "")
1473 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1474 [(match_operand:SI 1 "arith_reg_operand" "")
1476 (match_operand:SI 2 "arith_reg_dest" "")
1478 (set (match_dup 2) (match_dup 0))]
1479 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1481 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1483 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1484 VOIDmode, operands[1], CONST0_RTX (SImode));
1488 [(set (match_operand:SI 0 "general_movdst_operand" "")
1489 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1490 (set (match_operand:SI 2 "arith_reg_dest" "")
1491 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1492 [(match_operand:SI 3 "arith_reg_operand" "")
1496 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1497 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1499 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1501 replace_rtx (operands[4], operands[0], operands[1]);
1505 [(set (match_operand 0 "any_register_operand" "")
1506 (match_operand 1 "any_register_operand" ""))
1507 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1508 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1509 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1510 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1511 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1512 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1513 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1514 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1515 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1516 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1517 && (REGNO_REG_CLASS (REGNO (operands[0]))
1518 == REGNO_REG_CLASS (REGNO (operands[2])))
1519 && (REGNO_REG_CLASS (REGNO (operands[1]))
1520 == REGNO_REG_CLASS (REGNO (operands[0])))"
1521 [(set (match_dup 0) (match_dup 3))
1522 (set (match_dup 4) (match_dup 5))]
1524 rtx set1, set2, insn2;
1525 rtx replacements[4];
1527 /* We want to replace occurrences of operands[0] with operands[1] and
1528 operands[2] with operands[0] in operands[4]/operands[5].
1529 Doing just two replace_rtx calls naively would result in the second
1530 replacement undoing all that the first did if operands[1] and operands[2]
1531 are identical, so we must do this simultaneously. */
1532 replacements[0] = operands[0];
1533 replacements[1] = operands[1];
1534 replacements[2] = operands[2];
1535 replacements[3] = operands[0];
1536 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1537 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1538 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1541 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1542 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1543 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1544 /* The operands array is aliased to recog_data.operand, which gets
1545 clobbered by extract_insn, so finish with it now. */
1546 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1547 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1548 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1549 always uses emit_insn. */
1550 /* Check that we don't violate matching constraints or earlyclobbers. */
1551 extract_insn (emit_insn (set1));
1552 if (! constrain_operands (1))
1554 insn2 = emit (set2);
1555 if (GET_CODE (insn2) == BARRIER)
1557 extract_insn (insn2);
1558 if (! constrain_operands (1))
1562 tmp = replacements[0];
1563 replacements[0] = replacements[1];
1564 replacements[1] = tmp;
1565 tmp = replacements[2];
1566 replacements[2] = replacements[3];
1567 replacements[3] = tmp;
1568 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1569 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1570 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1576 ;; The register allocator is rather clumsy in handling multi-way conditional
1577 ;; moves, so allow the combiner to make them, and we split them up after
1579 (define_insn_and_split "*movsicc_umin"
1580 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1581 (umin:SI (if_then_else:SI
1582 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1584 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1585 (match_operand:SI 3 "register_operand" "0"))
1586 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1587 (clobber (match_scratch:SI 5 "=&r"))]
1588 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1590 "TARGET_SHMEDIA && reload_completed"
1593 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1595 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1596 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1601 (define_insn "*movsicc_t_false"
1602 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1603 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1604 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1605 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1606 "TARGET_PRETEND_CMOVE
1607 && (arith_reg_operand (operands[1], SImode)
1608 || (immediate_operand (operands[1], SImode)
1609 && satisfies_constraint_I08 (operands[1])))"
1615 [(set_attr "type" "mt_group,arith") ;; poor approximation
1616 (set_attr "length" "4")])
1618 (define_insn "*movsicc_t_true"
1619 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1620 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1621 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1622 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1623 "TARGET_PRETEND_CMOVE
1624 && (arith_reg_operand (operands[1], SImode)
1625 || (immediate_operand (operands[1], SImode)
1626 && satisfies_constraint_I08 (operands[1])))"
1632 [(set_attr "type" "mt_group,arith") ;; poor approximation
1633 (set_attr "length" "4")])
1635 (define_expand "movsicc"
1636 [(set (match_operand:SI 0 "arith_reg_dest" "")
1637 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1638 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1639 (match_operand:SI 3 "arith_reg_operand" "")))]
1640 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1642 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1643 && GET_MODE (XEXP (operands[1], 0)) == SImode
1645 || (REG_P (XEXP (operands[1], 0))
1646 && REGNO (XEXP (operands[1], 0)) == T_REG))
1647 && XEXP (operands[1], 1) == const0_rtx)
1650 else if (TARGET_PRETEND_CMOVE)
1652 enum rtx_code code = GET_CODE (operands[1]);
1653 enum rtx_code new_code = code;
1654 rtx op0 = XEXP (operands[1], 0);
1655 rtx op1 = XEXP (operands[1], 1);
1657 if (! currently_expanding_to_rtl)
1661 case LT: case LE: case LEU: case LTU:
1662 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1665 new_code = reverse_condition (code);
1667 case EQ: case GT: case GE: case GEU: case GTU:
1672 sh_emit_scc_to_t (new_code, op0, op1);
1673 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1674 gen_rtx_REG (SImode, T_REG), const0_rtx);
1678 if (!can_create_pseudo_p ())
1681 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1682 GET_CODE (operands[1]),
1683 XEXP (operands[1], 0),
1684 XEXP (operands[1], 1));
1690 (define_expand "movqicc"
1691 [(set (match_operand:QI 0 "register_operand" "")
1692 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1693 (match_operand:QI 2 "register_operand" "")
1694 (match_operand:QI 3 "register_operand" "")))]
1697 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1698 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1699 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1700 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1704 ;; -------------------------------------------------------------------------
1705 ;; Addition instructions
1706 ;; -------------------------------------------------------------------------
1708 (define_expand "adddi3"
1709 [(set (match_operand:DI 0 "arith_reg_operand" "")
1710 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1711 (match_operand:DI 2 "arith_operand" "")))]
1716 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1718 operands[2] = force_reg (DImode, operands[2]);
1719 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1724 (define_insn "*adddi3_media"
1725 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1726 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1727 (match_operand:DI 2 "arith_operand" "r,I10")))]
1732 [(set_attr "type" "arith_media")])
1734 (define_insn "*adddisi3_media"
1735 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1736 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1737 (match_operand:DI 2 "arith_operand" "r,I10")))]
1742 [(set_attr "type" "arith_media")
1743 (set_attr "highpart" "ignore")])
1745 (define_insn "adddi3z_media"
1746 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1748 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1749 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1751 "addz.l %1, %N2, %0"
1752 [(set_attr "type" "arith_media")
1753 (set_attr "highpart" "ignore")])
1755 (define_insn_and_split "adddi3_compact"
1756 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1757 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1758 (match_operand:DI 2 "arith_reg_operand" "r")))
1759 (clobber (reg:SI T_REG))]
1762 "&& reload_completed"
1765 rtx high0 = gen_highpart (SImode, operands[0]);
1766 rtx high2 = gen_highpart (SImode, operands[2]);
1767 rtx low0 = gen_lowpart (SImode, operands[0]);
1769 emit_insn (gen_clrt ());
1770 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1771 emit_insn (gen_addc (high0, high0, high2));
1776 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1777 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1778 (match_operand:SI 2 "arith_reg_operand" "r"))
1781 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1784 [(set_attr "type" "arith")])
1786 ;; A simplified version of the addc insn, where the exact value of the
1787 ;; T bit doesn't matter. This is easier for combine to pick up.
1788 ;; We allow a reg or 0 for one of the operands in order to be able to
1789 ;; do 'reg + T' sequences. Reload will load the constant 0 into the reg
1791 (define_insn "*addc"
1792 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1793 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1794 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1795 (match_operand:SI 3 "t_reg_operand" "")))
1796 (clobber (reg:SI T_REG))]
1799 [(set_attr "type" "arith")])
1801 ;; Split 'reg + reg + 1' into a sett addc sequence, as it can be scheduled
1802 ;; better, if the sett insn can be done early.
1803 (define_insn_and_split "*addc"
1804 [(set (match_operand:SI 0 "arith_reg_dest" "")
1805 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
1806 (match_operand:SI 2 "arith_reg_operand" ""))
1808 (clobber (reg:SI T_REG))]
1812 [(set (reg:SI T_REG) (const_int 1))
1813 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
1815 (clobber (reg:SI T_REG))])])
1817 ;; Left shifts by one are usually done with an add insn to avoid T_REG
1818 ;; clobbers. Thus addc can also be used to do something like '(x << 1) + 1'.
1819 (define_insn_and_split "*addc"
1820 [(set (match_operand:SI 0 "arith_reg_dest")
1821 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
1824 (clobber (reg:SI T_REG))]
1828 [(set (reg:SI T_REG) (const_int 1))
1829 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
1831 (clobber (reg:SI T_REG))])])
1833 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1834 ;; matched. Split this up into a simple sub add sequence, as this will save
1835 ;; us one sett insn.
1836 (define_insn_and_split "*minus_plus_one"
1837 [(set (match_operand:SI 0 "arith_reg_dest" "")
1838 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1839 (match_operand:SI 2 "arith_reg_operand" ""))
1844 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1845 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
1847 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
1848 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1849 ;; operation, as opposed to sequences such as
1853 ;; Even if the constant is not CSE-ed, a sequence such as
1856 ;; can be scheduled much better since the load of the constant can be
1857 ;; done earlier, before any comparison insns that store the result in
1859 (define_insn_and_split "*addc"
1860 [(set (match_operand:SI 0 "arith_reg_dest" "")
1861 (plus:SI (match_operand:SI 1 "t_reg_operand" "")
1862 (match_operand:SI 2 "arith_reg_operand" "")))
1863 (clobber (reg:SI T_REG))]
1867 [(parallel [(set (match_dup 0)
1868 (plus:SI (plus:SI (match_dup 2) (const_int 0))
1870 (clobber (reg:SI T_REG))])])
1872 (define_expand "addsi3"
1873 [(set (match_operand:SI 0 "arith_reg_operand" "")
1874 (plus:SI (match_operand:SI 1 "arith_operand" "")
1875 (match_operand:SI 2 "arith_operand" "")))]
1879 operands[1] = force_reg (SImode, operands[1]);
1882 (define_insn "addsi3_media"
1883 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1884 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1885 (match_operand:SI 2 "arith_operand" "r,I10")))]
1890 [(set_attr "type" "arith_media")
1891 (set_attr "highpart" "ignore")])
1893 (define_insn "addsidi3_media"
1894 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1895 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1897 (match_operand:SI 2 "arith_operand"
1903 [(set_attr "type" "arith_media")
1904 (set_attr "highpart" "ignore")])
1906 (define_insn "*addsi3_compact"
1907 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1908 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1909 (match_operand:SI 2 "arith_operand" "rI08")))]
1912 [(set_attr "type" "arith")])
1914 ;; -------------------------------------------------------------------------
1915 ;; Subtraction instructions
1916 ;; -------------------------------------------------------------------------
1918 (define_expand "subdi3"
1919 [(set (match_operand:DI 0 "arith_reg_operand" "")
1920 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1921 (match_operand:DI 2 "arith_reg_operand" "")))]
1926 operands[1] = force_reg (DImode, operands[1]);
1927 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1932 (define_insn "*subdi3_media"
1933 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1934 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1935 (match_operand:DI 2 "arith_reg_operand" "r")))]
1938 [(set_attr "type" "arith_media")])
1940 (define_insn "subdisi3_media"
1941 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1942 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1943 (match_operand:DI 2 "arith_reg_operand" "r")))]
1946 [(set_attr "type" "arith_media")
1947 (set_attr "highpart" "ignore")])
1949 (define_insn_and_split "subdi3_compact"
1950 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1951 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1952 (match_operand:DI 2 "arith_reg_operand" "r")))
1953 (clobber (reg:SI T_REG))]
1956 "&& reload_completed"
1959 rtx high0 = gen_highpart (SImode, operands[0]);
1960 rtx high2 = gen_highpart (SImode, operands[2]);
1961 rtx low0 = gen_lowpart (SImode, operands[0]);
1963 emit_insn (gen_clrt ());
1964 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1965 emit_insn (gen_subc (high0, high0, high2));
1970 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1971 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1972 (match_operand:SI 2 "arith_reg_operand" "r"))
1975 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1980 [(set_attr "type" "arith")])
1982 ;; A simplified version of the subc insn, where the exact value of the
1983 ;; T bit doesn't matter. This is easier for combine to pick up.
1984 ;; We allow a reg or 0 for one of the operands in order to be able to
1985 ;; do 'reg - T' sequences. Reload will load the constant 0 into the reg
1987 (define_insn "*subc"
1988 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1989 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1990 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1991 (match_operand:SI 3 "t_reg_operand" "")))
1992 (clobber (reg:SI T_REG))]
1995 [(set_attr "type" "arith")])
1997 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
1998 ;; better, if the sett insn can be done early.
1999 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
2000 (define_insn_and_split "*subc"
2001 [(set (match_operand:SI 0 "arith_reg_dest" "")
2002 (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
2003 (match_operand:SI 2 "arith_reg_operand" "")))
2004 (clobber (reg:SI T_REG))]
2008 [(set (reg:SI T_REG) (const_int 1))
2009 (parallel [(set (match_dup 0)
2010 (minus:SI (minus:SI (match_dup 2) (match_dup 1))
2012 (clobber (reg:SI T_REG))])])
2014 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
2015 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2016 ;; operation, as opposed to sequences such as
2020 ;; Even if the constant is not CSE-ed, a sequence such as
2023 ;; can be scheduled much better since the load of the constant can be
2024 ;; done earlier, before any comparison insns that store the result in
2026 (define_insn_and_split "*subc"
2027 [(set (match_operand:SI 0 "arith_reg_dest" "")
2028 (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2029 (match_operand:SI 2 "t_reg_operand" "")))
2030 (clobber (reg:SI T_REG))]
2034 [(parallel [(set (match_dup 0)
2035 (minus:SI (minus:SI (match_dup 1) (const_int 0))
2037 (clobber (reg:SI T_REG))])])
2039 (define_insn "*subsi3_internal"
2040 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2041 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2042 (match_operand:SI 2 "arith_reg_operand" "r")))]
2045 [(set_attr "type" "arith")])
2047 (define_insn_and_split "*subsi3_media"
2048 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2049 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2050 (match_operand:SI 2 "extend_reg_operand" "r")))]
2052 && (operands[1] != constm1_rtx
2053 || (GET_CODE (operands[2]) != TRUNCATE
2054 && GET_CODE (operands[2]) != SUBREG))"
2056 "operands[1] == constm1_rtx"
2057 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2059 [(set_attr "type" "arith_media")
2060 (set_attr "highpart" "ignore")])
2063 [(set (match_operand:SI 0 "arith_reg_dest" "")
2064 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2065 "general_extend_operand"
2067 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2068 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2069 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2073 [(set (match_operand:SI 0 "arith_reg_dest" "")
2074 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2075 "general_extend_operand"
2077 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
2078 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2079 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2081 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
2082 ;; will sometimes save one instruction. Otherwise we might get
2083 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
2086 (define_expand "subsi3"
2087 [(set (match_operand:SI 0 "arith_reg_operand" "")
2088 (minus:SI (match_operand:SI 1 "arith_operand" "")
2089 (match_operand:SI 2 "arith_reg_operand" "")))]
2092 if (TARGET_SH1 && CONST_INT_P (operands[1]))
2094 emit_insn (gen_negsi2 (operands[0], operands[2]));
2095 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2100 if (!can_create_pseudo_p ()
2101 && ! arith_reg_or_0_operand (operands[1], SImode))
2103 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2104 operands[1] = force_reg (SImode, operands[1]);
2108 ;; -------------------------------------------------------------------------
2109 ;; Division instructions
2110 ;; -------------------------------------------------------------------------
2112 ;; We take advantage of the library routines which don't clobber as many
2113 ;; registers as a normal function call would.
2115 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2116 ;; also has an effect on the register that holds the address of the sfunc.
2117 ;; To make this work, we have an extra dummy insn that shows the use
2118 ;; of this register for reorg.
2120 (define_insn "use_sfunc_addr"
2121 [(set (reg:SI PR_REG)
2122 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2123 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2125 [(set_attr "length" "0")])
2127 (define_insn "udivsi3_sh2a"
2128 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2129 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2130 (match_operand:SI 2 "arith_reg_operand" "z")))]
2133 [(set_attr "type" "arith")
2134 (set_attr "in_delay_slot" "no")])
2136 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2137 ;; hard register 0. If we used hard register 0, then the next instruction
2138 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
2139 ;; gets allocated to a stack slot that needs its address reloaded, then
2140 ;; there is nothing to prevent reload from using r0 to reload the address.
2141 ;; This reload would clobber the value in r0 we are trying to store.
2142 ;; If we let reload allocate r0, then this problem can never happen.
2144 (define_insn "udivsi3_i1"
2145 [(set (match_operand:SI 0 "register_operand" "=z")
2146 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2147 (clobber (reg:SI T_REG))
2148 (clobber (reg:SI PR_REG))
2149 (clobber (reg:SI R4_REG))
2150 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2151 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
2153 [(set_attr "type" "sfunc")
2154 (set_attr "needs_delay_slot" "yes")])
2156 ; Since shmedia-nofpu code could be linked against shcompact code, and
2157 ; the udivsi3 libcall has the same name, we must consider all registers
2158 ; clobbered that are in the union of the registers clobbered by the
2159 ; shmedia and the shcompact implementation. Note, if the shcompact
2160 ; implementation actually used shcompact code, we'd need to clobber
2161 ; also r23 and fr23.
2162 (define_insn "udivsi3_i1_media"
2163 [(set (match_operand:SI 0 "register_operand" "=z")
2164 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2165 (clobber (reg:SI T_MEDIA_REG))
2166 (clobber (reg:SI PR_MEDIA_REG))
2167 (clobber (reg:SI R20_REG))
2168 (clobber (reg:SI R21_REG))
2169 (clobber (reg:SI R22_REG))
2170 (clobber (reg:DI TR0_REG))
2171 (clobber (reg:DI TR1_REG))
2172 (clobber (reg:DI TR2_REG))
2173 (use (match_operand 1 "target_reg_operand" "b"))]
2174 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2176 [(set_attr "type" "sfunc")
2177 (set_attr "needs_delay_slot" "yes")])
2179 (define_expand "udivsi3_i4_media"
2181 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2183 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2184 (set (match_dup 5) (float:DF (match_dup 3)))
2185 (set (match_dup 6) (float:DF (match_dup 4)))
2186 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2187 (set (match_dup 8) (fix:DI (match_dup 7)))
2188 (set (match_operand:SI 0 "register_operand" "")
2189 (truncate:SI (match_dup 8)))]
2190 "TARGET_SHMEDIA_FPU"
2192 operands[3] = gen_reg_rtx (DImode);
2193 operands[4] = gen_reg_rtx (DImode);
2194 operands[5] = gen_reg_rtx (DFmode);
2195 operands[6] = gen_reg_rtx (DFmode);
2196 operands[7] = gen_reg_rtx (DFmode);
2197 operands[8] = gen_reg_rtx (DImode);
2200 (define_insn "udivsi3_i4"
2201 [(set (match_operand:SI 0 "register_operand" "=y")
2202 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2203 (clobber (reg:SI T_REG))
2204 (clobber (reg:SI PR_REG))
2205 (clobber (reg:DF DR0_REG))
2206 (clobber (reg:DF DR2_REG))
2207 (clobber (reg:DF DR4_REG))
2208 (clobber (reg:SI R0_REG))
2209 (clobber (reg:SI R1_REG))
2210 (clobber (reg:SI R4_REG))
2211 (clobber (reg:SI R5_REG))
2212 (use (reg:PSI FPSCR_REG))
2213 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2214 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2216 [(set_attr "type" "sfunc")
2217 (set_attr "fp_mode" "double")
2218 (set_attr "needs_delay_slot" "yes")])
2220 (define_insn "udivsi3_i4_single"
2221 [(set (match_operand:SI 0 "register_operand" "=y")
2222 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2223 (clobber (reg:SI T_REG))
2224 (clobber (reg:SI PR_REG))
2225 (clobber (reg:DF DR0_REG))
2226 (clobber (reg:DF DR2_REG))
2227 (clobber (reg:DF DR4_REG))
2228 (clobber (reg:SI R0_REG))
2229 (clobber (reg:SI R1_REG))
2230 (clobber (reg:SI R4_REG))
2231 (clobber (reg:SI R5_REG))
2232 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2233 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2235 [(set_attr "type" "sfunc")
2236 (set_attr "needs_delay_slot" "yes")])
2238 (define_insn "udivsi3_i4_int"
2239 [(set (match_operand:SI 0 "register_operand" "=z")
2240 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2241 (clobber (reg:SI T_REG))
2242 (clobber (reg:SI R1_REG))
2243 (clobber (reg:SI PR_REG))
2244 (clobber (reg:SI MACH_REG))
2245 (clobber (reg:SI MACL_REG))
2246 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2249 [(set_attr "type" "sfunc")
2250 (set_attr "needs_delay_slot" "yes")])
2253 (define_expand "udivsi3"
2254 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2255 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2256 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2257 (parallel [(set (match_operand:SI 0 "register_operand" "")
2258 (udiv:SI (reg:SI R4_REG)
2260 (clobber (reg:SI T_REG))
2261 (clobber (reg:SI PR_REG))
2262 (clobber (reg:SI R4_REG))
2263 (use (match_dup 3))])]
2268 operands[3] = gen_reg_rtx (Pmode);
2269 /* Emit the move of the address to a pseudo outside of the libcall. */
2270 if (TARGET_DIVIDE_CALL_TABLE)
2272 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2273 that causes problems when the divide code is supposed to come from a
2274 separate library. Division by zero is undefined, so dividing 1 can be
2275 implemented by comparing with the divisor. */
2276 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2278 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2279 emit_insn (gen_cstoresi4 (operands[0], test,
2280 operands[1], operands[2]));
2283 else if (operands[2] == const0_rtx)
2285 emit_move_insn (operands[0], operands[2]);
2288 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2289 last = gen_udivsi3_i4_int (operands[0], operands[3]);
2291 else if (TARGET_DIVIDE_CALL_FP)
2293 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2294 if (TARGET_FPU_SINGLE)
2295 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2297 last = gen_udivsi3_i4 (operands[0], operands[3]);
2299 else if (TARGET_SHMEDIA_FPU)
2301 operands[1] = force_reg (SImode, operands[1]);
2302 operands[2] = force_reg (SImode, operands[2]);
2303 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2306 else if (TARGET_SH2A)
2308 operands[1] = force_reg (SImode, operands[1]);
2309 operands[2] = force_reg (SImode, operands[2]);
2310 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2313 else if (TARGET_SH5)
2315 function_symbol (operands[3],
2316 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2320 last = gen_udivsi3_i1_media (operands[0], operands[3]);
2321 else if (TARGET_FPU_ANY)
2322 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2324 last = gen_udivsi3_i1 (operands[0], operands[3]);
2328 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2329 last = gen_udivsi3_i1 (operands[0], operands[3]);
2331 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2332 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2337 (define_insn "divsi3_sh2a"
2338 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2339 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2340 (match_operand:SI 2 "arith_reg_operand" "z")))]
2343 [(set_attr "type" "arith")
2344 (set_attr "in_delay_slot" "no")])
2346 (define_insn "divsi3_i1"
2347 [(set (match_operand:SI 0 "register_operand" "=z")
2348 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2349 (clobber (reg:SI T_REG))
2350 (clobber (reg:SI PR_REG))
2351 (clobber (reg:SI R1_REG))
2352 (clobber (reg:SI R2_REG))
2353 (clobber (reg:SI R3_REG))
2354 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2355 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
2357 [(set_attr "type" "sfunc")
2358 (set_attr "needs_delay_slot" "yes")])
2360 (define_insn "divsi3_i1_media"
2361 [(set (match_operand:SI 0 "register_operand" "=z")
2362 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2363 (clobber (reg:SI T_MEDIA_REG))
2364 (clobber (reg:SI PR_MEDIA_REG))
2365 (clobber (reg:SI R1_REG))
2366 (clobber (reg:SI R20_REG))
2367 (clobber (reg:SI R21_REG))
2368 (clobber (reg:SI TR0_REG))
2369 (use (match_operand 1 "target_reg_operand" "b"))]
2370 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2372 [(set_attr "type" "sfunc")])
2374 (define_insn "divsi3_media_2"
2375 [(set (match_operand:SI 0 "register_operand" "=z")
2376 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2377 (clobber (reg:SI T_MEDIA_REG))
2378 (clobber (reg:SI PR_MEDIA_REG))
2379 (clobber (reg:SI R1_REG))
2380 (clobber (reg:SI R21_REG))
2381 (clobber (reg:SI TR0_REG))
2382 (use (reg:SI R20_REG))
2383 (use (match_operand 1 "target_reg_operand" "b"))]
2384 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2386 [(set_attr "type" "sfunc")])
2388 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2389 ;; hard reg clobbers and data dependencies that we need when we want
2390 ;; to rematerialize the division into a call.
2391 (define_insn_and_split "divsi_inv_call"
2392 [(set (match_operand:SI 0 "register_operand" "=r")
2393 (div:SI (match_operand:SI 1 "register_operand" "r")
2394 (match_operand:SI 2 "register_operand" "r")))
2395 (clobber (reg:SI R4_REG))
2396 (clobber (reg:SI R5_REG))
2397 (clobber (reg:SI T_MEDIA_REG))
2398 (clobber (reg:SI PR_MEDIA_REG))
2399 (clobber (reg:SI R1_REG))
2400 (clobber (reg:SI R21_REG))
2401 (clobber (reg:SI TR0_REG))
2402 (clobber (reg:SI R20_REG))
2403 (use (match_operand:SI 3 "register_operand" "r"))]
2406 "&& (reload_in_progress || reload_completed)"
2407 [(set (match_dup 0) (match_dup 3))]
2409 [(set_attr "highpart" "must_split")])
2411 ;; This is the combiner pattern for -mdiv=inv:call .
2412 (define_insn_and_split "*divsi_inv_call_combine"
2413 [(set (match_operand:SI 0 "register_operand" "=z")
2414 (div:SI (match_operand:SI 1 "register_operand" "r")
2415 (match_operand:SI 2 "register_operand" "r")))
2416 (clobber (reg:SI R4_REG))
2417 (clobber (reg:SI R5_REG))
2418 (clobber (reg:SI T_MEDIA_REG))
2419 (clobber (reg:SI PR_MEDIA_REG))
2420 (clobber (reg:SI R1_REG))
2421 (clobber (reg:SI R21_REG))
2422 (clobber (reg:SI TR0_REG))
2423 (clobber (reg:SI R20_REG))
2424 (use (unspec:SI [(match_dup 1)
2425 (match_operand:SI 3 "" "")
2426 (unspec:SI [(match_operand:SI 4 "" "")
2428 (match_operand:DI 5 "" "")]
2430 (match_operand:DI 6 "" "")
2433 UNSPEC_DIV_INV_M3))]
2436 "&& (reload_in_progress || reload_completed)"
2439 const char *name = sh_divsi3_libfunc;
2440 enum sh_function_kind kind = SFUNC_GOT;
2443 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2444 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2445 while (TARGET_DIVIDE_INV_CALL2)
2447 rtx x = operands[3];
2449 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2451 x = XVECEXP (x, 0, 0);
2452 name = "__sdivsi3_2";
2453 kind = SFUNC_STATIC;
2454 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2457 sym = function_symbol (NULL, name, kind);
2458 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2461 [(set_attr "highpart" "must_split")])
2463 (define_expand "divsi3_i4_media"
2464 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2465 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2466 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2467 (set (match_operand:SI 0 "register_operand" "=r")
2468 (fix:SI (match_dup 5)))]
2469 "TARGET_SHMEDIA_FPU"
2471 operands[3] = gen_reg_rtx (DFmode);
2472 operands[4] = gen_reg_rtx (DFmode);
2473 operands[5] = gen_reg_rtx (DFmode);
2476 (define_insn "divsi3_i4"
2477 [(set (match_operand:SI 0 "register_operand" "=y")
2478 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2479 (clobber (reg:SI PR_REG))
2480 (clobber (reg:DF DR0_REG))
2481 (clobber (reg:DF DR2_REG))
2482 (use (reg:PSI FPSCR_REG))
2483 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2484 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2486 [(set_attr "type" "sfunc")
2487 (set_attr "fp_mode" "double")
2488 (set_attr "needs_delay_slot" "yes")])
2490 (define_insn "divsi3_i4_single"
2491 [(set (match_operand:SI 0 "register_operand" "=y")
2492 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2493 (clobber (reg:SI PR_REG))
2494 (clobber (reg:DF DR0_REG))
2495 (clobber (reg:DF DR2_REG))
2496 (clobber (reg:SI R2_REG))
2497 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2498 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2500 [(set_attr "type" "sfunc")
2501 (set_attr "needs_delay_slot" "yes")])
2503 (define_insn "divsi3_i4_int"
2504 [(set (match_operand:SI 0 "register_operand" "=z")
2505 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2506 (clobber (reg:SI T_REG))
2507 (clobber (reg:SI PR_REG))
2508 (clobber (reg:SI R1_REG))
2509 (clobber (reg:SI MACH_REG))
2510 (clobber (reg:SI MACL_REG))
2511 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2514 [(set_attr "type" "sfunc")
2515 (set_attr "needs_delay_slot" "yes")])
2517 (define_expand "divsi3"
2518 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2519 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2520 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2521 (parallel [(set (match_operand:SI 0 "register_operand" "")
2522 (div:SI (reg:SI R4_REG)
2524 (clobber (reg:SI T_REG))
2525 (clobber (reg:SI PR_REG))
2526 (clobber (reg:SI R1_REG))
2527 (clobber (reg:SI R2_REG))
2528 (clobber (reg:SI R3_REG))
2529 (use (match_dup 3))])]
2534 operands[3] = gen_reg_rtx (Pmode);
2535 /* Emit the move of the address to a pseudo outside of the libcall. */
2536 if (TARGET_DIVIDE_CALL_TABLE)
2538 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2539 last = gen_divsi3_i4_int (operands[0], operands[3]);
2541 else if (TARGET_DIVIDE_CALL_FP)
2543 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2544 if (TARGET_FPU_SINGLE)
2545 last = gen_divsi3_i4_single (operands[0], operands[3]);
2547 last = gen_divsi3_i4 (operands[0], operands[3]);
2549 else if (TARGET_SH2A)
2551 operands[1] = force_reg (SImode, operands[1]);
2552 operands[2] = force_reg (SImode, operands[2]);
2553 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2556 else if (TARGET_DIVIDE_INV)
2558 rtx dividend = operands[1];
2559 rtx divisor = operands[2];
2561 rtx nsb_res = gen_reg_rtx (DImode);
2562 rtx norm64 = gen_reg_rtx (DImode);
2563 rtx tab_ix = gen_reg_rtx (DImode);
2564 rtx norm32 = gen_reg_rtx (SImode);
2565 rtx i92 = force_reg (DImode, GEN_INT (92));
2566 rtx scratch0a = gen_reg_rtx (DImode);
2567 rtx scratch0b = gen_reg_rtx (DImode);
2568 rtx inv0 = gen_reg_rtx (SImode);
2569 rtx scratch1a = gen_reg_rtx (DImode);
2570 rtx scratch1b = gen_reg_rtx (DImode);
2571 rtx shift = gen_reg_rtx (DImode);
2573 rtx inv1 = gen_reg_rtx (SImode);
2574 rtx scratch2a = gen_reg_rtx (DImode);
2575 rtx scratch2b = gen_reg_rtx (SImode);
2576 rtx inv2 = gen_reg_rtx (SImode);
2577 rtx scratch3a = gen_reg_rtx (DImode);
2578 rtx scratch3b = gen_reg_rtx (DImode);
2579 rtx scratch3c = gen_reg_rtx (DImode);
2580 rtx scratch3d = gen_reg_rtx (SImode);
2581 rtx scratch3e = gen_reg_rtx (DImode);
2582 rtx result = gen_reg_rtx (SImode);
2584 if (! arith_reg_or_0_operand (dividend, SImode))
2585 dividend = force_reg (SImode, dividend);
2586 if (! arith_reg_operand (divisor, SImode))
2587 divisor = force_reg (SImode, divisor);
2588 if (flag_pic && Pmode != DImode)
2590 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2591 tab_base = gen_datalabel_ref (tab_base);
2592 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2596 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2597 tab_base = gen_datalabel_ref (tab_base);
2598 tab_base = force_reg (DImode, tab_base);
2600 if (TARGET_DIVIDE_INV20U)
2601 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2603 i2p27 = GEN_INT (0);
2604 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2605 i43 = force_reg (DImode, GEN_INT (43));
2608 emit_insn (gen_nsbdi (nsb_res,
2609 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2610 emit_insn (gen_ashldi3_media (norm64,
2611 gen_rtx_SUBREG (DImode, divisor, 0),
2613 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2614 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2615 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2616 inv0, scratch0a, scratch0b,
2617 scratch1a, scratch1b));
2618 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2619 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2621 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2623 scratch3a, scratch3b, scratch3c,
2624 scratch2a, scratch2b, scratch3d, scratch3e));
2625 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2626 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2627 else if (TARGET_DIVIDE_INV_FP)
2628 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2629 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2630 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2631 gen_reg_rtx (DFmode)));
2633 emit_move_insn (operands[0], result);
2636 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2638 operands[1] = force_reg (SImode, operands[1]);
2639 operands[2] = force_reg (SImode, operands[2]);
2640 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2643 else if (TARGET_SH5)
2645 if (TARGET_DIVIDE_CALL2)
2647 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2648 tab_base = gen_datalabel_ref (tab_base);
2649 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2651 if (TARGET_FPU_ANY && TARGET_SH1)
2652 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2653 else if (TARGET_DIVIDE_CALL2)
2654 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2656 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2659 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2660 (operands[0], operands[3]));
2661 else if (TARGET_FPU_ANY)
2662 last = gen_divsi3_i4_single (operands[0], operands[3]);
2664 last = gen_divsi3_i1 (operands[0], operands[3]);
2668 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2669 last = gen_divsi3_i1 (operands[0], operands[3]);
2671 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2672 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2677 ;; operands: scratch, tab_base, tab_ix
2678 ;; These are unspecs because we could generate an indexed addressing mode
2679 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2680 ;; confuse reload. See PR27117.
2682 (define_insn "divsi_inv_qitable"
2683 [(set (match_operand:DI 0 "register_operand" "=r")
2684 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2685 (match_operand:DI 2 "register_operand" "r")]
2686 UNSPEC_DIV_INV_TABLE)))]
2689 [(set_attr "type" "load_media")
2690 (set_attr "highpart" "user")])
2692 ;; operands: scratch, tab_base, tab_ix
2693 (define_insn "divsi_inv_hitable"
2694 [(set (match_operand:DI 0 "register_operand" "=r")
2695 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2696 (match_operand:DI 2 "register_operand" "r")]
2697 UNSPEC_DIV_INV_TABLE)))]
2700 [(set_attr "type" "load_media")
2701 (set_attr "highpart" "user")])
2703 ;; operands: inv0, tab_base, tab_ix, norm32
2704 ;; scratch equiv in sdivsi3_2: r19, r21
2705 (define_expand "divsi_inv_m0"
2706 [(set (match_operand:SI 0 "register_operand" "=r")
2707 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2708 (match_operand:DI 2 "register_operand" "r")
2709 (match_operand:SI 3 "register_operand" "r")]
2711 (clobber (match_operand:DI 4 "register_operand" "=r"))
2712 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2719 ldx.ub r20, r21, r19 // u0.8
2721 muls.l r25, r19, r19 // s2.38
2722 ldx.w r20, r21, r21 // s2.14
2723 shari r19, 24, r19 // truncate to s2.14
2724 sub r21, r19, r19 // some 11 bit inverse in s1.14
2727 rtx inv0 = operands[0];
2728 rtx tab_base = operands[1];
2729 rtx tab_ix = operands[2];
2730 rtx norm32 = operands[3];
2731 rtx scratch0 = operands[4];
2732 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2733 rtx scratch1 = operands[5];
2735 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2736 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2737 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2738 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2739 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2740 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2744 ;; operands: inv1, tab_base, tab_ix, norm32
2745 (define_insn_and_split "divsi_inv_m1"
2746 [(set (match_operand:SI 0 "register_operand" "=r")
2747 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2748 (match_operand:DI 2 "register_operand" "r")
2749 (match_operand:SI 3 "register_operand" "r")]
2751 (clobber (match_operand:SI 4 "register_operand" "=r"))
2752 (clobber (match_operand:DI 5 "register_operand" "=r"))
2753 (clobber (match_operand:DI 6 "register_operand" "=r"))
2754 (clobber (match_operand:DI 7 "register_operand" "=r"))
2755 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2758 "&& !can_create_pseudo_p ()"
2762 muls.l r19, r19, r18 // u0.28
2763 muls.l r25, r18, r18 // s2.58
2764 shlli r19, 45, r0 // multiply by two and convert to s2.58
2766 shari r18, 28, r18 // some 18 bit inverse in s1.30
2769 rtx inv1 = operands[0];
2770 rtx tab_base = operands[1];
2771 rtx tab_ix = operands[2];
2772 rtx norm32 = operands[3];
2773 rtx inv0 = operands[4];
2774 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2775 rtx scratch0a = operands[5];
2776 rtx scratch0b = operands[6];
2777 rtx scratch0 = operands[7];
2778 rtx scratch1 = operands[8];
2779 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2781 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2782 scratch0a, scratch0b));
2783 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2784 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2785 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2786 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2787 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2791 ;; operands: inv2, norm32, inv1, i92
2792 (define_insn_and_split "divsi_inv_m2"
2793 [(set (match_operand:SI 0 "register_operand" "=r")
2794 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2795 (match_operand:SI 2 "register_operand" "r")
2796 (match_operand:DI 3 "register_operand" "r")]
2798 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2801 "&& !can_create_pseudo_p ()"
2805 muls.l r18, r25, r0 // s2.60
2806 shari r0, 16, r0 // s-16.44
2808 muls.l r0, r18, r19 // s-16.74
2809 shari r19, 30, r19 // s-16.44
2811 rtx inv2 = operands[0];
2812 rtx norm32 = operands[1];
2813 rtx inv1 = operands[2];
2814 rtx i92 = operands[3];
2815 rtx scratch0 = operands[4];
2816 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2818 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2819 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2820 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2821 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2822 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2826 (define_insn_and_split "divsi_inv_m3"
2827 [(set (match_operand:SI 0 "register_operand" "=r")
2828 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2829 (match_operand:SI 2 "register_operand" "r")
2830 (match_operand:SI 3 "register_operand" "r")
2831 (match_operand:DI 4 "register_operand" "r")
2832 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2833 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2835 (clobber (match_operand:DI 7 "register_operand" "=r"))
2836 (clobber (match_operand:DI 8 "register_operand" "=r"))
2837 (clobber (match_operand:DI 9 "register_operand" "=r"))
2838 (clobber (match_operand:DI 10 "register_operand" "=r"))
2839 (clobber (match_operand:SI 11 "register_operand" "=r"))
2840 (clobber (match_operand:SI 12 "register_operand" "=r"))
2841 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2844 "&& !can_create_pseudo_p ()"
2848 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2849 r0: scratch0 r19: scratch1 r21: scratch2
2851 muls.l r18, r4, r25 // s32.30
2852 muls.l r19, r4, r19 // s15.30
2854 shari r19, 14, r19 // s18.-14
2860 rtx result = operands[0];
2861 rtx dividend = operands[1];
2862 rtx inv1 = operands[2];
2863 rtx inv2 = operands[3];
2864 rtx shift = operands[4];
2865 rtx scratch0 = operands[7];
2866 rtx scratch1 = operands[8];
2867 rtx scratch2 = operands[9];
2869 if (satisfies_constraint_N (dividend))
2871 emit_move_insn (result, dividend);
2875 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2876 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2877 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2878 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2879 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2880 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2881 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2885 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2886 ;; inv1: tab_base, tab_ix, norm32
2887 ;; inv2: norm32, inv1, i92
2888 (define_insn_and_split "divsi_inv_m1_3"
2889 [(set (match_operand:SI 0 "register_operand" "=r")
2890 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2891 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2892 (match_operand:DI 3 "register_operand" "r")
2893 (match_operand:SI 4 "register_operand" "r")]
2895 (unspec:SI [(match_dup 4)
2896 (unspec:SI [(match_dup 2)
2898 (match_dup 4)] UNSPEC_DIV_INV_M1)
2899 (match_operand:SI 5 "" "")]
2901 (match_operand:DI 6 "register_operand" "r")
2902 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2903 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2905 (clobber (match_operand:DI 9 "register_operand" "=r"))
2906 (clobber (match_operand:DI 10 "register_operand" "=r"))
2907 (clobber (match_operand:DI 11 "register_operand" "=r"))
2908 (clobber (match_operand:DI 12 "register_operand" "=r"))
2909 (clobber (match_operand:SI 13 "register_operand" "=r"))
2910 (clobber (match_operand:SI 14 "register_operand" "=r"))
2911 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2913 && (TARGET_DIVIDE_INV_MINLAT
2914 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2916 "&& !can_create_pseudo_p ()"
2919 rtx result = operands[0];
2920 rtx dividend = operands[1];
2921 rtx tab_base = operands[2];
2922 rtx tab_ix = operands[3];
2923 rtx norm32 = operands[4];
2924 /* rtx i92 = operands[5]; */
2925 rtx shift = operands[6];
2926 rtx i2p27 = operands[7];
2927 rtx i43 = operands[8];
2928 rtx scratch0 = operands[9];
2929 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2930 rtx scratch1 = operands[10];
2931 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2932 rtx scratch2 = operands[11];
2933 rtx scratch3 = operands[12];
2934 rtx scratch4 = operands[13];
2935 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2936 rtx scratch5 = operands[14];
2937 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2938 rtx scratch6 = operands[15];
2940 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2941 scratch0, scratch1));
2942 /* inv0 == scratch4 */
2943 if (! TARGET_DIVIDE_INV20U)
2945 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2947 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2951 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2952 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2954 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2955 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2956 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2957 /* inv1 == scratch4 */
2959 if (TARGET_DIVIDE_INV_MINLAT)
2961 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2962 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2963 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2964 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2965 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2966 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2967 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2968 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2969 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2970 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2971 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2975 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2976 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2977 emit_insn (gen_nsbdi (scratch6,
2978 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2979 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2980 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2981 emit_insn (gen_divsi_inv20 (scratch2,
2982 norm32, scratch4, dividend,
2983 scratch6, scratch3, i43,
2984 /* scratch0 may be shared with i2p27. */
2985 scratch0, scratch1, scratch5,
2986 label, label, i2p27));
2988 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2989 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2993 (define_insn "divsi_inv20"
2994 [(set (match_operand:DI 0 "register_operand" "=&r")
2995 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2996 (match_operand:SI 2 "register_operand" "r")
2997 (match_operand:SI 3 "register_operand" "r")
2998 (match_operand:DI 4 "register_operand" "r")
2999 (match_operand:DI 5 "register_operand" "r")
3000 (match_operand:DI 6 "register_operand" "r")
3001 (match_operand:DI 12 "register_operand" "r")
3002 (match_operand 10 "target_operand" "b")
3003 (match_operand 11 "immediate_operand" "i")]
3005 (clobber (match_operand:DI 7 "register_operand" "=&r"))
3006 (clobber (match_operand:DI 8 "register_operand" "=&r"))
3007 (clobber (match_operand:SI 9 "register_operand" "=r"))]
3009 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3011 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
3012 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
3013 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
3014 %10 label (tr), %11 label (imm)
3016 muls.l inv1, norm32, scratch0 // s2.60
3017 muls.l inv1, dividend, result // s32.30
3018 xor i2p27, result_sign, round_scratch
3019 bge/u dividend_nsb, i43, tr.. (label)
3020 shari scratch0, 16, scratch0 // s-16.44
3021 muls.l sratch0_si, inv1, scratch0 // s-16.74
3022 sub result, round_scratch, result
3023 shari dividend, 14, scratch1 // s19.-14
3024 shari scratch0, 30, scratch0 // s-16.44
3025 muls.l scratch0, scratch1, round_scratch // s15.30
3027 sub result, round_scratch, result */
3029 const bool likely = TARGET_DIVIDE_INV20L;
3032 "muls.l %2, %3, %0" "\n"
3033 " xor %12, %5, %7" "\n"
3034 " bge/l %4, %6, %10" "\n"
3035 " muls.l %2, %1, %8" "\n"
3036 " shari %8, 16, %8" "\n"
3037 " muls.l %8, %2, %8" "\n"
3038 " shari %3, 14, %9" "\n"
3039 " shari %8, 30, %8" "\n"
3040 " muls.l %8, %9, %8" "\n"
3041 " sub %0, %8, %0" "\n"
3042 "%11: add %0, %7, %0";
3045 "muls.l %2, %1, %8" "\n"
3046 " muls.l %2, %3, %0" "\n"
3047 " xor %12, %5, %7" "\n"
3048 " bge/u %4, %6, %10" "\n"
3049 " shari %8, 16, %8" "\n"
3050 " muls.l %8, %2, %8" "\n"
3051 " sub %0, %7, %0" "\n"
3052 " shari %3, 14, %9" "\n"
3053 " shari %8, 30, %8" "\n"
3054 " muls.l %8, %9, %7" "\n"
3055 "%11: sub %0, %7, %0";
3058 (define_insn_and_split "divsi_inv_fp"
3059 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3060 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3061 (match_operand:SI 2 "register_operand" "rf")))
3062 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3063 (clobber (match_operand:SI 4 "register_operand" "=r"))
3064 (clobber (match_operand:SI 5 "register_operand" "=r"))
3065 (clobber (match_operand:DF 6 "register_operand" "=r"))
3066 (clobber (match_operand:DF 7 "register_operand" "=r"))
3067 (clobber (match_operand:DF 8 "register_operand" "=r"))]
3068 "TARGET_SHMEDIA_FPU"
3070 "&& (reload_in_progress || reload_completed)"
3071 [(set (match_dup 0) (match_dup 3))]
3073 [(set_attr "highpart" "must_split")])
3075 ;; If a matching group of divide-by-inverse instructions is in the same
3076 ;; basic block after gcse & loop optimizations, we want to transform them
3077 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3078 (define_insn_and_split "*divsi_inv_fp_combine"
3079 [(set (match_operand:SI 0 "register_operand" "=f")
3080 (div:SI (match_operand:SI 1 "register_operand" "f")
3081 (match_operand:SI 2 "register_operand" "f")))
3082 (use (unspec:SI [(match_dup 1)
3083 (match_operand:SI 3 "" "")
3084 (unspec:SI [(match_operand:SI 4 "" "")
3086 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3087 (match_operand:DI 6 "" "")
3089 (const_int 0)] UNSPEC_DIV_INV_M3))
3090 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3091 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3092 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3093 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3094 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3095 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3098 [(set (match_dup 9) (float:DF (match_dup 1)))
3099 (set (match_dup 10) (float:DF (match_dup 2)))
3100 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3102 (fix:SI (match_dup 11)))
3103 (set (match_dup 0) (match_dup 8))]
3105 if (! fp_arith_reg_operand (operands[1], SImode))
3107 emit_move_insn (operands[7], operands[1]);
3108 operands[1] = operands[7];
3110 if (! fp_arith_reg_operand (operands[2], SImode))
3112 emit_move_insn (operands[8], operands[2]);
3113 operands[2] = operands[8];
3116 [(set_attr "highpart" "must_split")])
3118 ;; -------------------------------------------------------------------------
3119 ;; Multiplication instructions
3120 ;; -------------------------------------------------------------------------
3122 (define_insn "umulhisi3_i"
3123 [(set (reg:SI MACL_REG)
3124 (mult:SI (zero_extend:SI
3125 (match_operand:HI 0 "arith_reg_operand" "r"))
3127 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3130 [(set_attr "type" "smpy")])
3132 (define_insn "mulhisi3_i"
3133 [(set (reg:SI MACL_REG)
3134 (mult:SI (sign_extend:SI
3135 (match_operand:HI 0 "arith_reg_operand" "r"))
3137 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3140 [(set_attr "type" "smpy")])
3142 (define_expand "mulhisi3"
3143 [(set (reg:SI MACL_REG)
3144 (mult:SI (sign_extend:SI
3145 (match_operand:HI 1 "arith_reg_operand" ""))
3147 (match_operand:HI 2 "arith_reg_operand" ""))))
3148 (set (match_operand:SI 0 "arith_reg_operand" "")
3154 macl = gen_rtx_REG (SImode, MACL_REG);
3156 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3157 insn = get_insns ();
3159 /* expand_binop can't find a suitable code in umul_widen_optab to
3160 make a REG_EQUAL note from, so make one here.
3161 See also smulsi3_highpart.
3162 ??? Alternatively, we could put this at the calling site of expand_binop,
3163 i.e. expand_expr. */
3164 /* Use emit_libcall_block for loop invariant code motion and to make
3165 a REG_EQUAL note. */
3166 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3171 (define_expand "umulhisi3"
3172 [(set (reg:SI MACL_REG)
3173 (mult:SI (zero_extend:SI
3174 (match_operand:HI 1 "arith_reg_operand" ""))
3176 (match_operand:HI 2 "arith_reg_operand" ""))))
3177 (set (match_operand:SI 0 "arith_reg_operand" "")
3183 macl = gen_rtx_REG (SImode, MACL_REG);
3185 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3186 insn = get_insns ();
3188 /* expand_binop can't find a suitable code in umul_widen_optab to
3189 make a REG_EQUAL note from, so make one here.
3190 See also smulsi3_highpart.
3191 ??? Alternatively, we could put this at the calling site of expand_binop,
3192 i.e. expand_expr. */
3193 /* Use emit_libcall_block for loop invariant code motion and to make
3194 a REG_EQUAL note. */
3195 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3200 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3201 ;; a call to a routine which clobbers known registers.
3204 [(set (match_operand:SI 1 "register_operand" "=z")
3205 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3206 (clobber (reg:SI MACL_REG))
3207 (clobber (reg:SI T_REG))
3208 (clobber (reg:SI PR_REG))
3209 (clobber (reg:SI R3_REG))
3210 (clobber (reg:SI R2_REG))
3211 (clobber (reg:SI R1_REG))
3212 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3215 [(set_attr "type" "sfunc")
3216 (set_attr "needs_delay_slot" "yes")])
3218 (define_expand "mulsi3_call"
3219 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3220 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3221 (parallel[(set (match_operand:SI 0 "register_operand" "")
3222 (mult:SI (reg:SI R4_REG)
3224 (clobber (reg:SI MACL_REG))
3225 (clobber (reg:SI T_REG))
3226 (clobber (reg:SI PR_REG))
3227 (clobber (reg:SI R3_REG))
3228 (clobber (reg:SI R2_REG))
3229 (clobber (reg:SI R1_REG))
3230 (use (match_operand:SI 3 "register_operand" ""))])]
3234 (define_insn "mul_r"
3235 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3236 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3237 (match_operand:SI 2 "arith_reg_operand" "z")))]
3240 [(set_attr "type" "dmpy")])
3242 (define_insn "mul_l"
3243 [(set (reg:SI MACL_REG)
3244 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3245 (match_operand:SI 1 "arith_reg_operand" "r")))]
3248 [(set_attr "type" "dmpy")])
3250 (define_expand "mulsi3"
3251 [(set (reg:SI MACL_REG)
3252 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
3253 (match_operand:SI 2 "arith_reg_operand" "")))
3254 (set (match_operand:SI 0 "arith_reg_operand" "")
3260 /* The address must be set outside the libcall,
3261 since it goes into a pseudo. */
3262 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3263 rtx addr = force_reg (SImode, sym);
3264 rtx insns = gen_mulsi3_call (operands[0], operands[1],
3270 rtx macl = gen_rtx_REG (SImode, MACL_REG);
3272 emit_insn (gen_mul_l (operands[1], operands[2]));
3273 /* consec_sets_giv can only recognize the first insn that sets a
3274 giv as the giv insn. So we must tag this also with a REG_EQUAL
3276 emit_insn (gen_movsi_i ((operands[0]), macl));
3281 (define_insn "mulsidi3_i"
3282 [(set (reg:SI MACH_REG)
3286 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3287 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3289 (set (reg:SI MACL_REG)
3290 (mult:SI (match_dup 0)
3294 [(set_attr "type" "dmpy")])
3296 (define_expand "mulsidi3"
3297 [(set (match_operand:DI 0 "arith_reg_dest" "")
3298 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3299 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3300 "TARGET_SH2 || TARGET_SHMEDIA"
3304 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3309 (define_insn "mulsidi3_media"
3310 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3311 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3312 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3315 [(set_attr "type" "dmpy_media")
3316 (set_attr "highpart" "ignore")])
3318 (define_insn_and_split "mulsidi3_compact"
3319 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3321 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3322 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3323 (clobber (reg:SI MACH_REG))
3324 (clobber (reg:SI MACL_REG))]
3330 rtx low_dst = gen_lowpart (SImode, operands[0]);
3331 rtx high_dst = gen_highpart (SImode, operands[0]);
3333 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3335 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3336 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3337 /* We need something to tag the possible REG_EQUAL notes on to. */
3338 emit_move_insn (operands[0], operands[0]);
3342 (define_insn "umulsidi3_i"
3343 [(set (reg:SI MACH_REG)
3347 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3348 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3350 (set (reg:SI MACL_REG)
3351 (mult:SI (match_dup 0)
3355 [(set_attr "type" "dmpy")])
3357 (define_expand "umulsidi3"
3358 [(set (match_operand:DI 0 "arith_reg_dest" "")
3359 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3360 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3361 "TARGET_SH2 || TARGET_SHMEDIA"
3365 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3370 (define_insn "umulsidi3_media"
3371 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3373 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3376 [(set_attr "type" "dmpy_media")
3377 (set_attr "highpart" "ignore")])
3379 (define_insn_and_split "umulsidi3_compact"
3380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3382 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3383 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3384 (clobber (reg:SI MACH_REG))
3385 (clobber (reg:SI MACL_REG))]
3391 rtx low_dst = gen_lowpart (SImode, operands[0]);
3392 rtx high_dst = gen_highpart (SImode, operands[0]);
3394 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3396 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3397 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3398 /* We need something to tag the possible REG_EQUAL notes on to. */
3399 emit_move_insn (operands[0], operands[0]);
3403 (define_insn "smulsi3_highpart_i"
3404 [(set (reg:SI MACH_REG)
3408 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3409 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3411 (clobber (reg:SI MACL_REG))]
3414 [(set_attr "type" "dmpy")])
3416 (define_expand "smulsi3_highpart"
3418 [(set (reg:SI MACH_REG)
3422 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3423 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3425 (clobber (reg:SI MACL_REG))])
3426 (set (match_operand:SI 0 "arith_reg_operand" "")
3432 mach = gen_rtx_REG (SImode, MACH_REG);
3434 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3435 insn = get_insns ();
3437 /* expand_binop can't find a suitable code in mul_highpart_optab to
3438 make a REG_EQUAL note from, so make one here.
3439 See also {,u}mulhisi.
3440 ??? Alternatively, we could put this at the calling site of expand_binop,
3441 i.e. expand_mult_highpart. */
3442 /* Use emit_libcall_block for loop invariant code motion and to make
3443 a REG_EQUAL note. */
3444 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3449 (define_insn "umulsi3_highpart_i"
3450 [(set (reg:SI MACH_REG)
3454 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3455 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3457 (clobber (reg:SI MACL_REG))]
3460 [(set_attr "type" "dmpy")])
3462 (define_expand "umulsi3_highpart"
3464 [(set (reg:SI MACH_REG)
3468 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3469 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3471 (clobber (reg:SI MACL_REG))])
3472 (set (match_operand:SI 0 "arith_reg_operand" "")
3478 mach = gen_rtx_REG (SImode, MACH_REG);
3480 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3481 insn = get_insns ();
3483 /* Use emit_libcall_block for loop invariant code motion and to make
3484 a REG_EQUAL note. */
3485 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3490 (define_insn_and_split "muldi3"
3491 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3492 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3493 (match_operand:DI 2 "arith_reg_operand" "r")))
3494 (clobber (match_scratch:DI 3 "=&r"))
3495 (clobber (match_scratch:DI 4 "=r"))]
3501 rtx op3_v2si, op2_v2si;
3503 op3_v2si = operands[3];
3504 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3506 op3_v2si = XEXP (op3_v2si, 0);
3507 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3509 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3510 op2_v2si = operands[2];
3511 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3513 op2_v2si = XEXP (op2_v2si, 0);
3514 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3516 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3517 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3518 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3519 emit_insn (gen_umulsidi3_media (operands[4],
3520 sh_gen_truncate (SImode, operands[1], 0),
3521 sh_gen_truncate (SImode, operands[2], 0)));
3522 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3523 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3524 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3525 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3530 ;; -------------------------------------------------------------------------
3531 ;; Logical operations
3532 ;; -------------------------------------------------------------------------
3534 (define_expand "andsi3"
3535 [(set (match_operand:SI 0 "arith_reg_operand" "")
3536 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3537 (match_operand:SI 2 "logical_and_operand" "")))]
3540 /* If it is possible to turn the and insn into a zero extension
3541 already, redundant zero extensions will be folded, which results
3543 Ideally the splitter of *andsi_compact would be enough, if redundant
3544 zero extensions were detected after the combine pass, which does not
3545 happen at the moment. */
3548 if (satisfies_constraint_Jmb (operands[2]))
3550 emit_insn (gen_zero_extendqisi2 (operands[0],
3551 gen_lowpart (QImode, operands[1])));
3554 else if (satisfies_constraint_Jmw (operands[2]))
3556 emit_insn (gen_zero_extendhisi2 (operands[0],
3557 gen_lowpart (HImode, operands[1])));
3563 (define_insn_and_split "*andsi_compact"
3564 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3565 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3566 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3574 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3576 if (satisfies_constraint_Jmb (operands[2]))
3577 operands[1] = gen_lowpart (QImode, operands[1]);
3578 else if (satisfies_constraint_Jmw (operands[2]))
3579 operands[1] = gen_lowpart (HImode, operands[1]);
3583 [(set_attr "type" "arith")])
3585 (define_insn "*andsi3_media"
3586 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3587 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3588 (match_operand:SI 2 "logical_operand" "r,I10")))]
3593 [(set_attr "type" "arith_media")])
3595 (define_insn "*andsi3_bclr"
3596 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3597 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3598 (match_operand:SI 2 "const_int_operand" "Psz")))]
3599 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3601 [(set_attr "type" "arith")])
3603 (define_insn_and_split "anddi3"
3604 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3605 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3606 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3613 && ! logical_operand (operands[2], DImode)"
3616 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3617 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3619 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3622 [(set_attr "type" "arith_media")])
3624 (define_insn "andcsi3"
3625 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3626 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3627 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3630 [(set_attr "type" "arith_media")])
3632 (define_insn "andcdi3"
3633 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3634 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3635 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3638 [(set_attr "type" "arith_media")])
3640 (define_expand "iorsi3"
3641 [(set (match_operand:SI 0 "arith_reg_operand" "")
3642 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3643 (match_operand:SI 2 "logical_operand" "")))]
3647 (define_insn "*iorsi3_compact"
3648 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3649 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3650 (match_operand:SI 2 "logical_operand" "r,K08")))]
3652 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3654 [(set_attr "type" "arith")])
3656 (define_insn "*iorsi3_media"
3657 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3658 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3659 (match_operand:SI 2 "logical_operand" "r,I10")))]
3664 [(set_attr "type" "arith_media")])
3666 (define_insn "*iorsi3_bset"
3667 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3668 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3669 (match_operand:SI 2 "const_int_operand" "Pso")))]
3670 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3672 [(set_attr "type" "arith")])
3674 (define_insn "iordi3"
3675 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3676 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3677 (match_operand:DI 2 "logical_operand" "r,I10")))]
3682 [(set_attr "type" "arith_media")])
3684 (define_insn_and_split "*logical_sidi3"
3685 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3686 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3687 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3688 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3691 "&& reload_completed"
3692 [(set (match_dup 0) (match_dup 3))]
3695 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3696 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3697 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3700 (define_insn_and_split "*logical_sidisi3"
3701 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3702 (truncate:SI (sign_extend:DI
3703 (match_operator:SI 3 "logical_operator"
3704 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3705 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3709 [(set (match_dup 0) (match_dup 3))])
3711 (define_insn_and_split "*logical_sidi3_2"
3712 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3713 (sign_extend:DI (truncate:SI (sign_extend:DI
3714 (match_operator:SI 3 "logical_operator"
3715 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3716 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3720 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3722 (define_expand "xorsi3"
3723 [(set (match_operand:SI 0 "arith_reg_operand" "")
3724 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3725 (match_operand:SI 2 "xor_operand" "")))]
3729 (define_insn "*xorsi3_compact"
3730 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3731 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3732 (match_operand:SI 2 "logical_operand" "K08,r")))]
3735 [(set_attr "type" "arith")])
3737 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
3738 ;; of results where one of the inputs is a T bit store. Notice that this
3739 ;; pattern must not match during reload. If reload picks this pattern it
3740 ;; will be impossible to split it afterwards.
3741 (define_insn_and_split "*logical_op_t"
3742 [(set (match_operand:SI 0 "arith_reg_dest")
3743 (match_operator:SI 3 "logical_operator"
3744 [(match_operand:SI 1 "arith_reg_operand")
3745 (match_operand:SI 2 "t_reg_operand")]))]
3746 "TARGET_SH1 && can_create_pseudo_p ()"
3749 [(set (match_dup 4) (reg:SI T_REG))
3750 (set (match_dup 0) (match_dup 3))]
3752 operands[4] = gen_reg_rtx (SImode);
3753 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3754 operands[1], operands[4]);
3757 (define_insn "*xorsi3_media"
3758 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3759 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3760 (match_operand:SI 2 "xor_operand" "r,I06")))]
3765 [(set_attr "type" "arith_media")])
3767 (define_insn "xordi3"
3768 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3769 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3770 (match_operand:DI 2 "xor_operand" "r,I06")))]
3775 [(set_attr "type" "arith_media")])
3777 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3778 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3780 [(set (match_operand:DI 0 "arith_reg_dest" "")
3781 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3782 [(match_operand 1 "any_register_operand" "")
3783 (match_operand 2 "any_register_operand" "")])))]
3785 [(set (match_dup 5) (match_dup 4))
3786 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3788 enum machine_mode inmode = GET_MODE (operands[1]);
3791 if (GET_CODE (operands[0]) == SUBREG)
3793 offset = SUBREG_BYTE (operands[0]);
3794 operands[0] = SUBREG_REG (operands[0]);
3796 gcc_assert (REG_P (operands[0]));
3797 if (! TARGET_LITTLE_ENDIAN)
3798 offset += 8 - GET_MODE_SIZE (inmode);
3799 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3802 ;; -------------------------------------------------------------------------
3803 ;; Shifts and rotates
3804 ;; -------------------------------------------------------------------------
3806 (define_expand "rotldi3"
3807 [(set (match_operand:DI 0 "arith_reg_dest" "")
3808 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
3809 (match_operand:HI 2 "mextr_bit_offset" "")))]
3812 if (! mextr_bit_offset (operands[2], HImode))
3816 (define_insn "rotldi3_mextr"
3817 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3818 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3819 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3822 static char templ[16];
3823 sprintf (templ, "mextr%d %%1,%%1,%%0",
3824 8 - (int) (INTVAL (operands[2]) >> 3));
3827 [(set_attr "type" "arith_media")])
3829 (define_expand "rotrdi3"
3830 [(set (match_operand:DI 0 "arith_reg_dest" "")
3831 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
3832 (match_operand:HI 2 "mextr_bit_offset" "")))]
3835 if (! mextr_bit_offset (operands[2], HImode))
3839 (define_insn "rotrdi3_mextr"
3840 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3841 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3842 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3845 static char templ[16];
3846 sprintf (templ, "mextr%d %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
3849 [(set_attr "type" "arith_media")])
3852 [(set (match_operand:DI 0 "arith_reg_dest" "")
3853 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3854 "ua_address_operand" "")))
3855 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3857 (clobber (match_operand:DI 3 "register_operand" ""))]
3859 [(match_dup 4) (match_dup 5)]
3861 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3862 (operands[3], operands[1]));
3863 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3864 GEN_INT (56), GEN_INT (8));
3867 (define_expand "rotrsi3"
3868 [(set (match_operand:SI 0 "arith_reg_dest")
3869 (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
3870 (match_operand:SI 2 "const_int_operand")))]
3873 HOST_WIDE_INT ival = INTVAL (operands[2]);
3876 emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
3883 (define_insn "rotrsi3_1"
3884 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3885 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
3888 (and:SI (match_dup 1) (const_int 1)))]
3891 [(set_attr "type" "arith")])
3893 ;; A slimplified version of rotr for combine.
3894 (define_insn "*rotrsi3_1"
3895 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3896 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
3898 (clobber (reg:SI T_REG))]
3901 [(set_attr "type" "arith")])
3903 (define_insn "rotlsi3_1"
3904 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3905 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3908 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3911 [(set_attr "type" "arith")])
3913 ;; A simplified version of rotl for combine.
3914 (define_insn "*rotlsi3_1"
3915 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3916 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3918 (clobber (reg:SI T_REG))]
3921 [(set_attr "type" "arith")])
3923 (define_insn "rotlsi3_31"
3924 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3925 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3927 (clobber (reg:SI T_REG))]
3930 [(set_attr "type" "arith")])
3932 (define_insn "rotlsi3_16"
3933 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3934 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3938 [(set_attr "type" "arith")])
3940 (define_expand "rotlsi3"
3941 [(set (match_operand:SI 0 "arith_reg_dest")
3942 (rotate:SI (match_operand:SI 1 "arith_reg_operand")
3943 (match_operand:SI 2 "const_int_operand")))]
3946 static const char rot_tab[] = {
3947 000, 000, 000, 000, 000, 000, 010, 001,
3948 001, 001, 011, 013, 003, 003, 003, 003,
3949 003, 003, 003, 003, 003, 013, 012, 002,
3950 002, 002, 010, 000, 000, 000, 000, 000,
3953 int count = INTVAL (operands[2]);
3954 int choice = rot_tab[count];
3955 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3961 emit_move_insn (operands[0], operands[1]);
3962 count -= (count & 16) * 2;
3965 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3972 parts[0] = gen_reg_rtx (SImode);
3973 parts[1] = gen_reg_rtx (SImode);
3974 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3975 emit_move_insn (parts[choice-1], operands[1]);
3976 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3977 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3978 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3979 count = (count & ~16) - 8;
3983 for (; count > 0; count--)
3984 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3985 for (; count < 0; count++)
3986 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3991 (define_insn "*rotlhi3_8"
3992 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3993 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3997 [(set_attr "type" "arith")])
3999 (define_expand "rotlhi3"
4000 [(set (match_operand:HI 0 "arith_reg_operand")
4001 (rotate:HI (match_operand:HI 1 "arith_reg_operand")
4002 (match_operand:HI 2 "const_int_operand")))]
4005 if (INTVAL (operands[2]) != 8)
4009 ;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
4010 ;; They can also be used to implement things like
4012 ;; int x0 = (y >> 1) | (t << 31); // rotcr
4013 ;; int x1 = (y << 1) | t; // rotcl
4014 (define_insn "rotcr"
4015 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4016 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4018 (ashift:SI (match_operand:SI 2 "t_reg_operand")
4021 (and:SI (match_dup 1) (const_int 1)))]
4024 [(set_attr "type" "arith")])
4026 (define_insn "rotcl"
4027 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4028 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4030 (match_operand:SI 2 "t_reg_operand")))
4032 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4035 [(set_attr "type" "arith")])
4037 ;; Simplified rotcr version for combine, which allows arbitrary shift
4038 ;; amounts for the reg. If the shift amount is '1' rotcr can be used
4039 ;; directly. Otherwise we have to insert a shift in between.
4040 (define_insn_and_split "*rotcr"
4041 [(set (match_operand:SI 0 "arith_reg_dest")
4042 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4043 (match_operand:SI 2 "const_int_operand"))
4044 (ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4046 (clobber (reg:SI T_REG))]
4049 "&& can_create_pseudo_p ()"
4052 if (INTVAL (operands[2]) > 1)
4054 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4055 rtx prev_set_t_insn = NULL_RTX;
4056 rtx tmp_t_reg = NULL_RTX;
4058 /* If we're going to emit a shift sequence that clobbers the T_REG,
4059 try to find the previous insn that sets the T_REG and emit the
4060 shift insn before that insn, to remove the T_REG dependency.
4061 If the insn that sets the T_REG cannot be found, store the T_REG
4062 in a temporary reg and restore it after the shift. */
4063 if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4064 && ! sh_dynamicalize_shift_p (shift_count))
4066 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4068 /* Skip the nott insn, which was probably inserted by the splitter
4069 of *rotcr_neg_t. Don't use one of the recog functions
4070 here during insn splitting, since that causes problems in later
4072 if (prev_set_t_insn != NULL_RTX)
4074 rtx pat = PATTERN (prev_set_t_insn);
4075 if (GET_CODE (pat) == SET
4076 && t_reg_operand (XEXP (pat, 0), SImode)
4077 && negt_reg_operand (XEXP (pat, 1), SImode))
4078 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4081 if (! (prev_set_t_insn != NULL_RTX
4082 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4083 && ! reg_referenced_p (get_t_reg_rtx (),
4084 PATTERN (prev_set_t_insn))))
4086 prev_set_t_insn = NULL_RTX;
4087 tmp_t_reg = gen_reg_rtx (SImode);
4088 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4092 rtx shift_result = gen_reg_rtx (SImode);
4093 rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4094 operands[1] = shift_result;
4096 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4097 if (prev_set_t_insn != NULL_RTX)
4098 emit_insn_before (shift_insn, prev_set_t_insn);
4100 emit_insn (shift_insn);
4102 /* Restore T_REG if it has been saved before. */
4103 if (tmp_t_reg != NULL_RTX)
4104 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4107 /* For the rotcr insn to work, operands[3] must be in T_REG.
4108 If it is not we can get it there by shifting it right one bit.
4109 In this case T_REG is not an input for this insn, thus we don't have to
4110 pay attention as of where to insert the shlr insn. */
4111 if (! t_reg_operand (operands[3], SImode))
4113 /* We don't care about the shifted result here, only the T_REG. */
4114 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4115 operands[3] = get_t_reg_rtx ();
4118 emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4122 ;; If combine tries the same as above but with swapped operands, split
4123 ;; it so that it will try the pattern above.
4125 [(set (match_operand:SI 0 "arith_reg_dest")
4126 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4128 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4129 (match_operand:SI 3 "const_int_operand"))))]
4130 "TARGET_SH1 && can_create_pseudo_p ()"
4131 [(parallel [(set (match_dup 0)
4132 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4133 (ashift:SI (match_dup 1) (const_int 31))))
4134 (clobber (reg:SI T_REG))])])
4136 ;; Basically the same as the rotcr pattern above, but for rotcl.
4137 ;; FIXME: Fold copy pasted split code for rotcr and rotcl.
4138 (define_insn_and_split "*rotcl"
4139 [(set (match_operand:SI 0 "arith_reg_dest")
4140 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4141 (match_operand:SI 2 "const_int_operand"))
4142 (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4144 (clobber (reg:SI T_REG))]
4147 "&& can_create_pseudo_p ()"
4150 gcc_assert (INTVAL (operands[2]) > 0);
4152 if (INTVAL (operands[2]) > 1)
4154 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4155 rtx prev_set_t_insn = NULL_RTX;
4156 rtx tmp_t_reg = NULL_RTX;
4158 /* If we're going to emit a shift sequence that clobbers the T_REG,
4159 try to find the previous insn that sets the T_REG and emit the
4160 shift insn before that insn, to remove the T_REG dependency.
4161 If the insn that sets the T_REG cannot be found, store the T_REG
4162 in a temporary reg and restore it after the shift. */
4163 if (sh_ashlsi_clobbers_t_reg_p (shift_count)
4164 && ! sh_dynamicalize_shift_p (shift_count))
4166 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4168 /* Skip the nott insn, which was probably inserted by the splitter
4169 of *rotcl_neg_t. Don't use one of the recog functions
4170 here during insn splitting, since that causes problems in later
4172 if (prev_set_t_insn != NULL_RTX)
4174 rtx pat = PATTERN (prev_set_t_insn);
4175 if (GET_CODE (pat) == SET
4176 && t_reg_operand (XEXP (pat, 0), SImode)
4177 && negt_reg_operand (XEXP (pat, 1), SImode))
4178 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4181 if (! (prev_set_t_insn != NULL_RTX
4182 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4183 && ! reg_referenced_p (get_t_reg_rtx (),
4184 PATTERN (prev_set_t_insn))))
4186 prev_set_t_insn = NULL_RTX;
4187 tmp_t_reg = gen_reg_rtx (SImode);
4188 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4192 rtx shift_result = gen_reg_rtx (SImode);
4193 rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
4194 operands[1] = shift_result;
4196 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4197 if (prev_set_t_insn != NULL_RTX)
4198 emit_insn_before (shift_insn, prev_set_t_insn);
4200 emit_insn (shift_insn);
4202 /* Restore T_REG if it has been saved before. */
4203 if (tmp_t_reg != NULL_RTX)
4204 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4207 /* For the rotcl insn to work, operands[3] must be in T_REG.
4208 If it is not we can get it there by shifting it right one bit.
4209 In this case T_REG is not an input for this insn, thus we don't have to
4210 pay attention as of where to insert the shlr insn. */
4211 if (! t_reg_operand (operands[3], SImode))
4213 /* We don't care about the shifted result here, only the T_REG. */
4214 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4215 operands[3] = get_t_reg_rtx ();
4218 emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
4222 ;; rotcl combine pattern variations
4223 (define_insn_and_split "*rotcl"
4224 [(set (match_operand:SI 0 "arith_reg_dest")
4225 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4226 (match_operand:SI 2 "const_int_operand"))
4227 (match_operand:SI 3 "t_reg_operand")))
4228 (clobber (reg:SI T_REG))]
4231 "&& can_create_pseudo_p ()"
4232 [(parallel [(set (match_dup 0)
4233 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4234 (and:SI (match_dup 3) (const_int 1))))
4235 (clobber (reg:SI T_REG))])])
4237 (define_insn_and_split "*rotcl"
4238 [(set (match_operand:SI 0 "arith_reg_dest")
4239 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4241 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4242 (match_operand:SI 3 "const_int_operand"))))
4243 (clobber (reg:SI T_REG))]
4246 "&& can_create_pseudo_p ()"
4247 [(parallel [(set (match_dup 0)
4248 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4249 (and:SI (match_dup 1) (const_int 1))))
4250 (clobber (reg:SI T_REG))])])
4252 (define_insn_and_split "*rotcl"
4253 [(set (match_operand:SI 0 "arith_reg_dest")
4254 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4255 (match_operand:SI 2 "const_int_operand"))
4256 (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4258 (clobber (reg:SI T_REG))]
4261 "&& can_create_pseudo_p ()"
4262 [(parallel [(set (match_dup 0)
4263 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4264 (and:SI (reg:SI T_REG) (const_int 1))))
4265 (clobber (reg:SI T_REG))])]
4267 /* We don't care about the result of the left shift, only the T_REG. */
4268 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4271 (define_insn_and_split "*rotcl"
4272 [(set (match_operand:SI 0 "arith_reg_dest")
4273 (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4275 (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4276 (match_operand:SI 2 "const_int_operand"))))
4277 (clobber (reg:SI T_REG))]
4280 "&& can_create_pseudo_p ()"
4281 [(parallel [(set (match_dup 0)
4282 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4283 (and:SI (reg:SI T_REG) (const_int 1))))
4284 (clobber (reg:SI T_REG))])]
4286 /* We don't care about the result of the left shift, only the T_REG. */
4287 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4290 ;; rotcr combine bridge pattern which will make combine try out more
4291 ;; complex patterns.
4292 (define_insn_and_split "*rotcr"
4293 [(set (match_operand:SI 0 "arith_reg_dest")
4294 (ashift:SI (match_operand:SI 1 "t_reg_operand") (const_int 31)))]
4298 [(set (match_dup 0) (match_dup 1))
4299 (parallel [(set (match_dup 0)
4300 (ior:SI (lshiftrt:SI (match_dup 0) (const_int 1))
4301 (ashift:SI (match_dup 1) (const_int 31))))
4303 (and:SI (match_dup 0) (const_int 1)))])])
4305 (define_insn_and_split "*rotcr"
4306 [(set (match_operand:SI 0 "arith_reg_dest")
4307 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4308 (const_int -2147483648)) ;; 0xffffffff80000000
4309 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4311 (clobber (reg:SI T_REG))]
4314 "&& can_create_pseudo_p ()"
4317 rtx tmp = gen_reg_rtx (SImode);
4318 emit_insn (gen_shll (tmp, operands[1]));
4319 emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4323 ;; rotcr combine patterns for rotating in the negated T_REG value.
4324 (define_insn_and_split "*rotcr_neg_t"
4325 [(set (match_operand:SI 0 "arith_reg_dest")
4326 (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4327 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4328 (match_operand:SI 3 "const_int_operand"))))
4329 (clobber (reg:SI T_REG))]
4332 "&& can_create_pseudo_p ()"
4333 [(parallel [(set (match_dup 0)
4334 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4335 (ashift:SI (reg:SI T_REG) (const_int 31))))
4336 (clobber (reg:SI T_REG))])]
4338 emit_insn (gen_nott (get_t_reg_rtx ()));
4341 (define_insn_and_split "*rotcr_neg_t"
4342 [(set (match_operand:SI 0 "arith_reg_dest")
4343 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4344 (match_operand:SI 2 "const_int_operand"))
4345 (match_operand:SI 3 "negt_reg_shl31_operand")))
4346 (clobber (reg:SI T_REG))]
4349 "&& can_create_pseudo_p ()"
4350 [(parallel [(set (match_dup 0)
4351 (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4352 (ashift:SI (reg:SI T_REG) (const_int 31))))
4353 (clobber (reg:SI T_REG))])]
4355 emit_insn (gen_nott (get_t_reg_rtx ()));
4358 ;; rotcl combine patterns for rotating in the negated T_REG value.
4359 ;; For some strange reason these have to be specified as splits which combine
4360 ;; will pick up. If they are specified as insn_and_split like the
4361 ;; *rotcr_neg_t patterns above, combine would recognize them successfully
4362 ;; but not emit them on non-SH2A targets.
4364 [(set (match_operand:SI 0 "arith_reg_dest")
4365 (ior:SI (match_operand:SI 1 "negt_reg_operand")
4366 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4367 (match_operand:SI 3 "const_int_operand"))))]
4369 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4370 (parallel [(set (match_dup 0)
4371 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4372 (and:SI (reg:SI T_REG) (const_int 1))))
4373 (clobber (reg:SI T_REG))])])
4376 [(set (match_operand:SI 0 "arith_reg_dest")
4377 (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4378 (match_operand:SI 3 "const_int_operand"))
4379 (match_operand:SI 1 "negt_reg_operand")))]
4381 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4382 (parallel [(set (match_dup 0)
4383 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4384 (and:SI (reg:SI T_REG) (const_int 1))))
4385 (clobber (reg:SI T_REG))])])
4387 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4388 ;; SImode shift left
4390 (define_expand "ashlsi3"
4391 [(set (match_operand:SI 0 "arith_reg_operand" "")
4392 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4393 (match_operand:SI 2 "shift_count_operand" "")))]
4398 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4402 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4403 operands[2] = force_reg (SImode, operands[2]);
4405 /* If the ashlsi3_* insn is going to clobber the T_REG it must be
4407 if (CONST_INT_P (operands[2])
4408 && sh_ashlsi_clobbers_t_reg_p (operands[2])
4409 && ! sh_dynamicalize_shift_p (operands[2]))
4411 emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4416 /* Expand a library call for the dynamic shift. */
4417 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4419 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4420 rtx funcaddr = gen_reg_rtx (Pmode);
4421 function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4422 emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4428 (define_insn "ashlsi3_k"
4429 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4430 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4431 (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4436 [(set_attr "type" "arith")])
4438 (define_insn_and_split "ashlsi3_d"
4439 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4440 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4441 (match_operand:SI 2 "shift_count_operand" "r")))]
4444 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4445 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4448 if (satisfies_constraint_P27 (operands[2]))
4450 emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
4453 else if (! satisfies_constraint_P27 (operands[2]))
4455 /* This must happen before reload, otherwise the constant will be moved
4456 into a register due to the "r" constraint, after which this split
4457 cannot be done anymore.
4458 Unfortunately the move insn will not always be eliminated.
4459 Also, here we must not create a shift sequence that clobbers the
4461 emit_move_insn (operands[0], operands[1]);
4462 gen_shifty_op (ASHIFT, operands);
4468 [(set_attr "type" "dyn_shift")])
4470 ;; If dynamic shifts are not available use a library function.
4471 ;; By specifying the pattern we reduce the number of call clobbered regs.
4472 ;; In order to make combine understand the truncation of the shift amount
4473 ;; operand we have to allow it to use pseudo regs for the shift operands.
4474 (define_insn "ashlsi3_d_call"
4475 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4476 (ashift:SI (reg:SI R4_REG)
4477 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4479 (use (match_operand:SI 2 "arith_reg_operand" "r"))
4480 (clobber (reg:SI T_REG))
4481 (clobber (reg:SI PR_REG))]
4482 "TARGET_SH1 && !TARGET_DYNSHIFT"
4484 [(set_attr "type" "sfunc")
4485 (set_attr "needs_delay_slot" "yes")])
4487 (define_insn_and_split "ashlsi3_n"
4488 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4489 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4490 (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
4491 "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4493 "&& (reload_completed
4494 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4497 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4499 /* If this pattern was picked and dynamic shifts are supported, switch
4500 to dynamic shift pattern before reload. */
4501 operands[2] = force_reg (SImode, operands[2]);
4502 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4505 gen_shifty_op (ASHIFT, operands);
4510 (define_insn_and_split "ashlsi3_n_clobbers_t"
4511 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4512 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4513 (match_operand:SI 2 "not_p27_shift_count_operand" "")))
4514 (clobber (reg:SI T_REG))]
4515 "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
4517 "&& (reload_completed || INTVAL (operands[2]) == 31
4518 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4521 if (INTVAL (operands[2]) == 31)
4523 /* If the shift amount is 31 we split into a different sequence before
4524 reload so that it gets a chance to allocate R0 for the sequence.
4525 If it fails to do so (due to pressure on R0), it will take one insn
4526 more for the and. */
4527 emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
4528 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4530 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4532 /* If this pattern was picked and dynamic shifts are supported, switch
4533 to dynamic shift pattern before reload. */
4534 operands[2] = force_reg (SImode, operands[2]);
4535 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4538 gen_shifty_op (ASHIFT, operands);
4544 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4545 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4547 (lt:SI (match_dup 1) (const_int 0)))]
4550 [(set_attr "type" "arith")])
4552 (define_insn "*ashlsi_c_void"
4553 [(set (reg:SI T_REG)
4554 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
4555 (clobber (match_scratch:SI 1 "=0"))]
4556 "TARGET_SH1 && cse_not_expected"
4558 [(set_attr "type" "arith")])
4561 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
4563 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
4565 && peep2_reg_dead_p (2, operands[0])
4566 && peep2_reg_dead_p (2, operands[1])"
4569 emit_insn (gen_shll (operands[1], operands[1]));
4573 (define_insn "ashlsi3_media"
4574 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4575 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4576 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4581 [(set_attr "type" "arith_media")
4582 (set_attr "highpart" "ignore")])
4584 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4585 ;; HImode shift left
4587 (define_expand "ashlhi3"
4588 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
4589 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
4590 (match_operand:SI 2 "nonmemory_operand" "")))
4591 (clobber (reg:SI T_REG))])]
4594 if (!CONST_INT_P (operands[2]))
4596 /* It may be possible to call gen_ashlhi3 directly with more generic
4597 operands. Make sure operands[1] is a HImode register here. */
4598 if (!arith_reg_operand (operands[1], HImode))
4599 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4602 (define_insn "ashlhi3_k"
4603 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4604 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
4605 (match_operand:HI 2 "const_int_operand" "M,P27")))]
4606 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
4610 [(set_attr "type" "arith")])
4612 (define_insn_and_split "*ashlhi3_n"
4613 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4614 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
4615 (match_operand:HI 2 "const_int_operand" "n")))
4616 (clobber (reg:SI T_REG))]
4619 "&& reload_completed"
4620 [(use (reg:SI R0_REG))]
4622 gen_shifty_hi_op (ASHIFT, operands);
4626 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4627 ;; DImode shift left
4629 (define_expand "ashldi3"
4630 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4631 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4632 (match_operand:DI 2 "immediate_operand" "")))
4633 (clobber (reg:SI T_REG))])]
4638 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4641 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
4643 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4646 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
4648 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4655 ;; Expander for DImode shift left with SImode operations.
4656 (define_expand "ashldi3_std"
4657 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4658 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4659 (match_operand:DI 2 "const_int_operand" "n")))]
4660 "TARGET_SH1 && INTVAL (operands[2]) < 32"
4662 rtx low_src = gen_lowpart (SImode, operands[1]);
4663 rtx high_src = gen_highpart (SImode, operands[1]);
4664 rtx dst = gen_reg_rtx (DImode);
4665 rtx low_dst = gen_lowpart (SImode, dst);
4666 rtx high_dst = gen_highpart (SImode, dst);
4667 rtx tmp0 = gen_reg_rtx (SImode);
4668 rtx tmp1 = gen_reg_rtx (SImode);
4670 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4671 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
4672 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
4673 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4674 emit_move_insn (operands[0], dst);
4678 (define_insn_and_split "ashldi3_k"
4679 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4680 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
4682 (clobber (reg:SI T_REG))]
4685 "&& reload_completed"
4688 rtx high = gen_highpart (SImode, operands[0]);
4689 rtx low = gen_lowpart (SImode, operands[0]);
4690 emit_insn (gen_shll (low, low));
4691 emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
4695 (define_insn "ashldi3_media"
4696 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4697 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4698 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4703 [(set_attr "type" "arith_media")])
4705 (define_insn "*ashldisi3_media"
4706 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4707 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4708 (match_operand:DI 2 "const_int_operand" "n")))]
4709 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4710 "shlli.l %1, %2, %0"
4711 [(set_attr "type" "arith_media")
4712 (set_attr "highpart" "ignore")])
4714 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4715 ;; SImode arithmetic shift right
4717 ;; We can't do HImode right shifts correctly unless we start out with an
4718 ;; explicit zero / sign extension; doing that would result in worse overall
4719 ;; code, so just let the machine independent code widen the mode.
4720 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
4722 (define_expand "ashrsi3"
4723 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4724 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4725 (match_operand:SI 2 "nonmemory_operand" "")))
4726 (clobber (reg:SI T_REG))])]
4731 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4734 if (expand_ashiftrt (operands))
4741 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4742 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4745 (and:SI (match_dup 1) (const_int 1)))]
4748 [(set_attr "type" "arith")])
4750 (define_insn "ashrsi3_k"
4751 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4752 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4753 (match_operand:SI 2 "const_int_operand" "M")))
4754 (clobber (reg:SI T_REG))]
4755 "TARGET_SH1 && INTVAL (operands[2]) == 1"
4757 [(set_attr "type" "arith")])
4759 (define_insn_and_split "ashrsi2_16"
4760 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4761 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
4766 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
4767 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
4769 operands[2] = gen_lowpart (HImode, operands[0]);
4772 (define_insn_and_split "ashrsi2_31"
4773 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4774 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4776 (clobber (reg:SI T_REG))]
4782 emit_insn (gen_shll (operands[0], operands[1]));
4783 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
4787 (define_insn "ashrsi3_d"
4788 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4789 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4790 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4793 [(set_attr "type" "dyn_shift")])
4795 (define_insn "ashrsi3_n"
4796 [(set (reg:SI R4_REG)
4797 (ashiftrt:SI (reg:SI R4_REG)
4798 (match_operand:SI 0 "const_int_operand" "i")))
4799 (clobber (reg:SI T_REG))
4800 (clobber (reg:SI PR_REG))
4801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
4804 [(set_attr "type" "sfunc")
4805 (set_attr "needs_delay_slot" "yes")])
4807 (define_insn "ashrsi3_media"
4808 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4809 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4810 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4815 [(set_attr "type" "arith_media")
4816 (set_attr "highpart" "ignore")])
4818 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4819 ;; DImode arithmetic shift right
4821 (define_expand "ashrdi3"
4822 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4823 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4824 (match_operand:DI 2 "immediate_operand" "")))
4825 (clobber (reg:SI T_REG))])]
4830 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4833 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4837 (define_insn_and_split "ashrdi3_k"
4838 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4839 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4841 (clobber (reg:SI T_REG))]
4844 "&& reload_completed"
4847 rtx high = gen_highpart (SImode, operands[0]);
4848 rtx low = gen_lowpart (SImode, operands[0]);
4849 emit_insn (gen_shar (high, high));
4850 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
4854 (define_insn "ashrdi3_media"
4855 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4856 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4857 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4859 && (arith_reg_dest (operands[0], DImode)
4860 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4864 [(set_attr "type" "arith_media")])
4866 (define_insn "*ashrdisi3_media"
4867 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4868 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4869 (match_operand:DI 2 "const_int_operand" "n")))]
4870 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4871 "shari.l %1, %2, %0"
4872 [(set_attr "type" "arith_media")
4873 (set_attr "highpart" "ignore")])
4875 (define_insn "ashrdisi3_media_high"
4876 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4878 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4879 (match_operand:DI 2 "const_int_operand" "n"))))]
4880 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4882 [(set_attr "type" "arith_media")])
4884 (define_insn "ashrdisi3_media_opaque"
4885 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4886 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4887 (match_operand:DI 2 "const_int_operand" "n")]
4891 [(set_attr "type" "arith_media")])
4893 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4894 ;; SImode logical shift right
4896 (define_expand "lshrsi3"
4897 [(set (match_operand:SI 0 "arith_reg_dest" "")
4898 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4899 (match_operand:SI 2 "shift_count_operand" "")))]
4904 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
4908 /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
4909 here, otherwise the pattern will never match due to the shift amount reg
4912 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4914 rtx neg_count = force_reg (SImode,
4915 gen_int_mode (- INTVAL (operands[2]), SImode));
4916 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
4920 if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
4922 rtx neg_count = gen_reg_rtx (SImode);
4923 emit_insn (gen_negsi2 (neg_count, operands[2]));
4924 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
4928 /* If the lshrsi3_* insn is going to clobber the T_REG it must be
4930 if (CONST_INT_P (operands[2])
4931 && sh_lshrsi_clobbers_t_reg_p (operands[2])
4932 && ! sh_dynamicalize_shift_p (operands[2]))
4934 emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
4939 /* Expand a library call for the dynamic shift. */
4940 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4942 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4943 rtx funcaddr = gen_reg_rtx (Pmode);
4944 function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
4945 emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
4950 (define_insn "lshrsi3_k"
4951 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4952 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4953 (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
4956 [(set_attr "type" "arith")])
4958 (define_insn_and_split "lshrsi3_d"
4959 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4960 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4961 (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
4964 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4965 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
4968 if (satisfies_constraint_P27 (operands[2]))
4970 /* This will not be done for a shift amount of 1, because it would
4971 clobber the T_REG. */
4972 emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
4975 else if (! satisfies_constraint_P27 (operands[2]))
4977 /* This must happen before reload, otherwise the constant will be moved
4978 into a register due to the "r" constraint, after which this split
4979 cannot be done anymore.
4980 Unfortunately the move insn will not always be eliminated.
4981 Also, here we must not create a shift sequence that clobbers the
4983 emit_move_insn (operands[0], operands[1]);
4984 gen_shifty_op (LSHIFTRT, operands);
4990 [(set_attr "type" "dyn_shift")])
4992 ;; If dynamic shifts are not available use a library function.
4993 ;; By specifying the pattern we reduce the number of call clobbered regs.
4994 ;; In order to make combine understand the truncation of the shift amount
4995 ;; operand we have to allow it to use pseudo regs for the shift operands.
4996 (define_insn "lshrsi3_d_call"
4997 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4998 (lshiftrt:SI (reg:SI R4_REG)
4999 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5001 (use (match_operand:SI 2 "arith_reg_operand" "r"))
5002 (clobber (reg:SI T_REG))
5003 (clobber (reg:SI PR_REG))]
5004 "TARGET_SH1 && !TARGET_DYNSHIFT"
5006 [(set_attr "type" "sfunc")
5007 (set_attr "needs_delay_slot" "yes")])
5009 (define_insn_and_split "lshrsi3_n"
5010 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5011 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5012 (match_operand:SI 2 "not_p27_rshift_count_operand")))]
5013 "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5015 "&& (reload_completed
5016 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5019 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5021 /* If this pattern was picked and dynamic shifts are supported, switch
5022 to dynamic shift pattern before reload. */
5023 operands[2] = force_reg (SImode,
5024 gen_int_mode (- INTVAL (operands[2]), SImode));
5025 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5028 gen_shifty_op (LSHIFTRT, operands);
5033 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
5034 ;; the shlr pattern.
5035 (define_insn_and_split "lshrsi3_n_clobbers_t"
5036 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5037 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5038 (match_operand:SI 2 "not_p27_rshift_count_operand")))
5039 (clobber (reg:SI T_REG))]
5040 "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
5042 "&& (reload_completed || INTVAL (operands[2]) == 31
5043 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5046 if (INTVAL (operands[2]) == 31)
5048 emit_insn (gen_shll (operands[0], operands[1]));
5049 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
5051 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5053 /* If this pattern was picked and dynamic shifts are supported, switch
5054 to dynamic shift pattern before reload. */
5055 operands[2] = force_reg (SImode,
5056 gen_int_mode (- INTVAL (operands[2]), SImode));
5057 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5060 gen_shifty_op (LSHIFTRT, operands);
5066 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5067 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5070 (and:SI (match_dup 1) (const_int 1)))]
5073 [(set_attr "type" "arith")])
5075 (define_insn "lshrsi3_media"
5076 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5077 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5078 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5083 [(set_attr "type" "arith_media")
5084 (set_attr "highpart" "ignore")])
5086 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5087 ;; DImode logical shift right
5089 (define_expand "lshrdi3"
5090 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5091 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5092 (match_operand:DI 2 "immediate_operand" "")))
5093 (clobber (reg:SI T_REG))])]
5098 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
5101 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5105 (define_insn_and_split "lshrdi3_k"
5106 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5107 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5109 (clobber (reg:SI T_REG))]
5112 "&& reload_completed"
5115 rtx high = gen_highpart (SImode, operands[0]);
5116 rtx low = gen_lowpart (SImode, operands[0]);
5117 emit_insn (gen_shlr (high, high));
5118 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5122 (define_insn "lshrdi3_media"
5123 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5124 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5125 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5127 && (arith_reg_dest (operands[0], DImode)
5128 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
5132 [(set_attr "type" "arith_media")])
5134 (define_insn "*lshrdisi3_media"
5135 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5136 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5137 (match_operand:DI 2 "const_int_operand" "n")))]
5138 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5139 "shlri.l %1, %2, %0"
5140 [(set_attr "type" "arith_media")
5141 (set_attr "highpart" "ignore")])
5143 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5144 ;; Combined left/right shifts
5147 [(set (match_operand:SI 0 "register_operand" "")
5148 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5149 (match_operand:SI 2 "const_int_operand" ""))
5150 (match_operand:SI 3 "const_int_operand" "")))]
5151 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5152 [(use (reg:SI R0_REG))]
5154 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5160 [(set (match_operand:SI 0 "register_operand" "")
5161 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5162 (match_operand:SI 2 "const_int_operand" ""))
5163 (match_operand:SI 3 "const_int_operand" "")))
5164 (clobber (reg:SI T_REG))]
5165 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5166 [(use (reg:SI R0_REG))]
5168 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5174 [(set (match_operand:SI 0 "register_operand" "=r")
5175 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5176 (match_operand:SI 2 "const_int_operand" "n"))
5177 (match_operand:SI 3 "const_int_operand" "n")))
5178 (clobber (reg:SI T_REG))]
5179 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
5181 [(set (attr "length")
5182 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5184 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5186 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5188 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
5190 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
5192 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
5194 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
5195 (const_string "16")]
5196 (const_string "18")))
5197 (set_attr "type" "arith")])
5200 [(set (match_operand:SI 0 "register_operand" "=z")
5201 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5202 (match_operand:SI 2 "const_int_operand" "n"))
5203 (match_operand:SI 3 "const_int_operand" "n")))
5204 (clobber (reg:SI T_REG))]
5205 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
5207 [(set (attr "length")
5208 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5210 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5212 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5214 (const_string "10")))
5215 (set_attr "type" "arith")])
5217 ;; shift left / and combination with a scratch register: The combine pass
5218 ;; does not accept the individual instructions, even though they are
5219 ;; cheap. But it needs a precise description so that it is usable after
5221 (define_insn "and_shl_scratch"
5222 [(set (match_operand:SI 0 "register_operand" "=r,&r")
5226 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5227 (match_operand:SI 2 "const_int_operand" "N,n"))
5228 (match_operand:SI 3 "" "0,r"))
5229 (match_operand:SI 4 "const_int_operand" "n,n"))
5230 (match_operand:SI 5 "const_int_operand" "n,n")))
5231 (clobber (reg:SI T_REG))]
5234 [(set (attr "length")
5235 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5237 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5239 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5241 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5242 (const_string "10")]
5243 (const_string "12")))
5244 (set_attr "type" "arith")])
5247 [(set (match_operand:SI 0 "register_operand" "")
5251 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5252 (match_operand:SI 2 "const_int_operand" ""))
5253 (match_operand:SI 3 "register_operand" ""))
5254 (match_operand:SI 4 "const_int_operand" ""))
5255 (match_operand:SI 5 "const_int_operand" "")))
5256 (clobber (reg:SI T_REG))]
5258 [(use (reg:SI R0_REG))]
5260 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5262 if (INTVAL (operands[2]))
5264 gen_shifty_op (LSHIFTRT, operands);
5266 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5267 operands[2] = operands[4];
5268 gen_shifty_op (ASHIFT, operands);
5269 if (INTVAL (operands[5]))
5271 operands[2] = operands[5];
5272 gen_shifty_op (LSHIFTRT, operands);
5277 ;; signed left/right shift combination.
5279 [(set (match_operand:SI 0 "register_operand" "")
5281 (ashift:SI (match_operand:SI 1 "register_operand" "")
5282 (match_operand:SI 2 "const_int_operand" ""))
5283 (match_operand:SI 3 "const_int_operand" "")
5285 (clobber (reg:SI T_REG))]
5287 [(use (reg:SI R0_REG))]
5289 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5294 (define_insn "shl_sext_ext"
5295 [(set (match_operand:SI 0 "register_operand" "=r")
5297 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5298 (match_operand:SI 2 "const_int_operand" "n"))
5299 (match_operand:SI 3 "const_int_operand" "n")
5301 (clobber (reg:SI T_REG))]
5302 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5304 [(set (attr "length")
5305 (cond [(match_test "shl_sext_length (insn)")
5307 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5309 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5311 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5313 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5315 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5317 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5319 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5320 (const_string "16")]
5321 (const_string "18")))
5322 (set_attr "type" "arith")])
5324 (define_insn "shl_sext_sub"
5325 [(set (match_operand:SI 0 "register_operand" "=z")
5327 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5328 (match_operand:SI 2 "const_int_operand" "n"))
5329 (match_operand:SI 3 "const_int_operand" "n")
5331 (clobber (reg:SI T_REG))]
5332 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5334 [(set (attr "length")
5335 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5337 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5339 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5341 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5342 (const_string "12")]
5343 (const_string "14")))
5344 (set_attr "type" "arith")])
5346 ;; These patterns are found in expansions of DImode shifts by 16, and
5347 ;; allow the xtrct instruction to be generated from C source.
5349 (define_insn "xtrct_left"
5350 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5351 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5353 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5357 [(set_attr "type" "arith")])
5359 (define_insn "xtrct_right"
5360 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5361 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5363 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5367 [(set_attr "type" "arith")])
5369 ;; -------------------------------------------------------------------------
5371 ;; -------------------------------------------------------------------------
5374 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5375 (neg:SI (plus:SI (reg:SI T_REG)
5376 (match_operand:SI 1 "arith_reg_operand" "r"))))
5378 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5382 [(set_attr "type" "arith")])
5384 ;; A simplified version of the negc insn, where the exact value of the
5385 ;; T bit doesn't matter. This is easier for combine to pick up.
5386 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5387 ;; extra patterns for this case.
5388 (define_insn "*negc"
5389 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5390 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5391 (match_operand:SI 2 "t_reg_operand" "")))
5392 (clobber (reg:SI T_REG))]
5395 [(set_attr "type" "arith")])
5397 (define_insn "*negdi_media"
5398 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5399 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5402 [(set_attr "type" "arith_media")])
5404 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
5406 (define_expand "negdi2"
5407 [(parallel [(set (match_operand:DI 0 "arith_reg_dest")
5408 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5409 (clobber (reg:SI T_REG))])]
5412 (define_insn_and_split "*negdi2"
5413 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
5414 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))
5415 (clobber (reg:SI T_REG))]
5418 "&& reload_completed"
5421 emit_insn (gen_clrt ());
5422 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5423 gen_lowpart (SImode, operands[1])));
5424 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5425 gen_highpart (SImode, operands[1])));
5429 (define_insn "negsi2"
5430 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5431 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5434 [(set_attr "type" "arith")])
5436 (define_insn_and_split "one_cmplsi2"
5437 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5438 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5441 "&& can_create_pseudo_p ()"
5442 [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
5443 (set (match_dup 0) (reg:SI T_REG))]
5446 If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
5449 (set (reg0) (not:SI (reg0) (reg1)))
5450 (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
5451 (clobber (reg:SI T_REG))])
5453 ... match and combine the sequence manually in the split pass after the
5454 combine pass. Notice that combine does try the target pattern of this
5455 split, but if the pattern is added it interferes with other patterns, in
5456 particular with the div0s comparisons.
5457 This could also be done with a peephole but doing it here before register
5458 allocation can save one temporary.
5459 When we're here, the not:SI pattern obviously has been matched already
5460 and we only have to see whether the following insn is the left shift. */
5462 rtx i = next_nonnote_insn_bb (curr_insn);
5463 if (i == NULL_RTX || !NONJUMP_INSN_P (i))
5466 rtx p = PATTERN (i);
5467 if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
5470 rtx p0 = XVECEXP (p, 0, 0);
5471 rtx p1 = XVECEXP (p, 0, 1);
5473 if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
5474 GET_CODE (p0) == SET
5475 && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
5476 && REG_P (XEXP (XEXP (p0, 1), 0))
5477 && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
5478 && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
5479 && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
5481 /* (clobber (reg:SI T_REG)) */
5482 && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
5483 && REGNO (XEXP (p1, 0)) == T_REG)
5485 operands[0] = XEXP (p0, 0);
5486 set_insn_deleted (i);
5491 [(set_attr "type" "arith")])
5493 (define_expand "one_cmpldi2"
5494 [(set (match_operand:DI 0 "arith_reg_dest" "")
5495 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
5497 "TARGET_SHMEDIA" "")
5499 (define_expand "abs<mode>2"
5500 [(parallel [(set (match_operand:SIDI 0 "arith_reg_dest")
5501 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5502 (clobber (reg:SI T_REG))])]
5505 (define_insn_and_split "*abs<mode>2"
5506 [(set (match_operand:SIDI 0 "arith_reg_dest")
5507 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5508 (clobber (reg:SI T_REG))]
5511 "&& can_create_pseudo_p ()"
5514 if (<MODE>mode == SImode)
5515 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5518 rtx high_src = gen_highpart (SImode, operands[1]);
5519 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5522 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5527 (define_insn_and_split "*negabs<mode>2"
5528 [(set (match_operand:SIDI 0 "arith_reg_dest")
5529 (neg:SIDI (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand"))))
5530 (clobber (reg:SI T_REG))]
5533 "&& can_create_pseudo_p ()"
5536 if (<MODE>mode == SImode)
5537 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5540 rtx high_src = gen_highpart (SImode, operands[1]);
5541 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5544 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5549 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
5550 ;; This can be used as some kind of conditional execution, which is useful
5552 ;; Actually the instruction scheduling should decide whether to use a
5553 ;; zero-offset branch or not for any generic case involving a single
5554 ;; instruction on SH4 202.
5556 (define_insn_and_split "negsi_cond"
5557 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5559 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand" "M,N"))
5560 (match_operand:SI 1 "arith_reg_operand" "0,0")
5561 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
5562 "TARGET_SH1 && TARGET_ZDCBRANCH"
5564 static const char* alt[] =
5574 return alt[which_alternative];
5576 "TARGET_SH1 && ! TARGET_ZDCBRANCH"
5579 rtx skip_neg_label = gen_label_rtx ();
5581 emit_move_insn (operands[0], operands[1]);
5583 emit_jump_insn (INTVAL (operands[3])
5584 ? gen_branch_true (skip_neg_label)
5585 : gen_branch_false (skip_neg_label));
5587 emit_label_after (skip_neg_label,
5588 emit_insn (gen_negsi2 (operands[0], operands[1])));
5591 [(set_attr "type" "arith") ;; poor approximation
5592 (set_attr "length" "4")])
5594 (define_insn_and_split "negdi_cond"
5595 [(set (match_operand:DI 0 "arith_reg_dest")
5597 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand"))
5598 (match_operand:DI 1 "arith_reg_operand")
5599 (neg:DI (match_operand:DI 2 "arith_reg_operand"))))
5600 (clobber (reg:SI T_REG))]
5603 "&& can_create_pseudo_p ()"
5606 rtx skip_neg_label = gen_label_rtx ();
5608 emit_move_insn (operands[0], operands[1]);
5610 emit_jump_insn (INTVAL (operands[3])
5611 ? gen_branch_true (skip_neg_label)
5612 : gen_branch_false (skip_neg_label));
5614 if (!INTVAL (operands[3]))
5615 emit_insn (gen_clrt ());
5617 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5618 gen_lowpart (SImode, operands[1])));
5619 emit_label_after (skip_neg_label,
5620 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5621 gen_highpart (SImode, operands[1]))));
5625 (define_expand "bswapsi2"
5626 [(set (match_operand:SI 0 "arith_reg_dest" "")
5627 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
5630 if (! can_create_pseudo_p ())
5634 rtx tmp0 = gen_reg_rtx (SImode);
5635 rtx tmp1 = gen_reg_rtx (SImode);
5637 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
5638 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
5639 emit_insn (gen_swapbsi2 (operands[0], tmp1));
5644 (define_insn "swapbsi2"
5645 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5646 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
5647 (const_int 4294901760))
5648 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5650 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5651 (const_int 255)))))]
5654 [(set_attr "type" "arith")])
5656 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
5657 ;; partial byte swap expressions such as...
5658 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
5659 ;; ...which are currently not handled by the tree optimizers.
5660 ;; The combine pass will not initially try to combine the full expression,
5661 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
5662 ;; pattern acts as an intermediate pattern that will eventually lead combine
5663 ;; to the swapbsi2 pattern above.
5664 ;; As a side effect this also improves code that does (x & 0xFF) << 8
5665 ;; or (x << 8) & 0xFF00.
5666 (define_insn_and_split "*swapbisi2_and_shl8"
5667 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5668 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5671 (match_operand:SI 2 "arith_reg_operand" "r")))]
5672 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5674 "&& can_create_pseudo_p ()"
5677 rtx tmp0 = gen_reg_rtx (SImode);
5678 rtx tmp1 = gen_reg_rtx (SImode);
5680 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
5681 emit_insn (gen_swapbsi2 (tmp1, tmp0));
5682 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
5686 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
5687 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
5688 (define_insn_and_split "*swapbhisi2"
5689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5690 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5693 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
5694 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5696 "&& can_create_pseudo_p ()"
5699 rtx tmp = gen_reg_rtx (SImode);
5701 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
5702 emit_insn (gen_swapbsi2 (operands[0], tmp));
5706 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
5710 ;; which can be simplified to...
5713 [(set (match_operand:SI 0 "arith_reg_dest" "")
5714 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5715 (const_int 4294901760))
5716 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5718 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5720 (set (match_operand:SI 2 "arith_reg_dest" "")
5722 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
5724 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5725 (const_int 4294901760))
5726 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5728 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5729 (const_int 255)))))])
5732 ;; -------------------------------------------------------------------------
5733 ;; Zero extension instructions
5734 ;; -------------------------------------------------------------------------
5736 (define_insn "zero_extendsidi2"
5737 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5738 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
5740 "addz.l %1, r63, %0"
5741 [(set_attr "type" "arith_media")
5742 (set_attr "highpart" "extend")])
5744 (define_insn "zero_extendhidi2"
5745 [(set (match_operand:DI 0 "register_operand" "=r,r")
5746 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5751 [(set_attr "type" "*,load_media")
5752 (set (attr "highpart")
5753 (cond [(match_test "sh_contains_memref_p (insn)")
5754 (const_string "user")]
5755 (const_string "ignore")))])
5758 [(set (match_operand:DI 0 "register_operand" "")
5759 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5760 "TARGET_SHMEDIA && reload_completed"
5761 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5762 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
5764 if (GET_CODE (operands[1]) == TRUNCATE)
5765 operands[1] = XEXP (operands[1], 0);
5768 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
5769 ;; reload the entire truncate expression.
5770 (define_insn_and_split "*loaddi_trunc"
5771 [(set (match_operand 0 "any_register_operand" "=r")
5772 (truncate (match_operand:DI 1 "memory_operand" "m")))]
5773 "TARGET_SHMEDIA && reload_completed"
5775 "TARGET_SHMEDIA && reload_completed"
5776 [(set (match_dup 0) (match_dup 1))]
5778 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5781 (define_insn "zero_extendqidi2"
5782 [(set (match_operand:DI 0 "register_operand" "=r,r")
5783 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5788 [(set_attr "type" "arith_media,load_media")
5789 (set (attr "highpart")
5790 (cond [(match_test "sh_contains_memref_p (insn)")
5791 (const_string "user")]
5792 (const_string "ignore")))])
5794 (define_expand "zero_extend<mode>si2"
5795 [(set (match_operand:SI 0 "arith_reg_dest")
5796 (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
5798 (define_insn_and_split "*zero_extend<mode>si2_compact"
5799 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5800 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
5803 "&& can_create_pseudo_p ()"
5804 [(set (match_dup 0) (match_dup 2))]
5806 /* Sometimes combine fails to combine a T bit or negated T bit store to a
5807 reg with a following zero extension. In the split pass after combine,
5808 try to figure the extended reg was set. If it originated from the T
5809 bit we can replace the zero extension with a reg move, which will be
5810 eliminated. Notice that this also helps the *cbranch_t splitter when
5811 it tries to post-combine tests and conditional branches, as it does not
5812 check for zero extensions. */
5813 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
5814 if (operands[2] == NULL_RTX)
5817 [(set_attr "type" "arith")])
5819 (define_insn "*zero_extendhisi2_media"
5820 [(set (match_operand:SI 0 "register_operand" "=r,r")
5821 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5826 [(set_attr "type" "arith_media,load_media")
5827 (set (attr "highpart")
5828 (cond [(match_test "sh_contains_memref_p (insn)")
5829 (const_string "user")]
5830 (const_string "ignore")))])
5833 [(set (match_operand:SI 0 "register_operand" "")
5834 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
5835 "TARGET_SHMEDIA && reload_completed"
5836 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5837 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5839 rtx op1 = operands[1];
5841 if (GET_CODE (op1) == TRUNCATE)
5842 op1 = XEXP (op1, 0);
5844 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
5845 subreg_lowpart_offset (SImode, GET_MODE (op1)));
5848 (define_insn "*zero_extendqisi2_media"
5849 [(set (match_operand:SI 0 "register_operand" "=r,r")
5850 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5855 [(set_attr "type" "arith_media,load_media")
5856 (set (attr "highpart")
5857 (cond [(match_test "sh_contains_memref_p (insn)")
5858 (const_string "user")]
5859 (const_string "ignore")))])
5861 (define_insn "zero_extendqihi2"
5862 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
5863 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
5866 [(set_attr "type" "arith")])
5868 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
5869 ;; They could also be used for simple memory addresses like @Rn by setting
5870 ;; the displacement value to zero. However, doing so too early results in
5871 ;; missed opportunities for other optimizations such as post-inc or index
5872 ;; addressing loads.
5873 ;; Although the 'zero_extend_movu_operand' predicate does not allow simple
5874 ;; register addresses (an address without a displacement, index, post-inc),
5875 ;; zero-displacement addresses might be generated during reload, wich are
5876 ;; simplified to simple register addresses in turn. Thus, we have to
5877 ;; provide the Sdd and Sra alternatives in the patterns.
5878 (define_insn "*zero_extend<mode>si2_disp_mem"
5879 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5881 (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
5885 movu.<bw> @(0,%t1),%0"
5886 [(set_attr "type" "load")
5887 (set_attr "length" "4")])
5889 ;; Convert the zero extending loads in sequences such as:
5890 ;; movu.b @(1,r5),r0 movu.w @(2,r5),r0
5891 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
5893 ;; back to sign extending loads like:
5894 ;; mov.b @(1,r5),r0 mov.w @(2,r5),r0
5895 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
5897 ;; if the extension type is irrelevant. The sign extending mov.{b|w} insn
5898 ;; is only 2 bytes in size if the displacement is {K04|K05}.
5899 ;; If the displacement is greater it doesn't matter, so we convert anyways.
5901 [(set (match_operand:SI 0 "arith_reg_dest" "")
5902 (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
5903 (set (match_operand 2 "general_operand" "")
5904 (match_operand 3 "arith_reg_operand" ""))]
5906 && REGNO (operands[0]) == REGNO (operands[3])
5907 && peep2_reg_dead_p (2, operands[0])
5908 && GET_MODE_SIZE (GET_MODE (operands[2]))
5909 <= GET_MODE_SIZE (GET_MODE (operands[1]))"
5910 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
5911 (set (match_dup 2) (match_dup 3))])
5913 ;; Fold sequences such as
5917 ;; movu.b @(0,r3),r7
5918 ;; This does not reduce the code size but the number of instructions is
5919 ;; halved, which results in faster code.
5921 [(set (match_operand:SI 0 "arith_reg_dest" "")
5922 (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
5923 (set (match_operand:SI 2 "arith_reg_dest" "")
5924 (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
5926 && GET_MODE (operands[1]) == GET_MODE (operands[3])
5927 && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
5928 && REGNO (operands[0]) == REGNO (operands[3])
5929 && (REGNO (operands[2]) == REGNO (operands[0])
5930 || peep2_reg_dead_p (2, operands[0]))"
5931 [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
5934 = replace_equiv_address (operands[1],
5935 gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
5939 ;; -------------------------------------------------------------------------
5940 ;; Sign extension instructions
5941 ;; -------------------------------------------------------------------------
5943 ;; ??? This should be a define expand.
5944 ;; ??? Or perhaps it should be dropped?
5946 ;; convert_move generates good code for SH[1-4].
5947 (define_insn "extendsidi2"
5948 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5949 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
5955 [(set_attr "type" "arith_media,load_media,fpconv_media")
5956 (set (attr "highpart")
5957 (cond [(match_test "sh_contains_memref_p (insn)")
5958 (const_string "user")]
5959 (const_string "extend")))])
5961 (define_insn "extendhidi2"
5962 [(set (match_operand:DI 0 "register_operand" "=r,r")
5963 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5968 [(set_attr "type" "*,load_media")
5969 (set (attr "highpart")
5970 (cond [(match_test "sh_contains_memref_p (insn)")
5971 (const_string "user")]
5972 (const_string "ignore")))])
5975 [(set (match_operand:DI 0 "register_operand" "")
5976 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5977 "TARGET_SHMEDIA && reload_completed"
5978 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5979 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
5981 if (GET_CODE (operands[1]) == TRUNCATE)
5982 operands[1] = XEXP (operands[1], 0);
5985 (define_insn "extendqidi2"
5986 [(set (match_operand:DI 0 "register_operand" "=r,r")
5987 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5992 [(set_attr "type" "*,load_media")
5993 (set (attr "highpart")
5994 (cond [(match_test "sh_contains_memref_p (insn)")
5995 (const_string "user")]
5996 (const_string "ignore")))])
5999 [(set (match_operand:DI 0 "register_operand" "")
6000 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
6001 "TARGET_SHMEDIA && reload_completed"
6002 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
6003 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6005 if (GET_CODE (operands[1]) == TRUNCATE)
6006 operands[1] = XEXP (operands[1], 0);
6009 (define_expand "extend<mode>si2"
6010 [(set (match_operand:SI 0 "arith_reg_dest")
6011 (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
6013 (define_insn "*extendhisi2_media"
6014 [(set (match_operand:SI 0 "register_operand" "=r,r")
6015 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6020 [(set_attr "type" "arith_media,load_media")
6021 (set (attr "highpart")
6022 (cond [(match_test "sh_contains_memref_p (insn)")
6023 (const_string "user")]
6024 (const_string "ignore")))])
6027 [(set (match_operand:SI 0 "register_operand" "")
6028 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6029 "TARGET_SHMEDIA && reload_completed"
6030 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6031 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
6033 rtx op1 = operands[1];
6034 if (GET_CODE (op1) == TRUNCATE)
6035 op1 = XEXP (op1, 0);
6037 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6038 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6041 (define_insn_and_split "*extend<mode>si2_compact_reg"
6042 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6043 (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6046 "&& can_create_pseudo_p ()"
6047 [(set (match_dup 0) (match_dup 2))]
6049 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6050 reg with a following sign extension. In the split pass after combine,
6051 try to figure the extended reg was set. If it originated from the T
6052 bit we can replace the sign extension with a reg move, which will be
6054 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6055 if (operands[2] == NULL_RTX)
6058 [(set_attr "type" "arith")])
6060 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
6062 (define_insn "*extend<mode>si2_compact_mem_disp"
6063 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
6067 (match_operand:SI 1 "arith_reg_operand" "%r,r")
6068 (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
6069 "TARGET_SH1 && ! TARGET_SH2A
6070 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6072 mov.<bw> @(%O2,%1),%0
6074 [(set_attr "type" "load")])
6076 (define_insn "*extend<mode>si2_compact_mem_disp"
6077 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
6081 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6082 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
6083 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6085 mov.<bw> @(%O2,%1),%0
6087 mov.<bw> @(%O2,%1),%0"
6088 [(set_attr "type" "load")
6089 (set_attr "length" "2,2,4")])
6091 ;; The *_snd patterns will take care of other QImode/HImode addressing
6092 ;; modes than displacement addressing. They must be defined _after_ the
6093 ;; displacement addressing patterns. Otherwise the displacement addressing
6094 ;; patterns will not be picked.
6095 (define_insn "*extend<mode>si2_compact_snd"
6096 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6098 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
6101 [(set_attr "type" "load")])
6103 (define_insn "*extendqisi2_media"
6104 [(set (match_operand:SI 0 "register_operand" "=r,r")
6105 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6110 [(set_attr "type" "arith_media,load_media")
6111 (set (attr "highpart")
6112 (cond [(match_test "sh_contains_memref_p (insn)")
6113 (const_string "user")]
6114 (const_string "ignore")))])
6117 [(set (match_operand:SI 0 "register_operand" "")
6118 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
6119 "TARGET_SHMEDIA && reload_completed"
6120 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
6121 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
6123 rtx op1 = operands[1];
6124 if (GET_CODE (op1) == TRUNCATE)
6125 op1 = XEXP (op1, 0);
6127 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6128 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6131 (define_expand "extendqihi2"
6132 [(set (match_operand:HI 0 "arith_reg_dest" "")
6133 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
6137 (define_insn "*extendqihi2_compact_reg"
6138 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6139 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6142 [(set_attr "type" "arith")])
6144 ;; It would seem useful to combine the truncXi patterns into the movXi
6145 ;; patterns, but unary operators are ignored when matching constraints,
6146 ;; so we need separate patterns.
6147 (define_insn "truncdisi2"
6148 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
6149 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
6158 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
6159 (set (attr "highpart")
6160 (cond [(match_test "sh_contains_memref_p (insn)")
6161 (const_string "user")]
6162 (const_string "extend")))])
6164 (define_insn "truncdihi2"
6165 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
6166 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
6169 static const char* alt[] =
6171 "shlli %1,48,%0" "\n"
6176 return alt[which_alternative];
6178 [(set_attr "type" "arith_media,store_media")
6179 (set_attr "length" "8,4")
6180 (set (attr "highpart")
6181 (cond [(match_test "sh_contains_memref_p (insn)")
6182 (const_string "user")]
6183 (const_string "extend")))])
6185 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
6186 ; Because we use zero extension, we can't provide signed QImode compares
6187 ; using a simple compare or conditional branch insn.
6188 (define_insn "truncdiqi2"
6189 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
6190 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
6195 [(set_attr "type" "arith_media,store")
6196 (set (attr "highpart")
6197 (cond [(match_test "sh_contains_memref_p (insn)")
6198 (const_string "user")]
6199 (const_string "extend")))])
6200 ;; -------------------------------------------------------------------------
6201 ;; Move instructions
6202 ;; -------------------------------------------------------------------------
6204 ;; define push and pop so it is easy for sh.c
6205 ;; We can't use push and pop on SHcompact because the stack must always
6206 ;; be 8-byte aligned.
6208 (define_expand "push"
6209 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6210 (match_operand:SI 0 "register_operand" "r,l,x"))]
6211 "TARGET_SH1 && ! TARGET_SH5"
6214 (define_expand "pop"
6215 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6216 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6217 "TARGET_SH1 && ! TARGET_SH5"
6220 (define_expand "push_e"
6221 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6222 (match_operand:SF 0 "" ""))
6223 (use (reg:PSI FPSCR_REG))
6224 (clobber (scratch:SI))])]
6225 "TARGET_SH1 && ! TARGET_SH5"
6228 (define_insn "push_fpul"
6229 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6230 "TARGET_SH2E && ! TARGET_SH5"
6232 [(set_attr "type" "fstore")
6233 (set_attr "late_fp_use" "yes")
6234 (set_attr "hit_stack" "yes")])
6236 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6238 (define_expand "push_4"
6239 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6240 (match_operand:DF 0 "" ""))
6241 (use (reg:PSI FPSCR_REG))
6242 (clobber (scratch:SI))])]
6243 "TARGET_SH1 && ! TARGET_SH5"
6246 (define_expand "pop_e"
6247 [(parallel [(set (match_operand:SF 0 "" "")
6248 (mem:SF (post_inc:SI (reg:SI SP_REG))))
6249 (use (reg:PSI FPSCR_REG))
6250 (clobber (scratch:SI))])]
6251 "TARGET_SH1 && ! TARGET_SH5"
6254 (define_insn "pop_fpul"
6255 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6256 "TARGET_SH2E && ! TARGET_SH5"
6258 [(set_attr "type" "load")
6259 (set_attr "hit_stack" "yes")])
6261 (define_expand "pop_4"
6262 [(parallel [(set (match_operand:DF 0 "" "")
6263 (mem:DF (post_inc:SI (reg:SI SP_REG))))
6264 (use (reg:PSI FPSCR_REG))
6265 (clobber (scratch:SI))])]
6266 "TARGET_SH1 && ! TARGET_SH5"
6269 (define_expand "push_fpscr"
6273 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
6274 gen_rtx_PRE_DEC (Pmode,
6275 stack_pointer_rtx)),
6277 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6281 (define_expand "pop_fpscr"
6285 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
6286 gen_frame_mem (PSImode,
6287 gen_rtx_POST_INC (Pmode,
6288 stack_pointer_rtx))));
6289 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6293 ;; The clrt and sett patterns can happen as the result of optimization and
6295 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6296 ;; In this case they might not disappear completely, because the T reg is
6297 ;; a fixed hard reg.
6298 ;; When DImode operations that use the T reg as carry/borrow are split into
6299 ;; individual SImode operations, the T reg is usually cleared before the
6300 ;; first SImode insn.
6303 [(set (reg:SI T_REG) (const_int 0))]
6306 [(set_attr "type" "mt_group")])
6309 [(set (reg:SI T_REG) (const_int 1))]
6312 [(set_attr "type" "mt_group")])
6314 ;; Use the combine pass to transform sequences such as
6318 ;; mov.l @(r0,r4),r0
6324 ;; See also PR 39423.
6325 ;; Notice that these patterns have a T_REG clobber, because the shift
6326 ;; sequence that will be split out might clobber the T_REG. Ideally, the
6327 ;; clobber would be added conditionally, depending on the result of
6328 ;; sh_ashlsi_clobbers_t_reg_p. When splitting out the shifts we must go
6329 ;; through the ashlsi3 expander in order to get the right shift insn --
6330 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6331 ;; FIXME: Combine never tries this kind of patterns for DImode.
6332 (define_insn_and_split "*movsi_index_disp_load"
6333 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6334 (match_operand:SI 1 "mem_index_disp_operand" "m"))
6335 (clobber (reg:SI T_REG))]
6338 "&& can_create_pseudo_p ()"
6339 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6340 (set (match_dup 0) (match_dup 7))]
6342 rtx mem = operands[1];
6343 rtx plus0_rtx = XEXP (mem, 0);
6344 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6345 rtx mult_rtx = XEXP (plus1_rtx, 0);
6347 operands[1] = XEXP (mult_rtx, 0);
6348 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6349 operands[3] = XEXP (plus1_rtx, 1);
6350 operands[4] = XEXP (plus0_rtx, 1);
6351 operands[5] = gen_reg_rtx (SImode);
6352 operands[6] = gen_reg_rtx (SImode);
6354 replace_equiv_address (mem,
6355 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6357 emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6360 (define_insn_and_split "*movhi_index_disp_load"
6361 [(set (match_operand:SI 0 "arith_reg_dest")
6362 (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6363 (clobber (reg:SI T_REG))]
6366 "&& can_create_pseudo_p ()"
6369 rtx mem = operands[1];
6370 rtx plus0_rtx = XEXP (mem, 0);
6371 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6372 rtx mult_rtx = XEXP (plus1_rtx, 0);
6374 rtx op_1 = XEXP (mult_rtx, 0);
6375 rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6376 rtx op_3 = XEXP (plus1_rtx, 1);
6377 rtx op_4 = XEXP (plus0_rtx, 1);
6378 rtx op_5 = gen_reg_rtx (SImode);
6379 rtx op_6 = gen_reg_rtx (SImode);
6380 rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6382 emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6383 emit_insn (gen_addsi3 (op_6, op_5, op_3));
6385 if (<CODE> == SIGN_EXTEND)
6387 emit_insn (gen_extendhisi2 (operands[0], op_7));
6390 else if (<CODE> == ZERO_EXTEND)
6392 /* On SH2A the movu.w insn can be used for zero extending loads. */
6394 emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
6397 emit_insn (gen_extendhisi2 (operands[0], op_7));
6398 emit_insn (gen_zero_extendhisi2 (operands[0],
6399 gen_lowpart (HImode, operands[0])));
6407 (define_insn_and_split "*mov<mode>_index_disp_store"
6408 [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
6409 (match_operand:HISI 1 "arith_reg_operand" "r"))
6410 (clobber (reg:SI T_REG))]
6413 "&& can_create_pseudo_p ()"
6414 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6415 (set (match_dup 7) (match_dup 1))]
6417 rtx mem = operands[0];
6418 rtx plus0_rtx = XEXP (mem, 0);
6419 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6420 rtx mult_rtx = XEXP (plus1_rtx, 0);
6422 operands[0] = XEXP (mult_rtx, 0);
6423 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6424 operands[3] = XEXP (plus1_rtx, 1);
6425 operands[4] = XEXP (plus0_rtx, 1);
6426 operands[5] = gen_reg_rtx (SImode);
6427 operands[6] = gen_reg_rtx (SImode);
6429 replace_equiv_address (mem,
6430 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6432 emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
6435 ;; t/r must come after r/r, lest reload will try to reload stuff like
6436 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
6437 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
6438 (define_insn "movsi_i"
6439 [(set (match_operand:SI 0 "general_movdst_operand"
6440 "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
6441 (match_operand:SI 1 "general_movsrc_operand"
6442 "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
6446 && (register_operand (operands[0], SImode)
6447 || register_operand (operands[1], SImode))"
6463 [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
6464 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
6466 ;; t/r must come after r/r, lest reload will try to reload stuff like
6467 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
6468 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
6469 ;; will require a reload.
6470 ;; ??? We can't include f/f because we need the proper FPSCR setting when
6471 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
6472 (define_insn "movsi_ie"
6473 [(set (match_operand:SI 0 "general_movdst_operand"
6474 "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
6475 (match_operand:SI 1 "general_movsrc_operand"
6476 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
6477 "(TARGET_SH2E || TARGET_SH2A)
6478 && (register_operand (operands[0], SImode)
6479 || register_operand (operands[1], SImode))"
6504 ! move optimized away"
6505 [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
6506 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
6507 (set_attr_alternative "length"
6514 (match_test "TARGET_SH2A")
6515 (const_int 4) (const_int 2))
6519 (match_test "TARGET_SH2A")
6520 (const_int 4) (const_int 2))
6537 (define_insn "movsi_i_lowpart"
6538 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
6539 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
6541 && (register_operand (operands[0], SImode)
6542 || register_operand (operands[1], SImode))"
6552 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
6554 (define_insn_and_split "load_ra"
6555 [(set (match_operand:SI 0 "general_movdst_operand" "")
6556 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
6559 "&& ! currently_expanding_to_rtl"
6560 [(set (match_dup 0) (match_dup 1))]
6562 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
6563 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
6566 ;; The '?'s in the following constraints may not reflect the time taken
6567 ;; to perform the move. They are there to discourage the use of floating-
6568 ;; point registers for storing integer values.
6569 (define_insn "*movsi_media"
6570 [(set (match_operand:SI 0 "general_movdst_operand"
6571 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
6572 (match_operand:SI 1 "general_movsrc_operand"
6573 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6575 && (register_operand (operands[0], SImode)
6576 || sh_register_operand (operands[1], SImode)
6577 || GET_CODE (operands[1]) == TRUNCATE)"
6592 [(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")
6593 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
6594 (set (attr "highpart")
6595 (cond [(match_test "sh_contains_memref_p (insn)")
6596 (const_string "user")]
6597 (const_string "ignore")))])
6599 (define_insn "*movsi_media_nofpu"
6600 [(set (match_operand:SI 0 "general_movdst_operand"
6601 "=r,r,r,r,m,*b,r,*b")
6602 (match_operand:SI 1 "general_movsrc_operand"
6603 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
6605 && (register_operand (operands[0], SImode)
6606 || sh_register_operand (operands[1], SImode)
6607 || GET_CODE (operands[1]) == TRUNCATE)"
6617 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
6618 (set_attr "length" "4,4,8,4,4,4,4,12")
6619 (set (attr "highpart")
6620 (cond [(match_test "sh_contains_memref_p (insn)")
6621 (const_string "user")]
6622 (const_string "ignore")))])
6624 (define_expand "movsi_const"
6625 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6626 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6627 (const_int 16)] UNSPEC_EXTRACT_S16)))
6629 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
6630 (const:SI (unspec:SI [(match_dup 1)
6631 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6632 "TARGET_SHMEDIA && reload_completed
6633 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6635 if (GET_CODE (operands[1]) == LABEL_REF
6636 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
6637 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
6638 else if (GOTOFF_P (operands[1]))
6640 rtx unspec = XEXP (operands[1], 0);
6642 if (! UNSPEC_GOTOFF_P (unspec))
6644 unspec = XEXP (unspec, 0);
6645 if (! UNSPEC_GOTOFF_P (unspec))
6648 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
6649 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
6650 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
6654 (define_expand "movsi_const_16bit"
6655 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6656 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6657 (const_int 0)] UNSPEC_EXTRACT_S16)))]
6658 "TARGET_SHMEDIA && flag_pic && reload_completed
6659 && GET_CODE (operands[1]) == SYMBOL_REF"
6663 [(set (match_operand:SI 0 "arith_reg_dest" "")
6664 (match_operand:SI 1 "immediate_operand" ""))]
6665 "TARGET_SHMEDIA && reload_completed
6666 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6669 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
6671 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6677 [(set (match_operand:SI 0 "register_operand" "")
6678 (match_operand:SI 1 "immediate_operand" ""))]
6679 "TARGET_SHMEDIA && reload_completed
6680 && ((CONST_INT_P (operands[1])
6681 && ! satisfies_constraint_I16 (operands[1]))
6682 || GET_CODE (operands[1]) == CONST_DOUBLE)"
6683 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6685 (define_expand "movsi"
6686 [(set (match_operand:SI 0 "general_movdst_operand" "")
6687 (match_operand:SI 1 "general_movsrc_operand" ""))]
6690 prepare_move_operands (operands, SImode);
6693 (define_expand "ic_invalidate_line"
6694 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
6695 (match_dup 1)] UNSPEC_ICACHE)
6696 (clobber (scratch:SI))])]
6697 "TARGET_HARD_SH4 || TARGET_SH5"
6701 emit_insn (gen_ic_invalidate_line_media (operands[0]));
6704 else if (TARGET_SHCOMPACT)
6706 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
6707 operands[1] = force_reg (Pmode, operands[1]);
6708 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
6711 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
6713 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
6716 operands[0] = force_reg (Pmode, operands[0]);
6717 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
6721 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
6722 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
6723 ;; the requirement *1*00 for associative address writes. The alignment of
6724 ;; %0 implies that its least significant bit is cleared,
6725 ;; thus we clear the V bit of a matching entry if there is one.
6726 (define_insn "ic_invalidate_line_i"
6727 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
6728 (match_operand:SI 1 "register_operand" "r")]
6730 (clobber (match_scratch:SI 2 "=&r"))]
6733 return "ocbwb @%0" "\n"
6734 " extu.w %0,%2" "\n"
6738 [(set_attr "length" "8")
6739 (set_attr "type" "cwb")])
6741 (define_insn "ic_invalidate_line_sh4a"
6742 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6744 "TARGET_SH4A_ARCH || TARGET_SH4_300"
6746 return "ocbwb @%0" "\n"
6750 [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
6751 (set_attr "type" "cwb")])
6753 ;; ??? could make arg 0 an offsettable memory operand to allow to save
6754 ;; an add in the code that calculates the address.
6755 (define_insn "ic_invalidate_line_media"
6756 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
6760 return "ocbwb %0,0" "\n"
6765 [(set_attr "length" "16")
6766 (set_attr "type" "invalidate_line_media")])
6768 (define_insn "ic_invalidate_line_compact"
6769 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6770 (match_operand:SI 1 "register_operand" "r")]
6772 (clobber (reg:SI PR_REG))]
6775 [(set_attr "type" "sfunc")
6776 (set_attr "needs_delay_slot" "yes")])
6778 (define_expand "initialize_trampoline"
6779 [(match_operand:SI 0 "" "")
6780 (match_operand:SI 1 "" "")
6781 (match_operand:SI 2 "" "")]
6786 tramp = force_reg (Pmode, operands[0]);
6787 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
6789 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
6790 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
6792 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
6796 (define_insn "initialize_trampoline_compact"
6797 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6798 (match_operand:SI 1 "register_operand" "r")
6799 (reg:SI R2_REG) (reg:SI R3_REG)]
6802 (clobber (reg:SI PR_REG))]
6805 [(set_attr "type" "sfunc")
6806 (set_attr "needs_delay_slot" "yes")])
6808 (define_expand "movhi"
6809 [(set (match_operand:HI 0 "general_movdst_operand" "")
6810 (match_operand:HI 1 "general_movsrc_operand" ""))]
6813 prepare_move_operands (operands, HImode);
6816 (define_expand "movqi"
6817 [(set (match_operand:QI 0 "general_operand" "")
6818 (match_operand:QI 1 "general_operand" ""))]
6821 prepare_move_operands (operands, QImode);
6824 ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
6825 ;; selected to copy QImode regs. If one of them happens to be allocated
6826 ;; on the stack, reload will stick to movqi insn and generate wrong
6827 ;; displacement addressing because of the generic m alternatives.
6828 ;; With the movqi_reg_reg being specified before movqi it will be initially
6829 ;; picked to load/store regs. If the regs regs are on the stack reload will
6830 ;; try other insns and not stick to movqi_reg_reg.
6831 ;; The same applies to the movhi variants.
6833 ;; Notice, that T bit is not allowed as a mov src operand here. This is to
6834 ;; avoid things like (set (reg:QI) (subreg:QI (reg:SI T_REG) 0)), which
6835 ;; introduces zero extensions after T bit stores and redundant reg copies.
6837 ;; FIXME: We can't use 'arith_reg_operand' (which disallows T_REG) as a
6838 ;; predicate for the mov src operand because reload will have trouble
6839 ;; reloading MAC subregs otherwise. For that probably special patterns
6840 ;; would be required.
6841 (define_insn "*mov<mode>_reg_reg"
6842 [(set (match_operand:QIHI 0 "arith_reg_dest" "=r")
6843 (match_operand:QIHI 1 "register_operand" "r"))]
6844 "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
6846 [(set_attr "type" "move")])
6848 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
6849 ;; "enabled" attribute as it is done in other targets.
6850 (define_insn "*mov<mode>_store_mem_disp04"
6852 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
6853 (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
6854 (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
6855 "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
6857 mov.<bw> %2,@(%O1,%0)
6859 [(set_attr "type" "store")])
6861 (define_insn "*mov<mode>_store_mem_disp12"
6863 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
6864 (match_operand:SI 1 "const_int_operand" "<disp12>")))
6865 (match_operand:QIHI 2 "arith_reg_operand" "r"))]
6866 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
6867 "mov.<bw> %2,@(%O1,%0)"
6868 [(set_attr "type" "store")
6869 (set_attr "length" "4")])
6871 (define_insn "*mov<mode>_load_mem_disp04"
6872 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
6874 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
6875 (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
6876 "TARGET_SH1 && ! TARGET_SH2A
6877 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6879 mov.<bw> @(%O2,%1),%0
6881 [(set_attr "type" "load")])
6883 (define_insn "*mov<mode>_load_mem_disp12"
6884 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
6887 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6888 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
6889 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6891 mov.<bw> @(%O2,%1),%0
6893 mov.<bw> @(%O2,%1),%0"
6894 [(set_attr "type" "load")
6895 (set_attr "length" "2,2,4")])
6897 ;; The m constraints basically allow any kind of addresses to be used with any
6898 ;; source/target register as the other operand. This is not true for
6899 ;; displacement addressing modes on anything but SH2A. That's why the
6900 ;; specialized load/store insns are specified above.
6901 (define_insn "*movqi"
6902 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
6903 (match_operand:QI 1 "general_movsrc_operand" "i,m,r,l,r"))]
6905 && (arith_reg_operand (operands[0], QImode)
6906 || arith_reg_operand (operands[1], QImode))"
6913 [(set_attr "type" "movi8,load,store,prget,prset")])
6915 (define_insn "*movhi"
6916 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l")
6917 (match_operand:HI 1 "general_movsrc_operand" "Q,i,m,r,l,r"))]
6919 && (arith_reg_operand (operands[0], HImode)
6920 || arith_reg_operand (operands[1], HImode))"
6928 [(set_attr "type" "pcload,movi8,load,store,prget,prset")])
6930 (define_insn "*movqi_media"
6931 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
6932 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
6934 && (arith_reg_operand (operands[0], QImode)
6935 || extend_reg_or_0_operand (operands[1], QImode))"
6941 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
6942 (set (attr "highpart")
6943 (cond [(match_test "sh_contains_memref_p (insn)")
6944 (const_string "user")]
6945 (const_string "ignore")))])
6947 (define_expand "reload_inqi"
6948 [(set (match_operand:SI 2 "" "=&r")
6949 (match_operand:QI 1 "inqhi_operand" ""))
6950 (set (match_operand:QI 0 "arith_reg_operand" "=r")
6951 (truncate:QI (match_dup 3)))]
6954 rtx inner = XEXP (operands[1], 0);
6955 int regno = REGNO (inner);
6957 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
6958 operands[1] = gen_rtx_REG (SImode, regno);
6959 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
6962 (define_insn "*movhi_media"
6963 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
6964 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
6966 && (arith_reg_operand (operands[0], HImode)
6967 || arith_reg_or_0_operand (operands[1], HImode))"
6974 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
6975 (set (attr "highpart")
6976 (cond [(match_test "sh_contains_memref_p (insn)")
6977 (const_string "user")]
6978 (const_string "ignore")))])
6981 [(set (match_operand:HI 0 "register_operand" "")
6982 (match_operand:HI 1 "immediate_operand" ""))]
6983 "TARGET_SHMEDIA && reload_completed
6984 && ! satisfies_constraint_I16 (operands[1])"
6985 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6987 (define_expand "reload_inhi"
6988 [(set (match_operand:SI 2 "" "=&r")
6989 (match_operand:HI 1 "inqhi_operand" ""))
6990 (set (match_operand:HI 0 "arith_reg_operand" "=r")
6991 (truncate:HI (match_dup 3)))]
6994 rtx inner = XEXP (operands[1], 0);
6995 int regno = REGNO (inner);
6997 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
6998 operands[1] = gen_rtx_REG (SImode, regno);
6999 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7002 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7003 ;; compiled with -m2 -ml -O3 -funroll-loops
7004 (define_insn "*movdi_i"
7005 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7006 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7008 && (arith_reg_operand (operands[0], DImode)
7009 || arith_reg_operand (operands[1], DImode))"
7011 return output_movedouble (insn, operands, DImode);
7013 [(set_attr "length" "4")
7014 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7016 ;; If the output is a register and the input is memory or a register, we have
7017 ;; to be careful and see which word needs to be loaded first.
7020 [(set (match_operand:DI 0 "general_movdst_operand" "")
7021 (match_operand:DI 1 "general_movsrc_operand" ""))]
7022 "TARGET_SH1 && reload_completed"
7023 [(set (match_dup 2) (match_dup 3))
7024 (set (match_dup 4) (match_dup 5))]
7028 if ((MEM_P (operands[0])
7029 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7030 || (MEM_P (operands[1])
7031 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7034 switch (GET_CODE (operands[0]))
7037 regno = REGNO (operands[0]);
7040 regno = subreg_regno (operands[0]);
7050 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7052 operands[2] = operand_subword (operands[0], 0, 0, DImode);
7053 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7054 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7055 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7059 operands[2] = operand_subword (operands[0], 1, 0, DImode);
7060 operands[3] = operand_subword (operands[1], 1, 0, DImode);
7061 operands[4] = operand_subword (operands[0], 0, 0, DImode);
7062 operands[5] = operand_subword (operands[1], 0, 0, DImode);
7065 if (operands[2] == 0 || operands[3] == 0
7066 || operands[4] == 0 || operands[5] == 0)
7070 ;; The '?'s in the following constraints may not reflect the time taken
7071 ;; to perform the move. They are there to discourage the use of floating-
7072 ;; point registers for storing integer values.
7073 (define_insn "*movdi_media"
7074 [(set (match_operand:DI 0 "general_movdst_operand"
7075 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7076 (match_operand:DI 1 "general_movsrc_operand"
7077 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7079 && (register_operand (operands[0], DImode)
7080 || sh_register_operand (operands[1], DImode))"
7095 [(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")
7096 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7098 (define_insn "*movdi_media_nofpu"
7099 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7100 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7102 && (register_operand (operands[0], DImode)
7103 || sh_register_operand (operands[1], DImode))"
7113 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
7114 (set_attr "length" "4,4,16,4,4,4,4,*")])
7116 (define_insn "*movdi_media_I16"
7117 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7118 (match_operand:DI 1 "const_int_operand" "I16"))]
7119 "TARGET_SHMEDIA && reload_completed"
7121 [(set_attr "type" "arith_media")
7122 (set_attr "length" "4")])
7125 [(set (match_operand:DI 0 "arith_reg_dest" "")
7126 (match_operand:DI 1 "immediate_operand" ""))]
7127 "TARGET_SHMEDIA && reload_completed
7128 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7129 [(set (match_dup 0) (match_dup 1))]
7133 if (TARGET_SHMEDIA64)
7134 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7136 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7138 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7143 (define_expand "movdi_const"
7144 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7145 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7146 (const_int 48)] UNSPEC_EXTRACT_S16)))
7148 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7149 (const:DI (unspec:DI [(match_dup 1)
7150 (const_int 32)] UNSPEC_EXTRACT_U16))))
7152 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7153 (const:DI (unspec:DI [(match_dup 1)
7154 (const_int 16)] UNSPEC_EXTRACT_U16))))
7156 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7157 (const:DI (unspec:DI [(match_dup 1)
7158 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7159 "TARGET_SHMEDIA64 && reload_completed
7160 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7162 sh_mark_label (operands[1], 4);
7165 (define_expand "movdi_const_32bit"
7166 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7167 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7168 (const_int 16)] UNSPEC_EXTRACT_S16)))
7170 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7171 (const:DI (unspec:DI [(match_dup 1)
7172 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7173 "TARGET_SHMEDIA32 && reload_completed
7174 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7176 sh_mark_label (operands[1], 2);
7179 (define_expand "movdi_const_16bit"
7180 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7181 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7182 (const_int 0)] UNSPEC_EXTRACT_S16)))]
7183 "TARGET_SHMEDIA && flag_pic && reload_completed
7184 && GET_CODE (operands[1]) == SYMBOL_REF"
7188 [(set (match_operand:DI 0 "ext_dest_operand" "")
7189 (match_operand:DI 1 "immediate_operand" ""))]
7190 "TARGET_SHMEDIA && reload_completed
7191 && CONST_INT_P (operands[1])
7192 && ! satisfies_constraint_I16 (operands[1])"
7193 [(set (match_dup 0) (match_dup 2))
7196 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7197 unsigned HOST_WIDE_INT low = val;
7198 unsigned HOST_WIDE_INT high = val;
7199 unsigned HOST_WIDE_INT sign;
7200 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7202 /* Zero-extend the 16 least-significant bits. */
7205 /* Arithmetic shift right the word by 16 bits. */
7207 if (GET_CODE (operands[0]) == SUBREG
7208 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7217 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7223 /* If we can't generate the constant with a two-insn movi / shori
7224 sequence, try some other strategies. */
7225 if (! CONST_OK_FOR_I16 (high))
7227 /* Try constant load / left shift. We know VAL != 0. */
7228 val2 = val ^ (val-1);
7231 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7233 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7234 || (! CONST_OK_FOR_I16 (high >> 16)
7235 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7237 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7238 operands[1] = gen_ashldi3_media (operands[0], operands[0],
7239 GEN_INT (trailing_zeroes));
7243 /* Try constant load / right shift. */
7244 val2 = (val >> 15) + 1;
7245 if (val2 == (val2 & -val2))
7247 int shift = 49 - exact_log2 (val2);
7249 val2 = trunc_int_for_mode (val << shift, DImode);
7250 if (CONST_OK_FOR_I16 (val2))
7252 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7258 val2 = val & 0xffff;
7259 if ((val >> 16 & 0xffff) == val2
7260 && (val >> 32 & 0xffff) == val2
7261 && (val >> 48 & 0xffff) == val2)
7263 val2 = (HOST_WIDE_INT) val >> 48;
7264 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7265 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7268 /* Try movi / mshflo.l */
7269 val2 = (HOST_WIDE_INT) val >> 32;
7270 if (val2 == ((unsigned HOST_WIDE_INT)
7271 trunc_int_for_mode (val, SImode)))
7273 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7277 /* Try movi / mshflo.l w/ r63. */
7278 val2 = val + ((HOST_WIDE_INT) -1 << 32);
7279 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7281 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7287 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7290 operands[2] = GEN_INT (val2);
7294 [(set (match_operand:DI 0 "ext_dest_operand" "")
7295 (match_operand:DI 1 "immediate_operand" ""))]
7296 "TARGET_SHMEDIA && reload_completed
7297 && GET_CODE (operands[1]) == CONST_DOUBLE"
7298 [(set (match_dup 0) (match_dup 2))
7300 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7302 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7303 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7304 unsigned HOST_WIDE_INT val = low;
7305 unsigned HOST_WIDE_INT sign;
7307 /* Zero-extend the 16 least-significant bits. */
7309 operands[1] = GEN_INT (val);
7311 /* Arithmetic shift right the double-word by 16 bits. */
7313 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7316 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7320 /* This will only be true if high is a sign-extension of low, i.e.,
7321 it must be either 0 or (unsigned)-1, and be zero iff the
7322 most-significant bit of low is set. */
7323 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7324 operands[2] = GEN_INT (low);
7326 operands[2] = immed_double_const (low, high, DImode);
7329 (define_insn "shori_media"
7330 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7331 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7333 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7334 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7338 [(set_attr "type" "arith_media,*")])
7340 (define_insn "*shori_media_si"
7341 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7342 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7344 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7348 (define_expand "movdi"
7349 [(set (match_operand:DI 0 "general_movdst_operand" "")
7350 (match_operand:DI 1 "general_movsrc_operand" ""))]
7353 prepare_move_operands (operands, DImode);
7356 (define_insn "movdf_media"
7357 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7358 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7360 && (register_operand (operands[0], DFmode)
7361 || sh_register_operand (operands[1], DFmode))"
7372 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
7374 (define_insn "movdf_media_nofpu"
7375 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7376 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7378 && (register_operand (operands[0], DFmode)
7379 || sh_register_operand (operands[1], DFmode))"
7385 [(set_attr "type" "arith_media,*,load_media,store_media")])
7388 [(set (match_operand:DF 0 "arith_reg_dest" "")
7389 (match_operand:DF 1 "immediate_operand" ""))]
7390 "TARGET_SHMEDIA && reload_completed"
7391 [(set (match_dup 3) (match_dup 2))]
7393 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7395 REAL_VALUE_TYPE value;
7397 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7398 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7400 if (HOST_BITS_PER_WIDE_INT >= 64)
7401 operands[2] = immed_double_const ((unsigned long) values[endian]
7402 | ((HOST_WIDE_INT) values[1 - endian]
7406 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7407 operands[2] = immed_double_const (values[endian], values[1 - endian],
7411 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7414 ;; ??? This should be a define expand.
7416 (define_insn "movdf_k"
7417 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7418 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7420 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7421 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7422 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7423 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7424 && (arith_reg_operand (operands[0], DFmode)
7425 || arith_reg_operand (operands[1], DFmode))"
7427 return output_movedouble (insn, operands, DFmode);
7429 [(set_attr "length" "4")
7430 (set_attr "type" "move,pcload,load,store")])
7432 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7433 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7434 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7435 ;; the d/m/c/X alternative, which is split later into single-precision
7436 ;; instructions. And when not optimizing, no splits are done before fixing
7437 ;; up pcloads, so we need usable length information for that.
7438 (define_insn "movdf_i4"
7439 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7440 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
7441 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
7442 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
7443 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7444 && (arith_reg_operand (operands[0], DFmode)
7445 || arith_reg_operand (operands[1], DFmode))"
7447 switch (which_alternative)
7451 return "fmov %1,%0";
7452 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7453 return "fmov %R1,%R0" "\n"
7456 return "fmov %S1,%S0" "\n"
7460 return "fmov.d %1,%0";
7465 [(set_attr_alternative "length"
7466 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7468 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7469 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7470 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7472 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7473 ;; We can't use 4-byte push/pop on SHcompact, so we have to
7474 ;; increment or decrement r15 explicitly.
7476 (match_test "TARGET_SHCOMPACT")
7477 (const_int 10) (const_int 8))
7479 (match_test "TARGET_SHCOMPACT")
7480 (const_int 10) (const_int 8))])
7481 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7482 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7483 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7484 (const_string "double")
7485 (const_string "none")))])
7487 ;; Moving DFmode between fp/general registers through memory
7488 ;; (the top of the stack) is faster than moving through fpul even for
7489 ;; little endian. Because the type of an instruction is important for its
7490 ;; scheduling, it is beneficial to split these operations, rather than
7491 ;; emitting them in one single chunk, even if this will expose a stack
7492 ;; use that will prevent scheduling of other stack accesses beyond this
7495 [(set (match_operand:DF 0 "register_operand" "")
7496 (match_operand:DF 1 "register_operand" ""))
7497 (use (match_operand:PSI 2 "fpscr_operand" ""))
7498 (clobber (match_scratch:SI 3 "=X"))]
7499 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7500 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7505 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7507 emit_move_insn (stack_pointer_rtx,
7508 plus_constant (Pmode, stack_pointer_rtx, -8));
7509 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7512 tos = gen_tmp_stack_mem (DFmode,
7513 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7514 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
7515 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7516 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7517 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7518 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7520 tos = gen_tmp_stack_mem (DFmode,
7521 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7522 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
7523 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7524 emit_move_insn (stack_pointer_rtx,
7525 plus_constant (Pmode, stack_pointer_rtx, 8));
7527 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7531 ;; local-alloc sometimes allocates scratch registers even when not required,
7532 ;; so we must be prepared to handle these.
7534 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7536 [(set (match_operand:DF 0 "general_movdst_operand" "")
7537 (match_operand:DF 1 "general_movsrc_operand" ""))
7538 (use (match_operand:PSI 2 "fpscr_operand" ""))
7539 (clobber (match_scratch:SI 3 ""))]
7540 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7542 && true_regnum (operands[0]) < 16
7543 && true_regnum (operands[1]) < 16"
7544 [(set (match_dup 0) (match_dup 1))]
7546 /* If this was a reg <-> mem operation with base + index reg addressing,
7547 we have to handle this in a special way. */
7548 rtx mem = operands[0];
7550 if (! memory_operand (mem, DFmode))
7555 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7556 mem = SUBREG_REG (mem);
7559 rtx addr = XEXP (mem, 0);
7560 if (GET_CODE (addr) == PLUS
7561 && REG_P (XEXP (addr, 0))
7562 && REG_P (XEXP (addr, 1)))
7565 rtx reg0 = gen_rtx_REG (Pmode, 0);
7566 rtx regop = operands[store_p], word0 ,word1;
7568 if (GET_CODE (regop) == SUBREG)
7569 alter_subreg (®op, true);
7570 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7574 mem = copy_rtx (mem);
7575 PUT_MODE (mem, SImode);
7576 word0 = gen_rtx_SUBREG (SImode, regop, 0);
7577 alter_subreg (&word0, true);
7578 word1 = gen_rtx_SUBREG (SImode, regop, 4);
7579 alter_subreg (&word1, true);
7580 if (store_p || ! refers_to_regno_p (REGNO (word0),
7581 REGNO (word0) + 1, addr, 0))
7584 ? gen_movsi_ie (mem, word0)
7585 : gen_movsi_ie (word0, mem));
7586 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7587 mem = copy_rtx (mem);
7589 ? gen_movsi_ie (mem, word1)
7590 : gen_movsi_ie (word1, mem));
7591 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7595 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7596 emit_insn (gen_movsi_ie (word1, mem));
7597 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7598 mem = copy_rtx (mem);
7599 emit_insn (gen_movsi_ie (word0, mem));
7606 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7608 [(set (match_operand:DF 0 "register_operand" "")
7609 (match_operand:DF 1 "memory_operand" ""))
7610 (use (match_operand:PSI 2 "fpscr_operand" ""))
7611 (clobber (reg:SI R0_REG))]
7612 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7613 [(parallel [(set (match_dup 0) (match_dup 1))
7615 (clobber (scratch:SI))])]
7618 (define_expand "reload_indf__frn"
7619 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7620 (match_operand:DF 1 "immediate_operand" "FQ"))
7621 (use (reg:PSI FPSCR_REG))
7622 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7626 (define_expand "reload_outdf__RnFRm"
7627 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7628 (match_operand:DF 1 "register_operand" "af,r"))
7629 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7633 ;; Simplify no-op moves.
7635 [(set (match_operand:SF 0 "register_operand" "")
7636 (match_operand:SF 1 "register_operand" ""))
7637 (use (match_operand:PSI 2 "fpscr_operand" ""))
7638 (clobber (match_scratch:SI 3 ""))]
7639 "TARGET_SH2E && reload_completed
7640 && true_regnum (operands[0]) == true_regnum (operands[1])"
7641 [(set (match_dup 0) (match_dup 0))]
7644 ;; fmovd substitute post-reload splits
7646 [(set (match_operand:DF 0 "register_operand" "")
7647 (match_operand:DF 1 "register_operand" ""))
7648 (use (match_operand:PSI 2 "fpscr_operand" ""))
7649 (clobber (match_scratch:SI 3 ""))]
7650 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7651 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7652 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7655 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7656 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7657 gen_rtx_REG (SFmode, src), operands[2]));
7658 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7659 gen_rtx_REG (SFmode, src + 1), operands[2]));
7664 [(set (match_operand:DF 0 "register_operand" "")
7665 (mem:DF (match_operand:SI 1 "register_operand" "")))
7666 (use (match_operand:PSI 2 "fpscr_operand" ""))
7667 (clobber (match_scratch:SI 3 ""))]
7668 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7669 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7670 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7673 int regno = true_regnum (operands[0]);
7675 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7677 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7678 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7679 regno + !! TARGET_LITTLE_ENDIAN),
7680 mem2, operands[2]));
7681 add_reg_note (insn, REG_INC, operands[1]);
7682 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7683 regno + ! TARGET_LITTLE_ENDIAN),
7684 change_address (mem, SFmode, NULL_RTX),
7690 [(set (match_operand:DF 0 "register_operand" "")
7691 (match_operand:DF 1 "memory_operand" ""))
7692 (use (match_operand:PSI 2 "fpscr_operand" ""))
7693 (clobber (match_scratch:SI 3 ""))]
7694 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7695 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7698 int regno = true_regnum (operands[0]);
7700 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7701 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7702 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7704 operands[1] = copy_rtx (mem2);
7705 addr = XEXP (mem2, 0);
7707 switch (GET_CODE (addr))
7710 /* This is complicated. If the register is an arithmetic register
7711 we can just fall through to the REG+DISP case below. Otherwise
7712 we have to use a combination of POST_INC and REG addressing... */
7713 if (! arith_reg_operand (operands[1], SFmode))
7715 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7716 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
7717 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7719 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7721 /* If we have modified the stack pointer, the value that we have
7722 read with post-increment might be modified by an interrupt,
7723 so write it back. */
7724 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7725 emit_insn (gen_push_e (reg0));
7727 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
7733 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7734 operands[1] = copy_rtx (operands[1]);
7735 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7736 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7740 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7741 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7743 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7744 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7756 [(set (match_operand:DF 0 "memory_operand" "")
7757 (match_operand:DF 1 "register_operand" ""))
7758 (use (match_operand:PSI 2 "fpscr_operand" ""))
7759 (clobber (match_scratch:SI 3 ""))]
7760 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7761 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7764 int regno = true_regnum (operands[1]);
7766 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7767 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7769 operands[0] = copy_rtx (operands[0]);
7770 PUT_MODE (operands[0], SFmode);
7771 addr = XEXP (operands[0], 0);
7773 switch (GET_CODE (addr))
7776 /* This is complicated. If the register is an arithmetic register
7777 we can just fall through to the REG+DISP case below. Otherwise
7778 we have to use a combination of REG and PRE_DEC addressing... */
7779 if (! arith_reg_operand (operands[0], SFmode))
7781 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
7782 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7784 operands[0] = copy_rtx (operands[0]);
7785 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
7787 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7788 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7794 /* Since REG+DISP addressing has already been decided upon by gcc
7795 we can rely upon it having chosen an arithmetic register as the
7796 register component of the address. Just emit the lower numbered
7797 register first, to the lower address, then the higher numbered
7798 register to the higher address. */
7799 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7801 operands[0] = copy_rtx (operands[0]);
7802 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
7804 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7808 /* This is easy. Output the word to go to the higher address
7809 first (ie the word in the higher numbered register) then the
7810 word to go to the lower address. */
7812 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7813 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7815 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7816 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7828 ;; If the output is a register and the input is memory or a register, we have
7829 ;; to be careful and see which word needs to be loaded first.
7832 [(set (match_operand:DF 0 "general_movdst_operand" "")
7833 (match_operand:DF 1 "general_movsrc_operand" ""))]
7834 "TARGET_SH1 && reload_completed"
7835 [(set (match_dup 2) (match_dup 3))
7836 (set (match_dup 4) (match_dup 5))]
7840 if ((MEM_P (operands[0])
7841 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7842 || (MEM_P (operands[1])
7843 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7846 switch (GET_CODE (operands[0]))
7849 regno = REGNO (operands[0]);
7852 regno = subreg_regno (operands[0]);
7862 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7864 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
7865 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
7866 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
7867 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
7871 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
7872 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
7873 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
7874 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
7877 if (operands[2] == 0 || operands[3] == 0
7878 || operands[4] == 0 || operands[5] == 0)
7882 (define_expand "movdf"
7883 [(set (match_operand:DF 0 "general_movdst_operand" "")
7884 (match_operand:DF 1 "general_movsrc_operand" ""))]
7887 prepare_move_operands (operands, DFmode);
7890 if (TARGET_SHMEDIA_FPU)
7891 emit_insn (gen_movdf_media (operands[0], operands[1]));
7893 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
7896 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
7898 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7903 ;;This is incompatible with the way gcc uses subregs.
7904 ;;(define_insn "movv2sf_i"
7905 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
7906 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
7907 ;; "TARGET_SHMEDIA_FPU
7908 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
7909 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
7913 ;; fst%M0.p %m0, %1"
7914 ;; [(set_attr "type" "*,fload_media,fstore_media")])
7916 (define_insn_and_split "movv2sf_i"
7917 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7918 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7919 "TARGET_SHMEDIA_FPU"
7921 "TARGET_SHMEDIA_FPU && reload_completed"
7922 [(set (match_dup 0) (match_dup 1))]
7924 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
7925 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
7928 (define_expand "movv2sf"
7929 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
7930 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
7931 "TARGET_SHMEDIA_FPU"
7933 prepare_move_operands (operands, V2SFmode);
7936 (define_expand "addv2sf3"
7937 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7938 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7939 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7940 "TARGET_SHMEDIA_FPU"
7942 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
7946 (define_expand "subv2sf3"
7947 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7948 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7949 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7950 "TARGET_SHMEDIA_FPU"
7952 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
7956 (define_expand "mulv2sf3"
7957 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7958 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7959 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7960 "TARGET_SHMEDIA_FPU"
7962 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
7966 (define_expand "divv2sf3"
7967 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7968 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7969 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7970 "TARGET_SHMEDIA_FPU"
7972 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
7976 (define_insn_and_split "*movv4sf_i"
7977 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7978 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7979 "TARGET_SHMEDIA_FPU"
7981 "&& reload_completed"
7986 for (i = 0; i < 4/2; i++)
7990 if (MEM_P (operands[0]))
7991 x = adjust_address (operands[0], V2SFmode,
7992 i * GET_MODE_SIZE (V2SFmode));
7994 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
7996 if (MEM_P (operands[1]))
7997 y = adjust_address (operands[1], V2SFmode,
7998 i * GET_MODE_SIZE (V2SFmode));
8000 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8002 emit_insn (gen_movv2sf_i (x, y));
8007 [(set_attr "length" "8")])
8009 (define_expand "movv4sf"
8010 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8011 (match_operand:V4SF 1 "general_operand" ""))]
8012 "TARGET_SHMEDIA_FPU"
8014 prepare_move_operands (operands, V4SFmode);
8017 (define_insn_and_split "*movv16sf_i"
8018 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8019 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8020 "TARGET_SHMEDIA_FPU"
8022 "&& reload_completed"
8027 for (i = 0; i < 16/2; i++)
8031 if (MEM_P (operands[0]))
8032 x = adjust_address (operands[0], V2SFmode,
8033 i * GET_MODE_SIZE (V2SFmode));
8036 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8037 alter_subreg (&x, true);
8040 if (MEM_P (operands[1]))
8041 y = adjust_address (operands[1], V2SFmode,
8042 i * GET_MODE_SIZE (V2SFmode));
8045 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8046 alter_subreg (&y, true);
8049 emit_insn (gen_movv2sf_i (x, y));
8054 [(set_attr "length" "32")])
8056 (define_expand "movv16sf"
8057 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8058 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8059 "TARGET_SHMEDIA_FPU"
8061 prepare_move_operands (operands, V16SFmode);
8064 (define_insn "movsf_media"
8065 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8066 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8068 && (register_operand (operands[0], SFmode)
8069 || sh_register_operand (operands[1], SFmode))"
8080 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8081 (set (attr "highpart")
8082 (cond [(match_test "sh_contains_memref_p (insn)")
8083 (const_string "user")]
8084 (const_string "ignore")))])
8086 (define_insn "movsf_media_nofpu"
8087 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8088 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8090 && (register_operand (operands[0], SFmode)
8091 || sh_register_operand (operands[1], SFmode))"
8097 [(set_attr "type" "arith_media,*,load_media,store_media")
8098 (set (attr "highpart")
8099 (cond [(match_test "sh_contains_memref_p (insn)")
8100 (const_string "user")]
8101 (const_string "ignore")))])
8104 [(set (match_operand:SF 0 "arith_reg_dest" "")
8105 (match_operand:SF 1 "immediate_operand" ""))]
8106 "TARGET_SHMEDIA && reload_completed
8107 && ! FP_REGISTER_P (true_regnum (operands[0]))"
8108 [(set (match_dup 3) (match_dup 2))]
8111 REAL_VALUE_TYPE value;
8113 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
8114 REAL_VALUE_TO_TARGET_SINGLE (value, values);
8115 operands[2] = GEN_INT (values);
8117 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8120 (define_insn "movsf_i"
8121 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8122 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
8125 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8126 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8127 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8128 && (arith_reg_operand (operands[0], SFmode)
8129 || arith_reg_operand (operands[1], SFmode))"
8138 [(set_attr "type" "move,move,pcload,load,store,move,move")])
8140 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8141 ;; update_flow_info would not know where to put REG_EQUAL notes
8142 ;; when the destination changes mode.
8143 (define_insn "movsf_ie"
8144 [(set (match_operand:SF 0 "general_movdst_operand"
8145 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8146 (match_operand:SF 1 "general_movsrc_operand"
8147 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8148 (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"))
8149 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8151 && (arith_reg_operand (operands[0], SFmode)
8152 || arith_reg_operand (operands[1], SFmode)
8153 || arith_reg_operand (operands[3], SImode)
8154 || (fpul_operand (operands[0], SFmode)
8155 && memory_operand (operands[1], SFmode)
8156 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
8157 || (fpul_operand (operands[1], SFmode)
8158 && memory_operand (operands[0], SFmode)
8159 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
8179 ! move optimized away"
8180 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8181 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8182 (set_attr_alternative "length"
8189 (match_test "TARGET_SH2A")
8190 (const_int 4) (const_int 2))
8192 (match_test "TARGET_SH2A")
8193 (const_int 4) (const_int 2))
8196 (match_test "TARGET_SH2A")
8197 (const_int 4) (const_int 2))
8199 (match_test "TARGET_SH2A")
8200 (const_int 4) (const_int 2))
8210 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
8211 (const_string "single")
8212 (const_string "single")))])
8215 [(set (match_operand:SF 0 "register_operand" "")
8216 (match_operand:SF 1 "register_operand" ""))
8217 (use (match_operand:PSI 2 "fpscr_operand" ""))
8218 (clobber (reg:SI FPUL_REG))]
8220 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8222 (clobber (scratch:SI))])
8223 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8225 (clobber (scratch:SI))])]
8228 (define_expand "movsf"
8229 [(set (match_operand:SF 0 "general_movdst_operand" "")
8230 (match_operand:SF 1 "general_movsrc_operand" ""))]
8233 prepare_move_operands (operands, SFmode);
8236 if (TARGET_SHMEDIA_FPU)
8237 emit_insn (gen_movsf_media (operands[0], operands[1]));
8239 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8244 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
8249 (define_insn "mov_nop"
8250 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8253 [(set_attr "length" "0")
8254 (set_attr "type" "nil")])
8256 (define_expand "reload_insf__frn"
8257 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8258 (match_operand:SF 1 "immediate_operand" "FQ"))
8259 (use (reg:PSI FPSCR_REG))
8260 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8264 (define_expand "reload_insi__i_fpul"
8265 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8266 (match_operand:SI 1 "immediate_operand" "i"))
8267 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8271 (define_expand "ptabs"
8272 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8275 if (!TARGET_PT_FIXED)
8277 rtx eq = operands[1];
8279 /* ??? For canonical RTL we really should remove any CONST from EQ
8280 before wrapping it in the AND, and finally wrap the EQ into a
8281 const if is constant. However, for reload we must expose the
8282 input register or symbolic constant, and we can't have
8283 different insn structures outside of the operands for different
8284 alternatives of the same pattern. */
8285 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8288 = (gen_rtx_IF_THEN_ELSE
8291 gen_rtx_MEM (PDImode, operands[1]),
8292 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8293 PDImode, operands[1])));
8297 ;; expanded by ptabs expander.
8298 (define_insn "*extendsipdi_media"
8299 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8300 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8304 (mem:PDI (match_dup 1))
8305 (sign_extend:PDI (match_dup 1))))]
8306 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8310 [(set_attr "type" "ptabs_media,pt_media")
8311 (set_attr "length" "4,*")])
8313 (define_insn "*truncdipdi_media"
8314 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8315 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8319 (mem:PDI (match_dup 1))
8320 (truncate:PDI (match_dup 1))))]
8321 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8325 [(set_attr "type" "ptabs_media,pt_media")
8326 (set_attr "length" "4,*")])
8328 (define_insn "*movsi_y"
8329 [(set (match_operand:SI 0 "register_operand" "=y,y")
8330 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8331 (clobber (match_scratch:SI 2 "=&z,r"))]
8333 && (reload_in_progress || reload_completed)"
8335 [(set_attr "length" "4")
8336 (set_attr "type" "pcload,move")])
8339 [(set (match_operand:SI 0 "register_operand" "")
8340 (match_operand:SI 1 "immediate_operand" ""))
8341 (clobber (match_operand:SI 2 "register_operand" ""))]
8343 [(set (match_dup 2) (match_dup 1))
8344 (set (match_dup 0) (match_dup 2))]
8347 ;; ------------------------------------------------------------------------
8348 ;; Define the real conditional branch instructions.
8349 ;; ------------------------------------------------------------------------
8351 (define_expand "branch_true"
8352 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8353 (label_ref (match_operand 0))
8357 (define_expand "branch_false"
8358 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8359 (label_ref (match_operand 0))
8363 (define_insn_and_split "*cbranch_t"
8364 [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8365 (label_ref (match_operand 0))
8369 return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8372 [(set (pc) (if_then_else (eq (reg:SI T_REG) (match_dup 2))
8373 (label_ref (match_dup 0))
8376 /* Try to find missed test and branch combine opportunities which result
8377 in redundant T bit tests before conditional branches.
8378 This is done not only after combine (and before reload) but in every
8379 split pass, because some opportunities are formed also after combine.
8380 FIXME: Probably this would not be needed if CCmode was used
8381 together with TARGET_FIXED_CONDITION_CODE_REGS. */
8383 const int treg_value = sh_eval_treg_value (operands[1]);
8384 operands[2] = NULL_RTX;
8386 /* Scan the insns backwards for an insn that sets the T bit by testing a
8387 reg against zero like:
8388 (set (reg T_REG) (eq (reg) (const_int 0))) */
8389 rtx testing_insn = NULL_RTX;
8390 rtx tested_reg = NULL_RTX;
8392 set_of_reg s0 = sh_find_set_of_reg (get_t_reg_rtx (), curr_insn,
8393 prev_nonnote_insn_bb);
8394 if (s0.set_src != NULL_RTX
8395 && GET_CODE (s0.set_src) == EQ
8396 && REG_P (XEXP (s0.set_src, 0))
8397 && satisfies_constraint_Z (XEXP (s0.set_src, 1)))
8399 testing_insn = s0.insn;
8400 tested_reg = XEXP (s0.set_src, 0);
8405 /* Continue scanning the insns backwards and try to find the insn that
8406 sets the tested reg which we found above. If the reg is set by storing
8407 the T bit or the negated T bit we can eliminate the test insn before
8408 the branch. Notice that the branch condition has to be inverted if the
8409 test is eliminated. */
8411 /* If the T bit is used between the testing insn and the brach insn
8413 if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
8418 /* It's not safe to go beyond the current basic block after reload. */
8419 set_of_reg s1 = sh_find_set_of_reg (tested_reg, s0.insn,
8421 ? prev_nonnote_insn_bb
8422 : prev_nonnote_insn);
8423 if (s1.set_src == NULL_RTX)
8426 if (t_reg_operand (s1.set_src, VOIDmode))
8427 operands[2] = GEN_INT (treg_value ^ 1);
8428 else if (negt_reg_operand (s1.set_src, VOIDmode))
8429 operands[2] = GEN_INT (treg_value);
8430 else if (REG_P (s1.set_src))
8432 /* If it's a reg-reg copy follow the copied reg. This can
8433 happen e.g. when T bit store zero-extensions are
8435 tested_reg = s1.set_src;
8440 /* It's only safe to remove the testing insn if the T bit is not
8441 modified between the testing insn and the insn that stores the
8442 T bit. Notice that some T bit stores such as negc also modify
8444 if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
8445 || modified_in_p (get_t_reg_rtx (), s1.insn))
8446 operands[2] = NULL_RTX;
8451 if (operands[2] == NULL_RTX)
8454 set_insn_deleted (testing_insn);
8456 [(set_attr "type" "cbranch")])
8458 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8459 ;; which destination is too far away.
8460 ;; The const_int_operand is distinct for each branch target; it avoids
8461 ;; unwanted matches with redundant_insn.
8462 (define_insn "block_branch_redirect"
8463 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8466 [(set_attr "length" "0")])
8468 ;; This one has the additional purpose to record a possible scratch register
8469 ;; for the following branch.
8470 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8471 ;; because the insn then might be deemed dead and deleted. And we can't
8472 ;; make the use in the jump insn explicit because that would disable
8473 ;; delay slot scheduling from the target.
8474 (define_insn "indirect_jump_scratch"
8475 [(set (match_operand:SI 0 "register_operand" "=r")
8476 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8477 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8480 [(set_attr "length" "0")])
8482 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8483 ;; being pulled into the delay slot of a condbranch that has been made to
8484 ;; jump around the unconditional jump because it was out of range.
8485 (define_insn "stuff_delay_slot"
8487 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8488 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8491 [(set_attr "length" "0")
8492 (set_attr "cond_delay_slot" "yes")])
8494 ;; Conditional branch insns
8496 (define_expand "cbranchint4_media"
8498 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8499 [(match_operand 1 "" "")
8500 (match_operand 2 "" "")])
8501 (match_operand 3 "" "")
8505 enum machine_mode mode = GET_MODE (operands[1]);
8506 if (mode == VOIDmode)
8507 mode = GET_MODE (operands[2]);
8508 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8510 operands[1] = force_reg (mode, operands[1]);
8511 if (CONSTANT_P (operands[2])
8512 && (! satisfies_constraint_I06 (operands[2])))
8513 operands[2] = force_reg (mode, operands[2]);
8517 if (operands[1] != const0_rtx)
8518 operands[1] = force_reg (mode, operands[1]);
8519 if (operands[2] != const0_rtx)
8520 operands[2] = force_reg (mode, operands[2]);
8522 switch (GET_CODE (operands[0]))
8528 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8529 VOIDmode, operands[2], operands[1]);
8530 operands[1] = XEXP (operands[0], 0);
8531 operands[2] = XEXP (operands[0], 1);
8534 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8535 VOIDmode, operands[1], operands[2]);
8538 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8541 (define_expand "cbranchfp4_media"
8543 (if_then_else (match_operator 0 "sh_float_comparison_operator"
8544 [(match_operand 1 "" "")
8545 (match_operand 2 "" "")])
8546 (match_operand 3 "" "")
8550 rtx tmp = gen_reg_rtx (SImode);
8552 if (GET_CODE (operands[0]) == NE)
8553 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8555 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8556 operands[1], operands[2]);
8558 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8560 if (GET_CODE (cmp) == GET_CODE (operands[0]))
8561 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8563 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8565 operands[2] = const0_rtx;
8566 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8569 (define_insn "*beq_media_i"
8571 (if_then_else (match_operator 3 "equality_comparison_operator"
8572 [(match_operand:DI 1 "arith_reg_operand" "r,r")
8573 (match_operand:DI 2 "arith_operand" "r,I06")])
8574 (match_operand 0 "target_operand" "b,b")
8579 b%o3i%' %1, %2, %0%>"
8580 [(set_attr "type" "cbranch_media")])
8582 (define_insn "*beq_media_i32"
8584 (if_then_else (match_operator 3 "equality_comparison_operator"
8585 [(match_operand:SI 1 "arith_reg_operand" "r,r")
8586 (match_operand:SI 2 "arith_operand" "r,I06")])
8587 (match_operand 0 "target_operand" "b,b")
8592 b%o3i%' %1, %2, %0%>"
8593 [(set_attr "type" "cbranch_media")])
8595 (define_insn "*bgt_media_i"
8597 (if_then_else (match_operator 3 "greater_comparison_operator"
8598 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8599 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8600 (match_operand 0 "target_operand" "b")
8603 "b%o3%' %N1, %N2, %0%>"
8604 [(set_attr "type" "cbranch_media")])
8606 (define_insn "*bgt_media_i32"
8608 (if_then_else (match_operator 3 "greater_comparison_operator"
8609 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8610 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8611 (match_operand 0 "target_operand" "b")
8614 "b%o3%' %N1, %N2, %0%>"
8615 [(set_attr "type" "cbranch_media")])
8617 ;; These are only needed to make invert_jump() happy - otherwise, jump
8618 ;; optimization will be silently disabled.
8619 (define_insn "*blt_media_i"
8621 (if_then_else (match_operator 3 "less_comparison_operator"
8622 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8623 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8624 (match_operand 0 "target_operand" "b")
8627 "b%o3%' %N2, %N1, %0%>"
8628 [(set_attr "type" "cbranch_media")])
8630 (define_insn "*blt_media_i32"
8632 (if_then_else (match_operator 3 "less_comparison_operator"
8633 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8634 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8635 (match_operand 0 "target_operand" "b")
8638 "b%o3%' %N2, %N1, %0%>"
8639 [(set_attr "type" "cbranch_media")])
8641 ;; combiner splitter for test-and-branch on single bit in register. This
8642 ;; is endian dependent because the non-paradoxical subreg looks different
8647 (match_operator 3 "equality_comparison_operator"
8648 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
8649 "extend_reg_operand" "")
8653 "const_int_operand" "")) 0)
8655 (match_operand 0 "target_operand" "")
8657 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8658 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8659 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8660 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8662 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8663 operands[6] = (GET_CODE (operands[3]) == EQ
8664 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8665 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8668 ; operand 0 is the loop count pseudo register
8669 ; operand 1 is the number of loop iterations or 0 if it is unknown
8670 ; operand 2 is the maximum number of loop iterations
8671 ; operand 3 is the number of levels of enclosed loops
8672 ; operand 4 is the label to jump to at the top of the loop
8674 (define_expand "doloop_end"
8675 [(parallel [(set (pc) (if_then_else
8676 (ne:SI (match_operand:SI 0 "" "")
8678 (label_ref (match_operand 4 "" ""))
8681 (plus:SI (match_dup 0) (const_int -1)))
8682 (clobber (reg:SI T_REG))])
8683 (match_operand 5 "" "")]
8686 if (GET_MODE (operands[0]) != SImode)
8688 emit_jump_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
8692 (define_insn_and_split "doloop_end_split"
8694 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8696 (label_ref (match_operand 1 "" ""))
8698 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8699 (plus (match_dup 2) (const_int -1)))
8700 (clobber (reg:SI T_REG))]
8704 [(parallel [(set (reg:SI T_REG)
8705 (eq:SI (match_dup 2) (const_int 1)))
8706 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8707 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8708 (label_ref (match_dup 1))
8711 [(set_attr "type" "cbranch")])
8714 ;; ------------------------------------------------------------------------
8715 ;; Jump and linkage insns
8716 ;; ------------------------------------------------------------------------
8718 (define_insn "jump_compact"
8720 (label_ref (match_operand 0 "" "")))]
8721 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
8723 /* The length is 16 if the delay slot is unfilled. */
8724 if (get_attr_length(insn) > 4)
8725 return output_far_jump(insn, operands[0]);
8729 [(set_attr "type" "jump")
8730 (set_attr "needs_delay_slot" "yes")])
8732 ;; ??? It would be much saner to explicitly use the scratch register
8733 ;; in the jump insn, and have indirect_jump_scratch only set it,
8734 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8735 ;; from the target then, as it uses simplejump_p.
8736 ;;(define_insn "jump_compact_far"
8738 ;; (label_ref (match_operand 0 "" "")))
8739 ;; (use (match_operand 1 "register_operand" "r")]
8741 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
8742 ;; [(set_attr "type" "jump")
8743 ;; (set_attr "needs_delay_slot" "yes")])
8745 (define_insn "jump_media"
8747 (match_operand 0 "target_operand" "b"))]
8750 [(set_attr "type" "jump_media")])
8752 (define_expand "jump"
8754 (label_ref (match_operand 0 "" "")))]
8758 emit_jump_insn (gen_jump_compact (operands[0]));
8759 else if (TARGET_SHMEDIA)
8761 if (reload_in_progress || reload_completed)
8763 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
8769 (define_insn "force_mode_for_call"
8770 [(use (reg:PSI FPSCR_REG))]
8773 [(set_attr "length" "0")
8774 (set (attr "fp_mode")
8775 (if_then_else (eq_attr "fpu_single" "yes")
8776 (const_string "single") (const_string "double")))])
8778 (define_insn "calli"
8779 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8780 (match_operand 1 "" ""))
8781 (use (reg:PSI FPSCR_REG))
8782 (clobber (reg:SI PR_REG))]
8785 if (TARGET_SH2A && (dbr_sequence_length () == 0))
8790 [(set_attr "type" "call")
8791 (set (attr "fp_mode")
8792 (if_then_else (eq_attr "fpu_single" "yes")
8793 (const_string "single") (const_string "double")))
8794 (set_attr "needs_delay_slot" "yes")
8795 (set_attr "fp_set" "unknown")])
8797 ;; This is TBR relative jump instruction for SH2A architecture.
8798 ;; Its use is enabled assigning an attribute "function_vector"
8799 ;; and the vector number to a function during its declaration.
8801 (define_insn "calli_tbr_rel"
8802 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
8803 (match_operand 1 "" ""))
8804 (use (reg:PSI FPSCR_REG))
8805 (clobber (reg:SI PR_REG))]
8806 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
8808 unsigned HOST_WIDE_INT vect_num;
8809 vect_num = sh2a_get_function_vector_number (operands[0]);
8810 operands[2] = GEN_INT (vect_num * 4);
8812 return "jsr/n @@(%O2,tbr)";
8814 [(set_attr "type" "call")
8815 (set (attr "fp_mode")
8816 (if_then_else (eq_attr "fpu_single" "yes")
8817 (const_string "single") (const_string "double")))
8818 (set_attr "needs_delay_slot" "no")
8819 (set_attr "fp_set" "unknown")])
8821 ;; This is a pc-rel call, using bsrf, for use with PIC.
8823 (define_insn "calli_pcrel"
8824 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8825 (match_operand 1 "" ""))
8826 (use (reg:PSI FPSCR_REG))
8827 (use (reg:SI PIC_REG))
8828 (use (match_operand 2 "" ""))
8829 (clobber (reg:SI PR_REG))]
8832 return "bsrf %0" "\n"
8835 [(set_attr "type" "call")
8836 (set (attr "fp_mode")
8837 (if_then_else (eq_attr "fpu_single" "yes")
8838 (const_string "single") (const_string "double")))
8839 (set_attr "needs_delay_slot" "yes")
8840 (set_attr "fp_set" "unknown")])
8842 (define_insn_and_split "call_pcrel"
8843 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8844 (match_operand 1 "" ""))
8845 (use (reg:PSI FPSCR_REG))
8846 (use (reg:SI PIC_REG))
8847 (clobber (reg:SI PR_REG))
8848 (clobber (match_scratch:SI 2 "=r"))]
8854 rtx lab = PATTERN (gen_call_site ());
8856 if (SYMBOL_REF_LOCAL_P (operands[0]))
8857 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8859 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
8860 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
8863 [(set_attr "type" "call")
8864 (set (attr "fp_mode")
8865 (if_then_else (eq_attr "fpu_single" "yes")
8866 (const_string "single") (const_string "double")))
8867 (set_attr "needs_delay_slot" "yes")
8868 (set_attr "fp_set" "unknown")])
8870 (define_insn "call_compact"
8871 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8872 (match_operand 1 "" ""))
8873 (match_operand 2 "immediate_operand" "n")
8874 (use (reg:SI R0_REG))
8875 (use (reg:SI R1_REG))
8876 (use (reg:PSI FPSCR_REG))
8877 (clobber (reg:SI PR_REG))]
8878 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8880 [(set_attr "type" "call")
8881 (set (attr "fp_mode")
8882 (if_then_else (eq_attr "fpu_single" "yes")
8883 (const_string "single") (const_string "double")))
8884 (set_attr "needs_delay_slot" "yes")])
8886 (define_insn "call_compact_rettramp"
8887 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8888 (match_operand 1 "" ""))
8889 (match_operand 2 "immediate_operand" "n")
8890 (use (reg:SI R0_REG))
8891 (use (reg:SI R1_REG))
8892 (use (reg:PSI FPSCR_REG))
8893 (clobber (reg:SI R10_REG))
8894 (clobber (reg:SI PR_REG))]
8895 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8897 [(set_attr "type" "call")
8898 (set (attr "fp_mode")
8899 (if_then_else (eq_attr "fpu_single" "yes")
8900 (const_string "single") (const_string "double")))
8901 (set_attr "needs_delay_slot" "yes")])
8903 (define_insn "call_media"
8904 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
8905 (match_operand 1 "" ""))
8906 (clobber (reg:DI PR_MEDIA_REG))]
8909 [(set_attr "type" "jump_media")])
8911 (define_insn "call_valuei"
8912 [(set (match_operand 0 "" "=rf")
8913 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8914 (match_operand 2 "" "")))
8915 (use (reg:PSI FPSCR_REG))
8916 (clobber (reg:SI PR_REG))]
8919 if (TARGET_SH2A && (dbr_sequence_length () == 0))
8924 [(set_attr "type" "call")
8925 (set (attr "fp_mode")
8926 (if_then_else (eq_attr "fpu_single" "yes")
8927 (const_string "single") (const_string "double")))
8928 (set_attr "needs_delay_slot" "yes")
8929 (set_attr "fp_set" "unknown")])
8931 ;; This is TBR relative jump instruction for SH2A architecture.
8932 ;; Its use is enabled by assigning an attribute "function_vector"
8933 ;; and the vector number to a function during its declaration.
8935 (define_insn "call_valuei_tbr_rel"
8936 [(set (match_operand 0 "" "=rf")
8937 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8938 (match_operand 2 "" "")))
8939 (use (reg:PSI FPSCR_REG))
8940 (clobber (reg:SI PR_REG))]
8941 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
8943 unsigned HOST_WIDE_INT vect_num;
8944 vect_num = sh2a_get_function_vector_number (operands[1]);
8945 operands[3] = GEN_INT (vect_num * 4);
8947 return "jsr/n @@(%O3,tbr)";
8949 [(set_attr "type" "call")
8950 (set (attr "fp_mode")
8951 (if_then_else (eq_attr "fpu_single" "yes")
8952 (const_string "single") (const_string "double")))
8953 (set_attr "needs_delay_slot" "no")
8954 (set_attr "fp_set" "unknown")])
8956 (define_insn "call_valuei_pcrel"
8957 [(set (match_operand 0 "" "=rf")
8958 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8959 (match_operand 2 "" "")))
8960 (use (reg:PSI FPSCR_REG))
8961 (use (reg:SI PIC_REG))
8962 (use (match_operand 3 "" ""))
8963 (clobber (reg:SI PR_REG))]
8966 return "bsrf %1" "\n"
8969 [(set_attr "type" "call")
8970 (set (attr "fp_mode")
8971 (if_then_else (eq_attr "fpu_single" "yes")
8972 (const_string "single") (const_string "double")))
8973 (set_attr "needs_delay_slot" "yes")
8974 (set_attr "fp_set" "unknown")])
8976 (define_insn_and_split "call_value_pcrel"
8977 [(set (match_operand 0 "" "=rf")
8978 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8979 (match_operand 2 "" "")))
8980 (use (reg:PSI FPSCR_REG))
8981 (use (reg:SI PIC_REG))
8982 (clobber (reg:SI PR_REG))
8983 (clobber (match_scratch:SI 3 "=r"))]
8989 rtx lab = PATTERN (gen_call_site ());
8991 if (SYMBOL_REF_LOCAL_P (operands[1]))
8992 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8994 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
8995 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
8996 operands[2], copy_rtx (lab)));
8999 [(set_attr "type" "call")
9000 (set (attr "fp_mode")
9001 (if_then_else (eq_attr "fpu_single" "yes")
9002 (const_string "single") (const_string "double")))
9003 (set_attr "needs_delay_slot" "yes")
9004 (set_attr "fp_set" "unknown")])
9006 (define_insn "call_value_compact"
9007 [(set (match_operand 0 "" "=rf")
9008 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9009 (match_operand 2 "" "")))
9010 (match_operand 3 "immediate_operand" "n")
9011 (use (reg:SI R0_REG))
9012 (use (reg:SI R1_REG))
9013 (use (reg:PSI FPSCR_REG))
9014 (clobber (reg:SI PR_REG))]
9015 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9017 [(set_attr "type" "call")
9018 (set (attr "fp_mode")
9019 (if_then_else (eq_attr "fpu_single" "yes")
9020 (const_string "single") (const_string "double")))
9021 (set_attr "needs_delay_slot" "yes")])
9023 (define_insn "call_value_compact_rettramp"
9024 [(set (match_operand 0 "" "=rf")
9025 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9026 (match_operand 2 "" "")))
9027 (match_operand 3 "immediate_operand" "n")
9028 (use (reg:SI R0_REG))
9029 (use (reg:SI R1_REG))
9030 (use (reg:PSI FPSCR_REG))
9031 (clobber (reg:SI R10_REG))
9032 (clobber (reg:SI PR_REG))]
9033 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9035 [(set_attr "type" "call")
9036 (set (attr "fp_mode")
9037 (if_then_else (eq_attr "fpu_single" "yes")
9038 (const_string "single") (const_string "double")))
9039 (set_attr "needs_delay_slot" "yes")])
9041 (define_insn "call_value_media"
9042 [(set (match_operand 0 "" "=rf")
9043 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9044 (match_operand 2 "" "")))
9045 (clobber (reg:DI PR_MEDIA_REG))]
9048 [(set_attr "type" "jump_media")])
9050 (define_expand "call"
9051 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9052 (match_operand 1 "" ""))
9053 (match_operand 2 "" "")
9054 (use (reg:PSI FPSCR_REG))
9055 (clobber (reg:SI PR_REG))])]
9060 operands[0] = shmedia_prepare_call_address (operands[0], 0);
9061 emit_call_insn (gen_call_media (operands[0], operands[1]));
9064 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9066 rtx cookie_rtx = operands[2];
9067 long cookie = INTVAL (cookie_rtx);
9068 rtx func = XEXP (operands[0], 0);
9073 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9075 rtx reg = gen_reg_rtx (Pmode);
9077 emit_insn (gen_symGOTPLT2reg (reg, func));
9081 func = legitimize_pic_address (func, Pmode, 0);
9084 r0 = gen_rtx_REG (SImode, R0_REG);
9085 r1 = gen_rtx_REG (SImode, R1_REG);
9087 /* Since such a call function may use all call-clobbered
9088 registers, we force a mode switch earlier, so that we don't
9089 run out of registers when adjusting fpscr for the call. */
9090 emit_insn (gen_force_mode_for_call ());
9093 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9094 operands[0] = force_reg (SImode, operands[0]);
9096 emit_move_insn (r0, func);
9097 emit_move_insn (r1, cookie_rtx);
9099 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9100 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9103 emit_call_insn (gen_call_compact (operands[0], operands[1],
9108 else if (TARGET_SHCOMPACT && flag_pic
9109 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9110 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9112 rtx reg = gen_reg_rtx (Pmode);
9114 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9115 XEXP (operands[0], 0) = reg;
9117 if (!flag_pic && TARGET_SH2A
9118 && MEM_P (operands[0])
9119 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9121 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9123 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9128 if (flag_pic && TARGET_SH2
9129 && MEM_P (operands[0])
9130 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9132 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9137 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9138 operands[1] = operands[2];
9141 emit_call_insn (gen_calli (operands[0], operands[1]));
9145 (define_insn "call_pop_compact"
9146 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9147 (match_operand 1 "" ""))
9148 (match_operand 2 "immediate_operand" "n")
9149 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9150 (match_operand 3 "immediate_operand" "n")))
9151 (use (reg:SI R0_REG))
9152 (use (reg:SI R1_REG))
9153 (use (reg:PSI FPSCR_REG))
9154 (clobber (reg:SI PR_REG))]
9155 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9157 [(set_attr "type" "call")
9158 (set (attr "fp_mode")
9159 (if_then_else (eq_attr "fpu_single" "yes")
9160 (const_string "single") (const_string "double")))
9161 (set_attr "needs_delay_slot" "yes")])
9163 (define_insn "call_pop_compact_rettramp"
9164 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9165 (match_operand 1 "" ""))
9166 (match_operand 2 "immediate_operand" "n")
9167 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9168 (match_operand 3 "immediate_operand" "n")))
9169 (use (reg:SI R0_REG))
9170 (use (reg:SI R1_REG))
9171 (use (reg:PSI FPSCR_REG))
9172 (clobber (reg:SI R10_REG))
9173 (clobber (reg:SI PR_REG))]
9174 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9176 [(set_attr "type" "call")
9177 (set (attr "fp_mode")
9178 (if_then_else (eq_attr "fpu_single" "yes")
9179 (const_string "single") (const_string "double")))
9180 (set_attr "needs_delay_slot" "yes")])
9182 (define_expand "call_pop"
9183 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9184 (match_operand 1 "" ""))
9185 (match_operand 2 "" "")
9186 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9187 (match_operand 3 "" "")))])]
9195 gcc_assert (operands[2] && INTVAL (operands[2]));
9196 cookie_rtx = operands[2];
9197 cookie = INTVAL (cookie_rtx);
9198 func = XEXP (operands[0], 0);
9202 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9204 rtx reg = gen_reg_rtx (Pmode);
9205 emit_insn (gen_symGOTPLT2reg (reg, func));
9209 func = legitimize_pic_address (func, Pmode, 0);
9212 r0 = gen_rtx_REG (SImode, R0_REG);
9213 r1 = gen_rtx_REG (SImode, R1_REG);
9215 /* Since such a call function may use all call-clobbered
9216 registers, we force a mode switch earlier, so that we don't
9217 run out of registers when adjusting fpscr for the call. */
9218 emit_insn (gen_force_mode_for_call ());
9220 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9222 operands[0] = force_reg (SImode, operands[0]);
9224 emit_move_insn (r0, func);
9225 emit_move_insn (r1, cookie_rtx);
9227 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9228 emit_call_insn (gen_call_pop_compact_rettramp
9229 (operands[0], operands[1], operands[2], operands[3]));
9231 emit_call_insn (gen_call_pop_compact
9232 (operands[0], operands[1], operands[2], operands[3]));
9237 (define_expand "call_value"
9238 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9239 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9240 (match_operand 2 "" "")))
9241 (match_operand 3 "" "")
9242 (use (reg:PSI FPSCR_REG))
9243 (clobber (reg:SI PR_REG))])]
9248 operands[1] = shmedia_prepare_call_address (operands[1], 0);
9249 emit_call_insn (gen_call_value_media (operands[0], operands[1],
9253 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9255 rtx cookie_rtx = operands[3];
9256 long cookie = INTVAL (cookie_rtx);
9257 rtx func = XEXP (operands[1], 0);
9262 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9264 rtx reg = gen_reg_rtx (Pmode);
9266 emit_insn (gen_symGOTPLT2reg (reg, func));
9270 func = legitimize_pic_address (func, Pmode, 0);
9273 r0 = gen_rtx_REG (SImode, R0_REG);
9274 r1 = gen_rtx_REG (SImode, R1_REG);
9276 /* Since such a call function may use all call-clobbered
9277 registers, we force a mode switch earlier, so that we don't
9278 run out of registers when adjusting fpscr for the call. */
9279 emit_insn (gen_force_mode_for_call ());
9282 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9283 operands[1] = force_reg (SImode, operands[1]);
9285 emit_move_insn (r0, func);
9286 emit_move_insn (r1, cookie_rtx);
9288 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9289 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9294 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9295 operands[2], operands[3]));
9299 else if (TARGET_SHCOMPACT && flag_pic
9300 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9301 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9303 rtx reg = gen_reg_rtx (Pmode);
9305 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9306 XEXP (operands[1], 0) = reg;
9308 if (!flag_pic && TARGET_SH2A
9309 && MEM_P (operands[1])
9310 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9312 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9314 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9315 XEXP (operands[1], 0), operands[2]));
9319 if (flag_pic && TARGET_SH2
9320 && MEM_P (operands[1])
9321 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9323 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9328 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9330 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9334 (define_insn "sibcalli"
9335 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9336 (match_operand 1 "" ""))
9337 (use (reg:PSI FPSCR_REG))
9341 [(set_attr "needs_delay_slot" "yes")
9342 (set (attr "fp_mode")
9343 (if_then_else (eq_attr "fpu_single" "yes")
9344 (const_string "single") (const_string "double")))
9345 (set_attr "type" "jump_ind")])
9347 (define_insn "sibcalli_pcrel"
9348 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9349 (match_operand 1 "" ""))
9350 (use (match_operand 2 "" ""))
9351 (use (reg:PSI FPSCR_REG))
9355 return "braf %0" "\n"
9358 [(set_attr "needs_delay_slot" "yes")
9359 (set (attr "fp_mode")
9360 (if_then_else (eq_attr "fpu_single" "yes")
9361 (const_string "single") (const_string "double")))
9362 (set_attr "type" "jump_ind")])
9364 ;; This uses an unspec to describe that the symbol_ref is very close.
9365 (define_insn "sibcalli_thunk"
9366 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9368 (match_operand 1 "" ""))
9369 (use (reg:PSI FPSCR_REG))
9373 [(set_attr "needs_delay_slot" "yes")
9374 (set (attr "fp_mode")
9375 (if_then_else (eq_attr "fpu_single" "yes")
9376 (const_string "single") (const_string "double")))
9377 (set_attr "type" "jump")
9378 (set_attr "length" "2")])
9380 (define_insn_and_split "sibcall_pcrel"
9381 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9382 (match_operand 1 "" ""))
9383 (use (reg:PSI FPSCR_REG))
9384 (clobber (match_scratch:SI 2 "=k"))
9391 rtx lab = PATTERN (gen_call_site ());
9394 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9395 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9397 SIBLING_CALL_P (call_insn) = 1;
9400 [(set_attr "needs_delay_slot" "yes")
9401 (set (attr "fp_mode")
9402 (if_then_else (eq_attr "fpu_single" "yes")
9403 (const_string "single") (const_string "double")))
9404 (set_attr "type" "jump_ind")])
9406 (define_insn "sibcall_compact"
9407 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9408 (match_operand 1 "" ""))
9410 (use (match_operand:SI 2 "register_operand" "z,x"))
9411 (use (reg:SI R1_REG))
9412 (use (reg:PSI FPSCR_REG))
9413 ;; We want to make sure the `x' above will only match MACH_REG
9414 ;; because sibcall_epilogue may clobber MACL_REG.
9415 (clobber (reg:SI MACL_REG))]
9418 static const char* alt[] =
9425 return alt[which_alternative];
9427 [(set_attr "needs_delay_slot" "yes,no")
9428 (set_attr "length" "2,4")
9429 (set (attr "fp_mode") (const_string "single"))
9430 (set_attr "type" "jump_ind")])
9432 (define_insn "sibcall_media"
9433 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9434 (match_operand 1 "" ""))
9435 (use (reg:SI PR_MEDIA_REG))
9439 [(set_attr "type" "jump_media")])
9441 (define_expand "sibcall"
9443 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9444 (match_operand 1 "" ""))
9445 (match_operand 2 "" "")
9446 (use (reg:PSI FPSCR_REG))
9452 operands[0] = shmedia_prepare_call_address (operands[0], 1);
9453 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9456 else if (TARGET_SHCOMPACT && operands[2]
9457 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9459 rtx cookie_rtx = operands[2];
9460 long cookie = INTVAL (cookie_rtx);
9461 rtx func = XEXP (operands[0], 0);
9466 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9468 rtx reg = gen_reg_rtx (Pmode);
9470 emit_insn (gen_symGOT2reg (reg, func));
9474 func = legitimize_pic_address (func, Pmode, 0);
9477 /* FIXME: if we could tell whether all argument registers are
9478 already taken, we could decide whether to force the use of
9479 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9480 simple way to tell. We could use the CALL_COOKIE, but we
9481 can't currently tell a register used for regular argument
9482 passing from one that is unused. If we leave it up to reload
9483 to decide which register to use, it seems to always choose
9484 R0_REG, which leaves no available registers in SIBCALL_REGS
9485 to hold the address of the trampoline. */
9486 mach = gen_rtx_REG (SImode, MACH_REG);
9487 r1 = gen_rtx_REG (SImode, R1_REG);
9489 /* Since such a call function may use all call-clobbered
9490 registers, we force a mode switch earlier, so that we don't
9491 run out of registers when adjusting fpscr for the call. */
9492 emit_insn (gen_force_mode_for_call ());
9495 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9496 operands[0] = force_reg (SImode, operands[0]);
9498 /* We don't need a return trampoline, since the callee will
9499 return directly to the upper caller. */
9500 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9502 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9503 cookie_rtx = GEN_INT (cookie);
9506 emit_move_insn (mach, func);
9507 emit_move_insn (r1, cookie_rtx);
9509 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9512 else if (TARGET_SHCOMPACT && flag_pic
9513 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9514 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9516 rtx reg = gen_reg_rtx (Pmode);
9518 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9519 XEXP (operands[0], 0) = reg;
9521 if (flag_pic && TARGET_SH2
9522 && MEM_P (operands[0])
9523 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9524 /* The PLT needs the PIC register, but the epilogue would have
9525 to restore it, so we can only use PC-relative PIC calls for
9526 static functions. */
9527 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9529 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9533 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9535 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9539 (define_insn "sibcall_valuei"
9540 [(set (match_operand 0 "" "=rf")
9541 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9542 (match_operand 2 "" "")))
9543 (use (reg:PSI FPSCR_REG))
9547 [(set_attr "needs_delay_slot" "yes")
9548 (set (attr "fp_mode")
9549 (if_then_else (eq_attr "fpu_single" "yes")
9550 (const_string "single") (const_string "double")))
9551 (set_attr "type" "jump_ind")])
9553 (define_insn "sibcall_valuei_pcrel"
9554 [(set (match_operand 0 "" "=rf")
9555 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9556 (match_operand 2 "" "")))
9557 (use (match_operand 3 "" ""))
9558 (use (reg:PSI FPSCR_REG))
9562 return "braf %1" "\n"
9565 [(set_attr "needs_delay_slot" "yes")
9566 (set (attr "fp_mode")
9567 (if_then_else (eq_attr "fpu_single" "yes")
9568 (const_string "single") (const_string "double")))
9569 (set_attr "type" "jump_ind")])
9571 (define_insn_and_split "sibcall_value_pcrel"
9572 [(set (match_operand 0 "" "=rf")
9573 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9574 (match_operand 2 "" "")))
9575 (use (reg:PSI FPSCR_REG))
9576 (clobber (match_scratch:SI 3 "=k"))
9583 rtx lab = PATTERN (gen_call_site ());
9586 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9587 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9591 SIBLING_CALL_P (call_insn) = 1;
9594 [(set_attr "needs_delay_slot" "yes")
9595 (set (attr "fp_mode")
9596 (if_then_else (eq_attr "fpu_single" "yes")
9597 (const_string "single") (const_string "double")))
9598 (set_attr "type" "jump_ind")])
9600 (define_insn "sibcall_value_compact"
9601 [(set (match_operand 0 "" "=rf,rf")
9602 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9603 (match_operand 2 "" "")))
9605 (use (match_operand:SI 3 "register_operand" "z,x"))
9606 (use (reg:SI R1_REG))
9607 (use (reg:PSI FPSCR_REG))
9608 ;; We want to make sure the `x' above will only match MACH_REG
9609 ;; because sibcall_epilogue may clobber MACL_REG.
9610 (clobber (reg:SI MACL_REG))]
9613 static const char* alt[] =
9620 return alt[which_alternative];
9622 [(set_attr "needs_delay_slot" "yes,no")
9623 (set_attr "length" "2,4")
9624 (set (attr "fp_mode") (const_string "single"))
9625 (set_attr "type" "jump_ind")])
9627 (define_insn "sibcall_value_media"
9628 [(set (match_operand 0 "" "=rf")
9629 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9630 (match_operand 2 "" "")))
9631 (use (reg:SI PR_MEDIA_REG))
9635 [(set_attr "type" "jump_media")])
9637 (define_expand "sibcall_value"
9639 [(set (match_operand 0 "arith_reg_operand" "")
9640 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9641 (match_operand 2 "" "")))
9642 (match_operand 3 "" "")
9643 (use (reg:PSI FPSCR_REG))
9649 operands[1] = shmedia_prepare_call_address (operands[1], 1);
9650 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9654 else if (TARGET_SHCOMPACT && operands[3]
9655 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9657 rtx cookie_rtx = operands[3];
9658 long cookie = INTVAL (cookie_rtx);
9659 rtx func = XEXP (operands[1], 0);
9664 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9666 rtx reg = gen_reg_rtx (Pmode);
9668 emit_insn (gen_symGOT2reg (reg, func));
9672 func = legitimize_pic_address (func, Pmode, 0);
9675 /* FIXME: if we could tell whether all argument registers are
9676 already taken, we could decide whether to force the use of
9677 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9678 simple way to tell. We could use the CALL_COOKIE, but we
9679 can't currently tell a register used for regular argument
9680 passing from one that is unused. If we leave it up to reload
9681 to decide which register to use, it seems to always choose
9682 R0_REG, which leaves no available registers in SIBCALL_REGS
9683 to hold the address of the trampoline. */
9684 mach = gen_rtx_REG (SImode, MACH_REG);
9685 r1 = gen_rtx_REG (SImode, R1_REG);
9687 /* Since such a call function may use all call-clobbered
9688 registers, we force a mode switch earlier, so that we don't
9689 run out of registers when adjusting fpscr for the call. */
9690 emit_insn (gen_force_mode_for_call ());
9693 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9694 operands[1] = force_reg (SImode, operands[1]);
9696 /* We don't need a return trampoline, since the callee will
9697 return directly to the upper caller. */
9698 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9700 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9701 cookie_rtx = GEN_INT (cookie);
9704 emit_move_insn (mach, func);
9705 emit_move_insn (r1, cookie_rtx);
9707 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9708 operands[2], mach));
9711 else if (TARGET_SHCOMPACT && flag_pic
9712 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9713 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9715 rtx reg = gen_reg_rtx (Pmode);
9717 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9718 XEXP (operands[1], 0) = reg;
9720 if (flag_pic && TARGET_SH2
9721 && MEM_P (operands[1])
9722 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9723 /* The PLT needs the PIC register, but the epilogue would have
9724 to restore it, so we can only use PC-relative PIC calls for
9725 static functions. */
9726 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9728 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9729 XEXP (operands[1], 0),
9734 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9736 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9740 (define_insn "call_value_pop_compact"
9741 [(set (match_operand 0 "" "=rf")
9742 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9743 (match_operand 2 "" "")))
9744 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9745 (match_operand 4 "immediate_operand" "n")))
9746 (match_operand 3 "immediate_operand" "n")
9747 (use (reg:SI R0_REG))
9748 (use (reg:SI R1_REG))
9749 (use (reg:PSI FPSCR_REG))
9750 (clobber (reg:SI PR_REG))]
9751 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9753 [(set_attr "type" "call")
9754 (set (attr "fp_mode")
9755 (if_then_else (eq_attr "fpu_single" "yes")
9756 (const_string "single") (const_string "double")))
9757 (set_attr "needs_delay_slot" "yes")])
9759 (define_insn "call_value_pop_compact_rettramp"
9760 [(set (match_operand 0 "" "=rf")
9761 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9762 (match_operand 2 "" "")))
9763 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9764 (match_operand 4 "immediate_operand" "n")))
9765 (match_operand 3 "immediate_operand" "n")
9766 (use (reg:SI R0_REG))
9767 (use (reg:SI R1_REG))
9768 (use (reg:PSI FPSCR_REG))
9769 (clobber (reg:SI R10_REG))
9770 (clobber (reg:SI PR_REG))]
9771 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9773 [(set_attr "type" "call")
9774 (set (attr "fp_mode")
9775 (if_then_else (eq_attr "fpu_single" "yes")
9776 (const_string "single") (const_string "double")))
9777 (set_attr "needs_delay_slot" "yes")])
9779 (define_expand "call_value_pop"
9780 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9781 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9782 (match_operand 2 "" "")))
9783 (match_operand 3 "" "")
9784 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9785 (match_operand 4 "" "")))])]
9793 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
9794 cookie_rtx = operands[3];
9795 cookie = INTVAL (cookie_rtx);
9796 func = XEXP (operands[1], 0);
9800 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9802 rtx reg = gen_reg_rtx (Pmode);
9804 emit_insn (gen_symGOTPLT2reg (reg, func));
9808 func = legitimize_pic_address (func, Pmode, 0);
9811 r0 = gen_rtx_REG (SImode, R0_REG);
9812 r1 = gen_rtx_REG (SImode, R1_REG);
9814 /* Since such a call function may use all call-clobbered
9815 registers, we force a mode switch earlier, so that we don't
9816 run out of registers when adjusting fpscr for the call. */
9817 emit_insn (gen_force_mode_for_call ());
9819 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9821 operands[1] = force_reg (SImode, operands[1]);
9823 emit_move_insn (r0, func);
9824 emit_move_insn (r1, cookie_rtx);
9826 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9827 emit_call_insn (gen_call_value_pop_compact_rettramp
9828 (operands[0], operands[1], operands[2],
9829 operands[3], operands[4]));
9831 emit_call_insn (gen_call_value_pop_compact
9832 (operands[0], operands[1], operands[2],
9833 operands[3], operands[4]));
9838 (define_expand "sibcall_epilogue"
9842 sh_expand_epilogue (true);
9843 if (TARGET_SHCOMPACT)
9847 /* If epilogue clobbers r0, preserve it in macl. */
9848 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9849 if ((set = single_set (insn))
9850 && REG_P (SET_DEST (set))
9851 && REGNO (SET_DEST (set)) == R0_REG)
9853 rtx r0 = gen_rtx_REG (SImode, R0_REG);
9854 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
9856 /* We can't tell at this point whether the sibcall is a
9857 sibcall_compact and, if it is, whether it uses r0 or
9858 mach as operand 2, so let the instructions that
9859 preserve r0 be optimized away if r0 turns out to be
9861 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
9862 emit_move_insn (r0, tmp);
9869 (define_insn "indirect_jump_compact"
9871 (match_operand:SI 0 "arith_reg_operand" "r"))]
9874 [(set_attr "needs_delay_slot" "yes")
9875 (set_attr "type" "jump_ind")])
9877 (define_expand "indirect_jump"
9879 (match_operand 0 "register_operand" ""))]
9882 if (GET_MODE (operands[0]) != Pmode)
9883 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
9886 ;; The use of operand 1 / 2 helps us distinguish case table jumps
9887 ;; which can be present in structured code from indirect jumps which can not
9888 ;; be present in structured code. This allows -fprofile-arcs to work.
9890 ;; For SH1 processors.
9891 (define_insn "casesi_jump_1"
9893 (match_operand:SI 0 "register_operand" "r"))
9894 (use (label_ref (match_operand 1 "" "")))]
9897 [(set_attr "needs_delay_slot" "yes")
9898 (set_attr "type" "jump_ind")])
9900 ;; For all later processors.
9901 (define_insn "casesi_jump_2"
9902 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
9903 (label_ref (match_operand 1 "" ""))))
9904 (use (label_ref (match_operand 2 "" "")))]
9906 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
9908 [(set_attr "needs_delay_slot" "yes")
9909 (set_attr "type" "jump_ind")])
9911 (define_insn "casesi_jump_media"
9912 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
9913 (use (label_ref (match_operand 1 "" "")))]
9916 [(set_attr "type" "jump_media")])
9918 ;; Call subroutine returning any type.
9919 ;; ??? This probably doesn't work.
9921 (define_expand "untyped_call"
9922 [(parallel [(call (match_operand 0 "" "")
9924 (match_operand 1 "" "")
9925 (match_operand 2 "" "")])]
9926 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
9930 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9932 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9934 rtx set = XVECEXP (operands[2], 0, i);
9935 emit_move_insn (SET_DEST (set), SET_SRC (set));
9938 /* The optimizer does not know that the call sets the function value
9939 registers we stored in the result block. We avoid problems by
9940 claiming that all hard registers are used and clobbered at this
9942 emit_insn (gen_blockage ());
9947 ;; ------------------------------------------------------------------------
9949 ;; ------------------------------------------------------------------------
9952 [(set (reg:SI T_REG)
9953 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
9954 (set (match_operand:SI 0 "arith_reg_dest" "=r")
9955 (plus:SI (match_dup 1) (const_int -1)))]
9958 [(set_attr "type" "arith")])
9965 ;; Load address of a label. This is only generated by the casesi expand,
9966 ;; and by machine_dependent_reorg (fixing up fp moves).
9967 ;; This must use unspec, because this only works for labels that are
9971 [(set (reg:SI R0_REG)
9972 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
9975 [(set_attr "in_delay_slot" "no")
9976 (set_attr "type" "arith")])
9978 ;; machine_dependent_reorg will make this a `mova'.
9979 (define_insn "mova_const"
9980 [(set (reg:SI R0_REG)
9981 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
9984 [(set_attr "in_delay_slot" "no")
9985 (set_attr "type" "arith")])
9987 (define_expand "GOTaddr2picreg"
9988 [(set (reg:SI R0_REG)
9989 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
9991 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
9992 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9995 if (TARGET_VXWORKS_RTP)
9997 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
9998 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
9999 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
10003 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
10004 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10006 if (TARGET_SHMEDIA)
10008 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10009 rtx pic = operands[0];
10010 rtx lab = PATTERN (gen_call_site ());
10013 equiv = operands[1];
10014 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
10015 UNSPEC_PCREL_SYMOFF);
10016 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
10018 if (Pmode == SImode)
10020 emit_insn (gen_movsi_const (pic, operands[1]));
10021 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10025 emit_insn (gen_movdi_const (pic, operands[1]));
10026 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10029 insn = emit_move_insn (operands[0], tr);
10031 set_unique_reg_note (insn, REG_EQUAL, equiv);
10037 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10040 (define_expand "vxworks_picreg"
10041 [(set (reg:SI PIC_REG)
10042 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10043 (set (reg:SI R0_REG)
10044 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10045 (set (reg:SI PIC_REG)
10046 (mem:SI (reg:SI PIC_REG)))
10047 (set (reg:SI PIC_REG)
10048 (mem:SI (plus:SI (reg:SI PIC_REG)
10049 (reg:SI R0_REG))))]
10050 "TARGET_VXWORKS_RTP")
10052 (define_insn "*ptb"
10053 [(set (match_operand 0 "target_reg_operand" "=b")
10054 (const (unspec [(match_operand 1 "" "Csy")]
10055 UNSPEC_DATALABEL)))]
10056 "TARGET_SHMEDIA && flag_pic
10057 && satisfies_constraint_Csy (operands[1])"
10058 "ptb/u datalabel %1, %0"
10059 [(set_attr "type" "ptabs_media")
10060 (set_attr "length" "*")])
10062 (define_insn "ptrel_si"
10063 [(set (match_operand:SI 0 "target_reg_operand" "=b")
10064 (plus:SI (match_operand:SI 1 "register_operand" "r")
10066 (match_operand:SI 2 "" "")]
10068 "%O2: ptrel/u %1, %0"
10069 [(set_attr "type" "ptabs_media")])
10071 (define_insn "ptrel_di"
10072 [(set (match_operand:DI 0 "target_reg_operand" "=b")
10073 (plus:DI (match_operand:DI 1 "register_operand" "r")
10075 (match_operand:DI 2 "" "")]
10077 "%O2: ptrel/u %1, %0"
10078 [(set_attr "type" "ptabs_media")])
10080 (define_expand "builtin_setjmp_receiver"
10081 [(match_operand 0 "" "")]
10084 emit_insn (gen_GOTaddr2picreg ());
10088 (define_expand "call_site"
10089 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10092 static HOST_WIDE_INT i = 0;
10093 operands[0] = GEN_INT (i);
10097 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
10098 ;; in symGOT_load expand.
10100 (define_insn_and_split "chk_guard_add"
10101 [(set (match_operand:SI 0 "register_operand" "=&r")
10102 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10107 "TARGET_SH1 && reload_completed"
10108 [(set (match_dup 0) (reg:SI PIC_REG))
10109 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10111 [(set_attr "type" "arith")])
10113 (define_expand "sym_label2reg"
10114 [(set (match_operand:SI 0 "" "")
10115 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10116 (const (plus:SI (match_operand:SI 2 "" "")
10121 (define_expand "symGOT_load"
10122 [(set (match_dup 2) (match_operand 1 "" ""))
10123 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10124 (set (match_operand 0 "" "") (mem (match_dup 3)))]
10129 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10130 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10132 if (TARGET_SHMEDIA)
10134 rtx reg = operands[2];
10136 if (Pmode == DImode)
10139 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10141 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10146 emit_insn (gen_movsi_const (reg, operands[1]));
10148 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10152 emit_move_insn (operands[2], operands[1]);
10154 /* When stack protector inserts codes after the result is set to
10155 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
10156 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10157 when rX is a GOT address for the guard symbol. Ugly but doesn't
10158 matter because this is a rare situation. */
10159 if (!TARGET_SHMEDIA
10160 && flag_stack_protect
10161 && GET_CODE (operands[1]) == CONST
10162 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10163 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10164 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10165 "__stack_chk_guard") == 0)
10166 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10168 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10169 gen_rtx_REG (Pmode, PIC_REG)));
10171 /* N.B. This is not constant for a GOTPLT relocation. */
10172 mem = gen_rtx_MEM (Pmode, operands[3]);
10173 MEM_NOTRAP_P (mem) = 1;
10174 /* ??? Should we have a special alias set for the GOT? */
10175 emit_move_insn (operands[0], mem);
10180 (define_expand "sym2GOT"
10181 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10185 (define_expand "symGOT2reg"
10186 [(match_operand 0 "" "") (match_operand 1 "" "")]
10191 gotsym = gen_sym2GOT (operands[1]);
10192 PUT_MODE (gotsym, Pmode);
10193 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10195 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10200 (define_expand "symGOTPLT2reg"
10201 [(match_operand 0 "" "") (match_operand 1 "" "")]
10204 rtx pltsym = gen_rtx_CONST (Pmode,
10205 gen_rtx_UNSPEC (Pmode,
10206 gen_rtvec (1, operands[1]),
10208 emit_insn (gen_symGOT_load (operands[0], pltsym));
10212 (define_expand "sym2GOTOFF"
10213 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10217 (define_expand "symGOTOFF2reg"
10218 [(match_operand 0 "" "") (match_operand 1 "" "")]
10221 rtx gotoffsym, insn;
10222 rtx t = (!can_create_pseudo_p ()
10224 : gen_reg_rtx (GET_MODE (operands[0])));
10226 gotoffsym = gen_sym2GOTOFF (operands[1]);
10227 PUT_MODE (gotoffsym, Pmode);
10228 emit_move_insn (t, gotoffsym);
10229 insn = emit_move_insn (operands[0],
10230 gen_rtx_PLUS (Pmode, t,
10231 gen_rtx_REG (Pmode, PIC_REG)));
10233 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10238 (define_expand "symPLT_label2reg"
10239 [(set (match_operand:SI 0 "" "")
10242 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10243 (const:SI (plus:SI (match_operand:SI 2 "" "")
10244 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10245 ;; Even though the PIC register is not really used by the call
10246 ;; sequence in which this is expanded, the PLT code assumes the PIC
10247 ;; register is set, so we must not skip its initialization. Since
10248 ;; we only use this expand as part of calling sequences, and never
10249 ;; to take the address of a function, this is the best point to
10250 ;; insert the (use). Using the PLT to take the address of a
10251 ;; function would be wrong, not only because the PLT entry could
10252 ;; then be called from a function that doesn't initialize the PIC
10253 ;; register to the proper GOT, but also because pointers to the
10254 ;; same function might not compare equal, should they be set by
10255 ;; different shared libraries.
10256 (use (reg:SI PIC_REG))]
10260 (define_expand "sym2PIC"
10261 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10265 ;; TLS code generation.
10266 ;; ??? this should be a define_insn_and_split
10267 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10268 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10271 (define_insn "tls_global_dynamic"
10272 [(set (match_operand:SI 0 "register_operand" "=&z")
10273 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10276 (use (reg:PSI FPSCR_REG))
10277 (use (reg:SI PIC_REG))
10278 (clobber (reg:SI PR_REG))
10279 (clobber (scratch:SI))]
10282 return "mov.l 1f,r4" "\n"
10284 " mov.l 2f,r1" "\n"
10291 "1: .long %a1@TLSGD" "\n"
10292 "2: .long __tls_get_addr@PLT" "\n"
10295 [(set_attr "type" "tls_load")
10296 (set_attr "length" "26")])
10298 (define_insn "tls_local_dynamic"
10299 [(set (match_operand:SI 0 "register_operand" "=&z")
10300 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10303 (use (reg:PSI FPSCR_REG))
10304 (use (reg:SI PIC_REG))
10305 (clobber (reg:SI PR_REG))
10306 (clobber (scratch:SI))]
10309 return "mov.l 1f,r4" "\n"
10311 " mov.l 2f,r1" "\n"
10318 "1: .long %a1@TLSLDM" "\n"
10319 "2: .long __tls_get_addr@PLT" "\n"
10322 [(set_attr "type" "tls_load")
10323 (set_attr "length" "26")])
10325 (define_expand "sym2DTPOFF"
10326 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10330 (define_expand "symDTPOFF2reg"
10331 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10335 rtx t = (!can_create_pseudo_p ()
10337 : gen_reg_rtx (GET_MODE (operands[0])));
10339 dtpoffsym = gen_sym2DTPOFF (operands[1]);
10340 PUT_MODE (dtpoffsym, Pmode);
10341 emit_move_insn (t, dtpoffsym);
10342 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10346 (define_expand "sym2GOTTPOFF"
10347 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10351 (define_insn "tls_initial_exec"
10352 [(set (match_operand:SI 0 "register_operand" "=&r")
10353 (unspec:SI [(match_operand:SI 1 "" "")]
10355 (use (reg:SI GBR_REG))
10356 (use (reg:SI PIC_REG))
10357 (clobber (reg:SI R0_REG))]
10360 return "mov.l 1f,r0" "\n"
10362 " mov.l @(r0,r12),r0" "\n"
10366 "1: .long %a1" "\n"
10369 [(set_attr "type" "tls_load")
10370 (set_attr "length" "16")])
10372 (define_expand "sym2TPOFF"
10373 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10377 (define_expand "symTPOFF2reg"
10378 [(match_operand 0 "" "") (match_operand 1 "" "")]
10383 tpoffsym = gen_sym2TPOFF (operands[1]);
10384 PUT_MODE (tpoffsym, Pmode);
10385 emit_move_insn (operands[0], tpoffsym);
10389 ;;------------------------------------------------------------------------------
10390 ;; Thread pointer getter and setter.
10392 ;; On SH the thread pointer is kept in the GBR.
10393 ;; These patterns are usually expanded from the respective built-in functions.
10394 (define_expand "get_thread_pointersi"
10395 [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10398 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10399 (define_insn "store_gbr"
10400 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10403 [(set_attr "type" "tls_load")])
10405 (define_expand "set_thread_pointersi"
10406 [(set (reg:SI GBR_REG)
10407 (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10411 (define_insn "load_gbr"
10412 [(set (reg:SI GBR_REG)
10413 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10417 [(set_attr "type" "move")])
10419 ;;------------------------------------------------------------------------------
10420 ;; Thread pointer relative memory loads and stores.
10422 ;; On SH there are GBR displacement address modes which can be utilized to
10423 ;; access memory behind the thread pointer.
10424 ;; Since we do not allow using GBR for general purpose memory accesses, these
10425 ;; GBR addressing modes are formed by the combine pass.
10426 ;; This could be done with fewer patterns than below by using a mem predicate
10427 ;; for the GBR mem, but then reload would try to reload addresses with a
10428 ;; zero displacement for some strange reason.
10430 (define_insn "*mov<mode>_gbr_load"
10431 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10432 (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10433 (match_operand:QIHISI 1 "gbr_displacement"))))]
10435 "mov.<bwl> @(%O1,gbr),%0"
10436 [(set_attr "type" "load")])
10438 (define_insn "*mov<mode>_gbr_load"
10439 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10440 (mem:QIHISI (reg:SI GBR_REG)))]
10442 "mov.<bwl> @(0,gbr),%0"
10443 [(set_attr "type" "load")])
10445 (define_insn "*mov<mode>_gbr_load"
10446 [(set (match_operand:SI 0 "register_operand" "=z")
10448 (mem:QIHI (plus:SI (reg:SI GBR_REG)
10449 (match_operand:QIHI 1 "gbr_displacement")))))]
10451 "mov.<bw> @(%O1,gbr),%0"
10452 [(set_attr "type" "load")])
10454 (define_insn "*mov<mode>_gbr_load"
10455 [(set (match_operand:SI 0 "register_operand" "=z")
10456 (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10458 "mov.<bw> @(0,gbr),%0"
10459 [(set_attr "type" "load")])
10461 (define_insn "*mov<mode>_gbr_store"
10462 [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10463 (match_operand:QIHISI 0 "gbr_displacement")))
10464 (match_operand:QIHISI 1 "register_operand" "z"))]
10466 "mov.<bwl> %1,@(%O0,gbr)"
10467 [(set_attr "type" "store")])
10469 (define_insn "*mov<mode>_gbr_store"
10470 [(set (mem:QIHISI (reg:SI GBR_REG))
10471 (match_operand:QIHISI 0 "register_operand" "z"))]
10473 "mov.<bwl> %0,@(0,gbr)"
10474 [(set_attr "type" "store")])
10476 ;; DImode memory accesses have to be split in two SImode accesses.
10477 ;; Split them before reload, so that it gets a better chance to figure out
10478 ;; how to deal with the R0 restriction for the individual SImode accesses.
10479 ;; Do not match this insn during or after reload because it can't be split
10481 (define_insn_and_split "*movdi_gbr_load"
10482 [(set (match_operand:DI 0 "register_operand")
10483 (match_operand:DI 1 "gbr_address_mem"))]
10484 "TARGET_SH1 && can_create_pseudo_p ()"
10487 [(set (match_dup 3) (match_dup 5))
10488 (set (match_dup 4) (match_dup 6))]
10490 /* Swap low/high part load order on little endian, so that the result reg
10491 of the second load can be used better. */
10492 int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10493 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10494 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10495 operands[4 - off] = gen_highpart (SImode, operands[0]);
10496 operands[6 - off] = gen_highpart (SImode, operands[1]);
10499 (define_insn_and_split "*movdi_gbr_store"
10500 [(set (match_operand:DI 0 "gbr_address_mem")
10501 (match_operand:DI 1 "register_operand"))]
10502 "TARGET_SH1 && can_create_pseudo_p ()"
10505 [(set (match_dup 3) (match_dup 5))
10506 (set (match_dup 4) (match_dup 6))]
10508 /* Swap low/high part store order on big endian, so that stores of function
10509 call results can save a reg copy. */
10510 int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10511 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10512 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10513 operands[4 - off] = gen_highpart (SImode, operands[0]);
10514 operands[6 - off] = gen_highpart (SImode, operands[1]);
10517 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10518 ;; in particular when the displacements are in the range of the regular move
10519 ;; insns. Thus, in the first split pass after the combine pass we search
10520 ;; for missed opportunities and try to fix them up ourselves.
10521 ;; If an equivalent GBR address can be determined the load / store is split
10522 ;; into one of the GBR load / store patterns.
10523 ;; All of that must happen before reload (GBR address modes use R0 as the
10524 ;; other operand) and there's no point of doing it if the GBR is not
10525 ;; referenced in a function at all.
10527 [(set (match_operand:QIHISIDI 0 "register_operand")
10528 (match_operand:QIHISIDI 1 "memory_operand"))]
10529 "TARGET_SH1 && !reload_in_progress && !reload_completed
10530 && df_regs_ever_live_p (GBR_REG)"
10531 [(set (match_dup 0) (match_dup 1))]
10533 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10534 if (gbr_mem != NULL_RTX)
10535 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10541 [(set (match_operand:SI 0 "register_operand")
10542 (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10543 "TARGET_SH1 && !reload_in_progress && !reload_completed
10544 && df_regs_ever_live_p (GBR_REG)"
10545 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10547 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10548 if (gbr_mem != NULL_RTX)
10549 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10554 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10555 ;; Split those so that a GBR load can be used.
10557 [(set (match_operand:SI 0 "register_operand")
10558 (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10559 "TARGET_SH2A && !reload_in_progress && !reload_completed
10560 && df_regs_ever_live_p (GBR_REG)"
10561 [(set (match_dup 2) (match_dup 1))
10562 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10564 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10565 if (gbr_mem != NULL_RTX)
10567 operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10568 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10575 [(set (match_operand:QIHISIDI 0 "memory_operand")
10576 (match_operand:QIHISIDI 1 "register_operand"))]
10577 "TARGET_SH1 && !reload_in_progress && !reload_completed
10578 && df_regs_ever_live_p (GBR_REG)"
10579 [(set (match_dup 0) (match_dup 1))]
10581 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10582 if (gbr_mem != NULL_RTX)
10583 operands[0] = replace_equiv_address (operands[0], gbr_mem);
10588 ;;------------------------------------------------------------------------------
10589 ;; case instruction for switch statements.
10591 ;; Operand 0 is index
10592 ;; operand 1 is the minimum bound
10593 ;; operand 2 is the maximum bound - minimum bound + 1
10594 ;; operand 3 is CODE_LABEL for the table;
10595 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10597 (define_expand "casesi"
10598 [(match_operand:SI 0 "arith_reg_operand" "")
10599 (match_operand:SI 1 "arith_reg_operand" "")
10600 (match_operand:SI 2 "arith_reg_operand" "")
10601 (match_operand 3 "" "") (match_operand 4 "" "")]
10604 rtx reg = gen_reg_rtx (SImode);
10605 rtx reg2 = gen_reg_rtx (SImode);
10606 if (TARGET_SHMEDIA)
10608 rtx reg = gen_reg_rtx (DImode);
10609 rtx reg2 = gen_reg_rtx (DImode);
10610 rtx reg3 = gen_reg_rtx (Pmode);
10611 rtx reg4 = gen_reg_rtx (Pmode);
10612 rtx reg5 = gen_reg_rtx (Pmode);
10615 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10616 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10617 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10619 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10620 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
10621 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10622 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10623 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10624 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10625 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10626 (Pmode, operands[3])));
10627 /* Messy: can we subreg to clean this up? */
10628 if (Pmode == DImode)
10629 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10631 load = gen_casesi_load_media (reg4,
10632 gen_rtx_SUBREG (DImode, reg3, 0),
10633 reg2, operands[3]);
10634 PUT_MODE (SET_SRC (load), Pmode);
10636 /* ??? The following add could be eliminated if we used ptrel. */
10637 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10638 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10642 operands[1] = copy_to_mode_reg (SImode, operands[1]);
10643 operands[2] = copy_to_mode_reg (SImode, operands[2]);
10644 /* If optimizing, casesi_worker depends on the mode of the instruction
10645 before label it 'uses' - operands[3]. */
10646 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10648 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10650 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10652 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10653 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10654 operands[3], but to lab. We will fix this up in
10655 machine_dependent_reorg. */
10660 (define_expand "casesi_0"
10661 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10662 (set (match_dup 4) (minus:SI (match_dup 4)
10663 (match_operand:SI 1 "arith_operand" "")))
10664 (set (reg:SI T_REG)
10665 (gtu:SI (match_dup 4)
10666 (match_operand:SI 2 "arith_reg_operand" "")))
10668 (if_then_else (ne (reg:SI T_REG)
10670 (label_ref (match_operand 3 "" ""))
10675 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10676 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10677 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10679 (define_insn "casesi_worker_0"
10680 [(set (match_operand:SI 0 "register_operand" "=r,r")
10681 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10682 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10683 (clobber (match_scratch:SI 3 "=X,1"))
10684 (clobber (match_scratch:SI 4 "=&z,z"))]
10689 [(set (match_operand:SI 0 "register_operand" "")
10690 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10691 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10692 (clobber (match_scratch:SI 3 ""))
10693 (clobber (match_scratch:SI 4 ""))]
10694 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10695 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10696 (parallel [(set (match_dup 0)
10697 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10698 (label_ref (match_dup 2))] UNSPEC_CASESI))
10699 (clobber (match_dup 3))])
10700 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10702 if (GET_CODE (operands[2]) == CODE_LABEL)
10703 LABEL_NUSES (operands[2])++;
10707 [(set (match_operand:SI 0 "register_operand" "")
10708 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10709 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10710 (clobber (match_scratch:SI 3 ""))
10711 (clobber (match_scratch:SI 4 ""))]
10712 "TARGET_SH2 && reload_completed"
10713 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10714 (parallel [(set (match_dup 0)
10715 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10716 (label_ref (match_dup 2))] UNSPEC_CASESI))
10717 (clobber (match_dup 3))])]
10719 if (GET_CODE (operands[2]) == CODE_LABEL)
10720 LABEL_NUSES (operands[2])++;
10723 (define_insn "casesi_worker_1"
10724 [(set (match_operand:SI 0 "register_operand" "=r,r")
10725 (unspec:SI [(reg:SI R0_REG)
10726 (match_operand:SI 1 "register_operand" "0,r")
10727 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10728 (clobber (match_scratch:SI 3 "=X,1"))]
10731 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10733 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10735 switch (GET_MODE (diff_vec))
10738 return "shll2 %1" "\n"
10739 " mov.l @(r0,%1),%0";
10741 return "add %1,%1" "\n"
10742 " mov.w @(r0,%1),%0";
10744 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10745 return "mov.b @(r0,%1),%0" "\n"
10748 return "mov.b @(r0,%1),%0";
10751 gcc_unreachable ();
10754 [(set_attr "length" "4")])
10756 (define_insn "casesi_worker_2"
10757 [(set (match_operand:SI 0 "register_operand" "=r,r")
10758 (unspec:SI [(reg:SI R0_REG)
10759 (match_operand:SI 1 "register_operand" "0,r")
10760 (label_ref (match_operand 2 "" ""))
10761 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
10762 (clobber (match_operand:SI 4 "" "=X,1"))]
10763 "TARGET_SH2 && reload_completed && flag_pic"
10765 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10766 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10768 switch (GET_MODE (diff_vec))
10771 return "shll2 %1" "\n"
10773 " mova %O3,r0" "\n"
10774 " mov.l @(r0,%1),%0";
10776 return "add %1,%1" "\n"
10778 " mova %O3,r0" "\n"
10779 " mov.w @(r0,%1),%0";
10781 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10782 return "add r0,%1" "\n"
10783 " mova %O3,r0" "\n"
10784 " mov.b @(r0,%1),%0" "\n"
10787 return "add r0,%1" "\n"
10788 " mova %O3,r0" "\n"
10789 " mov.b @(r0,%1),%0";
10791 gcc_unreachable ();
10794 [(set_attr "length" "8")])
10796 (define_insn "casesi_shift_media"
10797 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10798 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
10799 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
10803 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10805 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10807 switch (GET_MODE (diff_vec))
10810 return "shlli %1, 2, %0";
10812 return "shlli %1, 1, %0";
10814 if (rtx_equal_p (operands[0], operands[1]))
10816 return "add %1, r63, %0";
10818 gcc_unreachable ();
10821 [(set_attr "type" "arith_media")])
10823 (define_insn "casesi_load_media"
10824 [(set (match_operand 0 "any_arith_reg_dest" "=r")
10825 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
10826 (match_operand:DI 2 "arith_reg_operand" "r")
10827 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
10830 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
10832 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10834 switch (GET_MODE (diff_vec))
10837 return "ldx.l %1, %2, %0";
10840 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10841 return "ldx.uw %1, %2, %0";
10843 return "ldx.w %1, %2, %0";
10845 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10846 return "ldx.ub %1, %2, %0";
10847 return "ldx.b %1, %2, %0";
10849 gcc_unreachable ();
10852 [(set_attr "type" "load_media")])
10854 (define_expand "simple_return"
10856 "sh_can_use_simple_return_p ()")
10858 (define_expand "return"
10860 "reload_completed && epilogue_completed"
10862 if (TARGET_SHMEDIA)
10864 emit_jump_insn (gen_return_media ());
10868 if (TARGET_SHCOMPACT
10869 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
10871 emit_jump_insn (gen_shcompact_return_tramp ());
10876 (define_insn "*<code>_i"
10878 "TARGET_SH1 && ! (TARGET_SHCOMPACT
10879 && (crtl->args.info.call_cookie
10880 & CALL_COOKIE_RET_TRAMP (1)))
10881 && reload_completed
10882 && ! sh_cfun_trap_exit_p ()"
10884 if (TARGET_SH2A && (dbr_sequence_length () == 0)
10885 && !current_function_interrupt)
10890 [(set_attr "type" "return")
10891 (set_attr "needs_delay_slot" "yes")])
10893 ;; trapa has no delay slot.
10894 (define_insn "*return_trapa"
10896 "TARGET_SH1 && !TARGET_SHCOMPACT
10897 && reload_completed"
10899 [(set_attr "type" "return")])
10901 (define_expand "shcompact_return_tramp"
10904 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10906 rtx reg = gen_rtx_REG (Pmode, R0_REG);
10908 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
10909 emit_jump_insn (gen_shcompact_return_tramp_i ());
10913 (define_insn "shcompact_return_tramp_i"
10914 [(parallel [(return) (use (reg:SI R0_REG))])]
10916 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10918 [(set_attr "type" "jump_ind")
10919 (set_attr "needs_delay_slot" "yes")])
10921 (define_insn "return_media_i"
10922 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
10923 "TARGET_SHMEDIA && reload_completed"
10925 [(set_attr "type" "jump_media")])
10927 (define_insn "return_media_rte"
10929 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
10931 [(set_attr "type" "jump_media")])
10933 (define_expand "return_media"
10935 "TARGET_SHMEDIA && reload_completed"
10937 int tr_regno = sh_media_register_for_return ();
10940 if (current_function_interrupt)
10942 emit_jump_insn (gen_return_media_rte ());
10947 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
10949 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
10950 tr_regno = TR0_REG;
10951 tr = gen_rtx_REG (Pmode, tr_regno);
10952 emit_move_insn (tr, r18);
10955 tr = gen_rtx_REG (Pmode, tr_regno);
10957 emit_jump_insn (gen_return_media_i (tr));
10961 (define_insn "shcompact_preserve_incoming_args"
10962 [(set (match_operand:SI 0 "register_operand" "+r")
10963 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
10966 [(set_attr "length" "0")])
10968 (define_insn "shcompact_incoming_args"
10969 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
10970 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
10971 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
10972 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
10973 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
10974 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
10975 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
10976 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
10977 (set (mem:BLK (reg:SI MACL_REG))
10978 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
10979 (use (reg:SI R0_REG))
10980 (clobber (reg:SI R0_REG))
10981 (clobber (reg:SI MACL_REG))
10982 (clobber (reg:SI MACH_REG))
10983 (clobber (reg:SI PR_REG))]
10986 [(set_attr "needs_delay_slot" "yes")])
10988 (define_insn "shmedia_save_restore_regs_compact"
10989 [(set (reg:SI SP_REG)
10990 (plus:SI (reg:SI SP_REG)
10991 (match_operand:SI 0 "immediate_operand" "i")))
10992 (use (reg:SI R0_REG))
10993 (clobber (reg:SI PR_REG))]
10995 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
10996 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
10998 [(set_attr "needs_delay_slot" "yes")])
11000 (define_expand "prologue"
11004 sh_expand_prologue ();
11008 (define_expand "epilogue"
11012 sh_expand_epilogue (false);
11014 || (TARGET_SHCOMPACT
11015 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11017 emit_jump_insn (gen_return ());
11022 (define_expand "eh_return"
11023 [(use (match_operand 0 "register_operand" ""))]
11026 rtx ra = operands[0];
11028 if (TARGET_SHMEDIA64)
11029 emit_insn (gen_eh_set_ra_di (ra));
11031 emit_insn (gen_eh_set_ra_si (ra));
11036 ;; Clobber the return address on the stack. We can't expand this
11037 ;; until we know where it will be put in the stack frame.
11039 (define_insn "eh_set_ra_si"
11040 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11042 (clobber (match_scratch:SI 1 "=&r"))]
11043 "! TARGET_SHMEDIA64"
11046 (define_insn "eh_set_ra_di"
11047 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11049 (clobber (match_scratch:DI 1 "=&r"))]
11054 [(unspec_volatile [(match_operand 0 "register_operand" "")]
11056 (clobber (match_scratch 1 ""))]
11060 sh_set_return_address (operands[0], operands[1]);
11064 (define_insn "blockage"
11065 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11068 [(set_attr "length" "0")])
11070 ;; Define movml instructions for SH2A target. Currently they are
11071 ;; used to push and pop all banked registers only.
11073 (define_insn "movml_push_banked"
11074 [(set (match_operand:SI 0 "register_operand" "=r")
11075 (plus (match_dup 0) (const_int -32)))
11076 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11077 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11078 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11079 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11080 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11081 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11082 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11083 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11084 "TARGET_SH2A && REGNO (operands[0]) == 15"
11086 [(set_attr "in_delay_slot" "no")])
11088 (define_insn "movml_pop_banked"
11089 [(set (match_operand:SI 0 "register_operand" "=r")
11090 (plus (match_dup 0) (const_int 32)))
11091 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11092 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11093 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11094 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11095 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11096 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11097 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11098 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11099 "TARGET_SH2A && REGNO (operands[0]) == 15"
11101 [(set_attr "in_delay_slot" "no")])
11103 ;; ------------------------------------------------------------------------
11104 ;; Scc instructions
11105 ;; ------------------------------------------------------------------------
11107 (define_insn "movt"
11108 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11109 (match_operand:SI 1 "t_reg_operand"))]
11112 [(set_attr "type" "arith")])
11114 (define_insn "movrt"
11115 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11116 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11119 [(set_attr "type" "arith")])
11121 (define_expand "cstore4_media"
11122 [(set (match_operand:SI 0 "register_operand" "=r")
11123 (match_operator:SI 1 "sh_float_comparison_operator"
11124 [(match_operand 2 "logical_operand" "")
11125 (match_operand 3 "cmp_operand" "")]))]
11128 enum machine_mode mode = GET_MODE (operands[2]);
11129 enum rtx_code code = GET_CODE (operands[1]);
11131 if (mode == VOIDmode)
11132 mode = GET_MODE (operands[3]);
11133 if (operands[2] == const0_rtx)
11135 if (code == EQ || code == NE)
11136 operands[2] = operands[3], operands[3] = const0_rtx;
11139 operands[2] = force_reg (mode, operands[2]);
11140 if (operands[3] != const0_rtx)
11141 operands[3] = force_reg (mode, operands[3]);
11147 swap = invert = !FLOAT_MODE_P (mode);
11152 swap = FLOAT_MODE_P (mode), invert = !swap;
11157 swap = true, invert = false;
11164 swap = invert = false;
11168 swap = invert = true;
11172 gcc_unreachable ();
11177 rtx tem = operands[2];
11178 operands[2] = operands[3];
11180 code = swap_condition (code);
11185 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11186 code = reverse_condition (code);
11187 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11188 emit_insn (gen_cstore4_media (tem, operands[1],
11189 operands[2], operands[3]));
11192 operands[3] = const0_rtx;
11195 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11198 (define_expand "cstoresi4"
11199 [(set (match_operand:SI 0 "register_operand" "=r")
11200 (match_operator:SI 1 "comparison_operator"
11201 [(match_operand:SI 2 "cmpsi_operand" "")
11202 (match_operand:SI 3 "arith_operand" "")]))]
11203 "TARGET_SH1 || TARGET_SHMEDIA"
11205 if (TARGET_SHMEDIA)
11207 emit_insn (gen_cstore4_media (operands[0], operands[1],
11208 operands[2], operands[3]));
11212 if (sh_expand_t_scc (operands))
11215 if (! currently_expanding_to_rtl)
11218 sh_emit_compare_and_set (operands, SImode);
11222 (define_expand "cstoredi4"
11223 [(set (match_operand:SI 0 "register_operand" "=r")
11224 (match_operator:SI 1 "comparison_operator"
11225 [(match_operand:DI 2 "arith_operand" "")
11226 (match_operand:DI 3 "arith_operand" "")]))]
11227 "TARGET_SH2 || TARGET_SHMEDIA"
11229 if (TARGET_SHMEDIA)
11231 emit_insn (gen_cstore4_media (operands[0], operands[1],
11232 operands[2], operands[3]));
11236 if (sh_expand_t_scc (operands))
11239 if (! currently_expanding_to_rtl)
11242 sh_emit_compare_and_set (operands, DImode);
11246 ;; Move the complement of the T reg to a reg.
11247 ;; On SH2A the movrt insn can be used.
11248 ;; On anything else than SH2A this has to be done with multiple instructions.
11249 ;; One obvious way would be:
11254 ;; However, this puts pressure on r0 in most cases and thus the following is
11260 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11261 ;; becomes a one instruction operation. Moreover, care must be taken that
11262 ;; the insn can still be combined with inverted compare and branch code
11263 ;; around it. On the other hand, if a function returns the complement of
11264 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11265 ;; lead to better code.
11267 (define_expand "movnegt"
11268 [(set (match_operand:SI 0 "arith_reg_dest" "")
11269 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11273 emit_insn (gen_movrt (operands[0], operands[1]));
11276 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11277 emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11282 (define_insn "movrt_negc"
11283 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11284 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11285 (set (reg:SI T_REG) (const_int 1))
11286 (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11289 [(set_attr "type" "arith")])
11291 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11292 ;; pattern can be used by the combine pass. Using a scratch reg for the
11293 ;; -1 constant results in slightly better register allocations compared to
11294 ;; generating a pseudo reg before reload.
11295 (define_insn_and_split "*movrt_negc"
11296 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11297 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11298 (clobber (match_scratch:SI 2 "=r"))
11299 (clobber (reg:SI T_REG))]
11300 "TARGET_SH1 && ! TARGET_SH2A"
11302 "&& reload_completed"
11303 [(set (match_dup 2) (const_int -1))
11305 [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
11306 (set (reg:SI T_REG) (const_int 1))
11307 (use (match_dup 2))])])
11309 ;; Store the negated T bit in a reg using r0 and xor. This one doesn't
11310 ;; clobber the T bit, which is useful when storing the T bit and the
11311 ;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
11312 ;; Usually we don't want this insn to be matched, except for cases where the
11313 ;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
11314 (define_insn_and_split "movrt_xor"
11315 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11316 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11317 (use (reg:SI T_REG))]
11318 "TARGET_SH1 && !TARGET_SH2A"
11320 "&& reload_completed"
11321 [(set (match_dup 0) (reg:SI T_REG))
11322 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11324 ;; Store the T bit and the negated T bit in two regs in parallel. There is
11325 ;; no real insn to do that, but specifying this pattern will give combine
11326 ;; some opportunities.
11327 (define_insn_and_split "*movt_movrt"
11328 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11329 (match_operand:SI 1 "negt_reg_operand"))
11330 (set (match_operand:SI 2 "arith_reg_dest")
11331 (match_operand:SI 3 "t_reg_operand"))])]
11337 rtx i = TARGET_SH2A
11338 ? gen_movrt (operands[0], get_t_reg_rtx ())
11339 : gen_movrt_xor (operands[0], get_t_reg_rtx ());
11342 emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
11346 (define_insn_and_split "*movt_movrt"
11347 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11348 (match_operand:SI 1 "t_reg_operand"))
11349 (set (match_operand:SI 2 "arith_reg_dest")
11350 (match_operand:SI 3 "negt_reg_operand"))])]
11354 [(parallel [(set (match_dup 2) (match_dup 3))
11355 (set (match_dup 0) (match_dup 1))])])
11357 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11358 ;; T = 1: 0x80000000 -> reg
11359 ;; T = 0: 0x7FFFFFFF -> reg
11360 ;; This works because 0 - 0x80000000 = 0x80000000.
11361 (define_insn_and_split "*mov_t_msb_neg"
11362 [(set (match_operand:SI 0 "arith_reg_dest")
11363 (minus:SI (const_int -2147483648) ;; 0x80000000
11364 (match_operand 1 "t_reg_operand")))
11365 (clobber (reg:SI T_REG))]
11368 "&& can_create_pseudo_p ()"
11369 [(set (match_dup 2) (const_int -2147483648))
11370 (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11372 (clobber (reg:SI T_REG))])]
11374 operands[2] = gen_reg_rtx (SImode);
11377 ;; These are essentially the same as above, but with the inverted T bit.
11378 ;; Combine recognizes the split patterns, but does not take them sometimes
11379 ;; if the T_REG clobber is specified. Instead it tries to split out the
11380 ;; T bit negation. Since these splits are supposed to be taken only by
11381 ;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
11384 [(set (match_operand:SI 0 "arith_reg_dest")
11385 (plus:SI (match_operand 1 "negt_reg_operand")
11386 (const_int 2147483647)))] ;; 0x7fffffff
11387 "TARGET_SH1 && can_create_pseudo_p ()"
11388 [(parallel [(set (match_dup 0)
11389 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11390 (clobber (reg:SI T_REG))])])
11393 [(set (match_operand:SI 0 "arith_reg_dest")
11394 (if_then_else:SI (match_operand 1 "t_reg_operand")
11395 (const_int 2147483647) ;; 0x7fffffff
11396 (const_int -2147483648)))] ;; 0x80000000
11397 "TARGET_SH1 && can_create_pseudo_p ()"
11398 [(parallel [(set (match_dup 0)
11399 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11400 (clobber (reg:SI T_REG))])])
11402 ;; The *negnegt pattern helps the combine pass to figure out how to fold
11403 ;; an explicit double T bit negation.
11404 (define_insn_and_split "*negnegt"
11405 [(set (reg:SI T_REG)
11406 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11412 ;; Store T bit as all zeros or ones in a reg.
11413 (define_insn "mov_neg_si_t"
11414 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11415 (neg:SI (match_operand 1 "t_reg_operand" "")))]
11418 [(set_attr "type" "arith")])
11420 ;; Store negated T bit as all zeros or ones in a reg.
11421 ;; Use the following sequence:
11422 ;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
11423 ;; not Rn,Rn ! Rn = 0 - Rn
11425 [(set (match_operand:SI 0 "arith_reg_dest" "")
11426 (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11428 [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11429 (set (match_dup 0) (not:SI (match_dup 0)))])
11431 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11432 (define_insn_and_split "*movtt"
11433 [(set (reg:SI T_REG)
11434 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11440 (define_insn_and_split "nott"
11441 [(set (reg:SI T_REG)
11442 (xor:SI (match_operand:SI 0 "t_reg_operand" "") (const_int 1)))]
11445 gcc_assert (TARGET_SH2A);
11448 "! TARGET_SH2A && can_create_pseudo_p ()"
11449 [(set (match_dup 0) (reg:SI T_REG))
11450 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11452 operands[0] = gen_reg_rtx (SImode);
11455 ;; Store T bit as MSB in a reg.
11456 ;; T = 0: 0x00000000 -> reg
11457 ;; T = 1: 0x80000000 -> reg
11458 (define_insn_and_split "*movt_msb"
11459 [(set (match_operand:SI 0 "arith_reg_dest")
11460 (mult:SI (match_operand:SI 1 "t_reg_operand")
11461 (const_int -2147483648))) ;; 0xffffffff80000000
11462 (clobber (reg:SI T_REG))]
11466 [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11468 ;; Store inverted T bit as MSB in a reg.
11469 ;; T = 0: 0x80000000 -> reg
11470 ;; T = 1: 0x00000000 -> reg
11471 ;; On SH2A we can get away without clobbering the T_REG.
11472 (define_insn_and_split "*negt_msb"
11473 [(set (match_operand:SI 0 "arith_reg_dest")
11474 (match_operand:SI 1 "negt_reg_shl31_operand"))]
11477 "&& can_create_pseudo_p ()"
11480 rtx tmp = gen_reg_rtx (SImode);
11481 emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11482 emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11486 (define_insn_and_split "*negt_msb"
11487 [(set (match_operand:SI 0 "arith_reg_dest")
11488 (match_operand:SI 1 "negt_reg_shl31_operand"))
11489 (clobber (reg:SI T_REG))]
11490 "TARGET_SH1 && !TARGET_SH2A"
11492 "&& can_create_pseudo_p ()"
11495 rtx tmp = gen_reg_rtx (SImode);
11496 emit_move_insn (tmp, get_t_reg_rtx ());
11497 emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11498 emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11502 ;; The *cset_zero patterns convert optimizations such as
11503 ;; "if (test) x = 0;" to "x &= -(test == 0);"
11504 ;; back to conditional branch sequences if zero-displacement branches
11506 ;; FIXME: These patterns can be removed when conditional execution patterns
11507 ;; are implemented, since ifcvt will not perform these optimizations if
11508 ;; conditional execution is supported.
11509 (define_insn "*cset_zero"
11510 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11511 (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11513 (match_operand:SI 2 "arith_reg_operand" "0")))]
11514 "TARGET_SH1 && TARGET_ZDCBRANCH"
11516 return "bf 0f" "\n"
11520 [(set_attr "type" "arith") ;; poor approximation
11521 (set_attr "length" "4")])
11523 (define_insn "*cset_zero"
11524 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11525 (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
11526 (match_operand:SI 2 "arith_reg_operand" "0")
11528 "TARGET_SH1 && TARGET_ZDCBRANCH"
11530 return "bt 0f" "\n"
11534 [(set_attr "type" "arith") ;; poor approximation
11535 (set_attr "length" "4")])
11537 (define_expand "cstoresf4"
11538 [(set (match_operand:SI 0 "register_operand" "=r")
11539 (match_operator:SI 1 "sh_float_comparison_operator"
11540 [(match_operand:SF 2 "arith_operand" "")
11541 (match_operand:SF 3 "arith_operand" "")]))]
11542 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11544 if (TARGET_SHMEDIA)
11546 emit_insn (gen_cstore4_media (operands[0], operands[1],
11547 operands[2], operands[3]));
11551 if (! currently_expanding_to_rtl)
11554 sh_emit_compare_and_set (operands, SFmode);
11558 (define_expand "cstoredf4"
11559 [(set (match_operand:SI 0 "register_operand" "=r")
11560 (match_operator:SI 1 "sh_float_comparison_operator"
11561 [(match_operand:DF 2 "arith_operand" "")
11562 (match_operand:DF 3 "arith_operand" "")]))]
11563 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11565 if (TARGET_SHMEDIA)
11567 emit_insn (gen_cstore4_media (operands[0], operands[1],
11568 operands[2], operands[3]));
11572 if (! currently_expanding_to_rtl)
11575 sh_emit_compare_and_set (operands, DFmode);
11579 ;; -------------------------------------------------------------------------
11580 ;; Instructions to cope with inline literal tables
11581 ;; -------------------------------------------------------------------------
11583 ; 2 byte integer in line
11585 (define_insn "consttable_2"
11586 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11587 (match_operand 1 "" "")]
11591 if (operands[1] != const0_rtx)
11592 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11595 [(set_attr "length" "2")
11596 (set_attr "in_delay_slot" "no")])
11598 ; 4 byte integer in line
11600 (define_insn "consttable_4"
11601 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11602 (match_operand 1 "" "")]
11606 if (operands[1] != const0_rtx)
11608 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11609 mark_symbol_refs_as_used (operands[0]);
11613 [(set_attr "length" "4")
11614 (set_attr "in_delay_slot" "no")])
11616 ; 8 byte integer in line
11618 (define_insn "consttable_8"
11619 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11620 (match_operand 1 "" "")]
11624 if (operands[1] != const0_rtx)
11625 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11628 [(set_attr "length" "8")
11629 (set_attr "in_delay_slot" "no")])
11631 ; 4 byte floating point
11633 (define_insn "consttable_sf"
11634 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11635 (match_operand 1 "" "")]
11639 if (operands[1] != const0_rtx)
11642 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11643 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11647 [(set_attr "length" "4")
11648 (set_attr "in_delay_slot" "no")])
11650 ; 8 byte floating point
11652 (define_insn "consttable_df"
11653 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11654 (match_operand 1 "" "")]
11658 if (operands[1] != const0_rtx)
11661 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11662 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11666 [(set_attr "length" "8")
11667 (set_attr "in_delay_slot" "no")])
11669 ;; Alignment is needed for some constant tables; it may also be added for
11670 ;; Instructions at the start of loops, or after unconditional branches.
11671 ;; ??? We would get more accurate lengths if we did instruction
11672 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11673 ;; here is too conservative.
11675 ; align to a two byte boundary
11677 (define_expand "align_2"
11678 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11682 ; align to a four byte boundary
11683 ;; align_4 and align_log are instructions for the starts of loops, or
11684 ;; after unconditional branches, which may take up extra room.
11686 (define_expand "align_4"
11687 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11691 ; align to a cache line boundary
11693 (define_insn "align_log"
11694 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11697 [(set_attr "length" "0")
11698 (set_attr "in_delay_slot" "no")])
11700 ; emitted at the end of the literal table, used to emit the
11701 ; 32bit branch labels if needed.
11703 (define_insn "consttable_end"
11704 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11707 return output_jump_label_table ();
11709 [(set_attr "in_delay_slot" "no")])
11711 ; emitted at the end of the window in the literal table.
11713 (define_insn "consttable_window_end"
11714 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11717 [(set_attr "length" "0")
11718 (set_attr "in_delay_slot" "no")])
11720 ;; -------------------------------------------------------------------------
11722 ;; -------------------------------------------------------------------------
11724 ;; String/block move insn.
11726 (define_expand "movmemsi"
11727 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
11728 (mem:BLK (match_operand:BLK 1 "" "")))
11729 (use (match_operand:SI 2 "nonmemory_operand" ""))
11730 (use (match_operand:SI 3 "immediate_operand" ""))
11731 (clobber (reg:SI PR_REG))
11732 (clobber (reg:SI R4_REG))
11733 (clobber (reg:SI R5_REG))
11734 (clobber (reg:SI R0_REG))])]
11735 "TARGET_SH1 && ! TARGET_SH5"
11737 if(expand_block_move (operands))
11742 (define_insn "block_move_real"
11743 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11744 (mem:BLK (reg:SI R5_REG)))
11745 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11746 (clobber (reg:SI PR_REG))
11747 (clobber (reg:SI R0_REG))])]
11748 "TARGET_SH1 && ! TARGET_HARD_SH4"
11750 [(set_attr "type" "sfunc")
11751 (set_attr "needs_delay_slot" "yes")])
11753 (define_insn "block_lump_real"
11754 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11755 (mem:BLK (reg:SI R5_REG)))
11756 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11757 (use (reg:SI R6_REG))
11758 (clobber (reg:SI PR_REG))
11759 (clobber (reg:SI T_REG))
11760 (clobber (reg:SI R4_REG))
11761 (clobber (reg:SI R5_REG))
11762 (clobber (reg:SI R6_REG))
11763 (clobber (reg:SI R0_REG))])]
11764 "TARGET_SH1 && ! TARGET_HARD_SH4"
11766 [(set_attr "type" "sfunc")
11767 (set_attr "needs_delay_slot" "yes")])
11769 (define_insn "block_move_real_i4"
11770 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11771 (mem:BLK (reg:SI R5_REG)))
11772 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11773 (clobber (reg:SI PR_REG))
11774 (clobber (reg:SI R0_REG))
11775 (clobber (reg:SI R1_REG))
11776 (clobber (reg:SI R2_REG))])]
11779 [(set_attr "type" "sfunc")
11780 (set_attr "needs_delay_slot" "yes")])
11782 (define_insn "block_lump_real_i4"
11783 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11784 (mem:BLK (reg:SI R5_REG)))
11785 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11786 (use (reg:SI R6_REG))
11787 (clobber (reg:SI PR_REG))
11788 (clobber (reg:SI T_REG))
11789 (clobber (reg:SI R4_REG))
11790 (clobber (reg:SI R5_REG))
11791 (clobber (reg:SI R6_REG))
11792 (clobber (reg:SI R0_REG))
11793 (clobber (reg:SI R1_REG))
11794 (clobber (reg:SI R2_REG))
11795 (clobber (reg:SI R3_REG))])]
11798 [(set_attr "type" "sfunc")
11799 (set_attr "needs_delay_slot" "yes")])
11801 ;; -------------------------------------------------------------------------
11802 ;; Floating point instructions.
11803 ;; -------------------------------------------------------------------------
11805 ;; ??? All patterns should have a type attribute.
11807 (define_expand "movpsi"
11808 [(set (match_operand:PSI 0 "register_operand" "")
11809 (match_operand:PSI 1 "general_movsrc_operand" ""))]
11810 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11813 ;; The c / m alternative is a fake to guide reload to load directly into
11814 ;; fpscr, since reload doesn't know how to use post-increment.
11815 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
11816 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
11817 ;; predicate after reload.
11818 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
11819 ;; like a mac -> gpr move.
11820 (define_insn "fpu_switch"
11821 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
11822 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
11824 && (! reload_completed
11825 || true_regnum (operands[0]) != FPSCR_REG
11826 || !MEM_P (operands[1])
11827 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
11829 ! precision stays the same
11838 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
11839 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
11842 [(set (reg:PSI FPSCR_REG)
11843 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11844 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
11847 rtx fpscr, mem, new_insn;
11849 fpscr = SET_DEST (PATTERN (curr_insn));
11850 mem = SET_SRC (PATTERN (curr_insn));
11851 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11853 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11854 add_reg_note (new_insn, REG_INC, operands[0]);
11859 [(set (reg:PSI FPSCR_REG)
11860 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11861 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
11862 && (flag_peephole2 ? epilogue_completed : reload_completed)"
11865 rtx fpscr, mem, new_insn;
11867 fpscr = SET_DEST (PATTERN (curr_insn));
11868 mem = SET_SRC (PATTERN (curr_insn));
11869 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11871 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11872 add_reg_note (new_insn, REG_INC, operands[0]);
11874 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
11875 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
11879 ;; ??? This uses the fp unit, but has no type indicating that.
11880 ;; If we did that, this would either give a bogus latency or introduce
11881 ;; a bogus FIFO constraint.
11882 ;; Since this insn is currently only used for prologues/epilogues,
11883 ;; it is probably best to claim no function unit, which matches the
11884 ;; current setting.
11885 (define_insn "toggle_sz"
11886 [(set (reg:PSI FPSCR_REG)
11887 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
11888 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11890 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
11892 ;; There's no way we can use it today, since optimize mode switching
11893 ;; doesn't enable us to know from which mode we're switching to the
11894 ;; mode it requests, to tell whether we can use a relative mode switch
11895 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
11897 (define_insn "toggle_pr"
11898 [(set (reg:PSI FPSCR_REG)
11899 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
11900 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
11902 [(set_attr "type" "fpscr_toggle")])
11904 (define_expand "addsf3"
11905 [(set (match_operand:SF 0 "arith_reg_operand" "")
11906 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
11907 (match_operand:SF 2 "arith_reg_operand" "")))]
11908 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11912 expand_sf_binop (&gen_addsf3_i, operands);
11917 (define_insn "*addsf3_media"
11918 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11919 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
11920 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11921 "TARGET_SHMEDIA_FPU"
11922 "fadd.s %1, %2, %0"
11923 [(set_attr "type" "fparith_media")])
11925 (define_insn_and_split "unary_sf_op"
11926 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11931 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
11932 (match_operator:SF 2 "unary_float_operator"
11933 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11934 (parallel [(match_operand 4
11935 "const_int_operand" "n")]))]))
11936 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
11937 "TARGET_SHMEDIA_FPU"
11939 "TARGET_SHMEDIA_FPU && reload_completed"
11940 [(set (match_dup 5) (match_dup 6))]
11942 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11943 rtx op1 = gen_rtx_REG (SFmode,
11944 (true_regnum (operands[1])
11945 + (INTVAL (operands[4]) ^ endian)));
11947 operands[7] = gen_rtx_REG (SFmode,
11948 (true_regnum (operands[0])
11949 + (INTVAL (operands[3]) ^ endian)));
11950 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
11952 [(set_attr "type" "fparith_media")])
11954 (define_insn_and_split "binary_sf_op0"
11955 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11957 (match_operator:SF 3 "binary_float_operator"
11958 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11959 (parallel [(const_int 0)]))
11960 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11961 (parallel [(const_int 0)]))])
11964 (parallel [(const_int 1)]))))]
11965 "TARGET_SHMEDIA_FPU"
11967 "&& reload_completed"
11968 [(set (match_dup 4) (match_dup 5))]
11970 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11971 rtx op1 = gen_rtx_REG (SFmode,
11972 true_regnum (operands[1]) + endian);
11973 rtx op2 = gen_rtx_REG (SFmode,
11974 true_regnum (operands[2]) + endian);
11976 operands[4] = gen_rtx_REG (SFmode,
11977 true_regnum (operands[0]) + endian);
11978 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
11980 [(set_attr "type" "fparith_media")])
11982 (define_insn_and_split "binary_sf_op1"
11983 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11987 (parallel [(const_int 0)]))
11988 (match_operator:SF 3 "binary_float_operator"
11989 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11990 (parallel [(const_int 1)]))
11991 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11992 (parallel [(const_int 1)]))])))]
11993 "TARGET_SHMEDIA_FPU"
11995 "&& reload_completed"
11996 [(set (match_dup 4) (match_dup 5))]
11998 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11999 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
12000 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
12002 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
12003 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12005 [(set_attr "type" "fparith_media")])
12007 (define_insn "addsf3_i"
12008 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12009 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12010 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12011 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12014 [(set_attr "type" "fp")
12015 (set_attr "fp_mode" "single")])
12017 (define_expand "subsf3"
12018 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12019 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12020 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12021 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12025 expand_sf_binop (&gen_subsf3_i, operands);
12030 (define_insn "*subsf3_media"
12031 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12032 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12033 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12034 "TARGET_SHMEDIA_FPU"
12035 "fsub.s %1, %2, %0"
12036 [(set_attr "type" "fparith_media")])
12038 (define_insn "subsf3_i"
12039 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12040 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12041 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12042 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12045 [(set_attr "type" "fp")
12046 (set_attr "fp_mode" "single")])
12048 (define_expand "mulsf3"
12049 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12050 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12051 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12052 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12056 emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2],
12057 get_fpscr_rtx ()));
12062 (define_insn "*mulsf3_media"
12063 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12064 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12065 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12066 "TARGET_SHMEDIA_FPU"
12067 "fmul.s %1, %2, %0"
12068 [(set_attr "type" "fparith_media")])
12070 (define_insn "mulsf3_i"
12071 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12072 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12073 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12074 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12077 [(set_attr "type" "fp")
12078 (set_attr "fp_mode" "single")])
12080 ;; FMA (fused multiply-add) patterns
12081 (define_expand "fmasf4"
12082 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12083 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12084 (match_operand:SF 2 "fp_arith_reg_operand" "")
12085 (match_operand:SF 3 "fp_arith_reg_operand" "")))]
12086 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12090 emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
12091 operands[3], get_fpscr_rtx ()));
12096 (define_insn "fmasf4_i"
12097 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12098 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
12099 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12100 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
12101 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
12104 [(set_attr "type" "fp")
12105 (set_attr "fp_mode" "single")])
12107 (define_insn "fmasf4_media"
12108 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12109 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12110 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12111 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12112 "TARGET_SHMEDIA_FPU"
12113 "fmac.s %1, %2, %0"
12114 [(set_attr "type" "fparith_media")])
12116 (define_expand "divsf3"
12117 [(set (match_operand:SF 0 "arith_reg_operand" "")
12118 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
12119 (match_operand:SF 2 "arith_reg_operand" "")))]
12120 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12124 expand_sf_binop (&gen_divsf3_i, operands);
12129 (define_insn "*divsf3_media"
12130 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12131 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12132 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12133 "TARGET_SHMEDIA_FPU"
12134 "fdiv.s %1, %2, %0"
12135 [(set_attr "type" "fdiv_media")])
12137 (define_insn "divsf3_i"
12138 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
12139 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
12140 (match_operand:SF 2 "arith_reg_operand" "f")))
12141 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12144 [(set_attr "type" "fdiv")
12145 (set_attr "fp_mode" "single")])
12147 (define_insn "floatdisf2"
12148 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12149 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12150 "TARGET_SHMEDIA_FPU"
12152 [(set_attr "type" "fpconv_media")])
12154 (define_expand "floatsisf2"
12155 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12156 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
12157 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12159 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12161 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
12166 (define_insn "*floatsisf2_media"
12167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12168 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12169 "TARGET_SHMEDIA_FPU"
12171 [(set_attr "type" "fpconv_media")])
12173 (define_insn "floatsisf2_i4"
12174 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12175 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
12176 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12177 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12179 [(set_attr "type" "fp")
12180 (set_attr "fp_mode" "single")])
12182 (define_insn "*floatsisf2_ie"
12183 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12184 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
12185 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12187 [(set_attr "type" "fp")])
12189 (define_insn "fix_truncsfdi2"
12190 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12191 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12192 "TARGET_SHMEDIA_FPU"
12194 [(set_attr "type" "fpconv_media")])
12196 (define_expand "fix_truncsfsi2"
12197 [(set (match_operand:SI 0 "fpul_operand" "=y")
12198 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12199 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12201 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12203 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
12208 (define_insn "*fix_truncsfsi2_media"
12209 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12210 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12211 "TARGET_SHMEDIA_FPU"
12213 [(set_attr "type" "fpconv_media")])
12215 (define_insn "fix_truncsfsi2_i4"
12216 [(set (match_operand:SI 0 "fpul_operand" "=y")
12217 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12218 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12219 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12221 [(set_attr "type" "ftrc_s")
12222 (set_attr "fp_mode" "single")])
12224 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
12225 ;; fix_truncsfsi2_i4.
12226 ;; (define_insn "fix_truncsfsi2_i4_2"
12227 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12228 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12229 ;; (use (reg:PSI FPSCR_REG))
12230 ;; (clobber (reg:SI FPUL_REG))]
12233 ;; [(set_attr "length" "4")
12234 ;; (set_attr "fp_mode" "single")])
12237 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12238 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12239 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12240 ;; (clobber (reg:SI FPUL_REG))]
12242 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12243 ;; (use (match_dup 2))])
12244 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
12246 (define_insn "*fixsfsi"
12247 [(set (match_operand:SI 0 "fpul_operand" "=y")
12248 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12249 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12251 [(set_attr "type" "fp")])
12253 (define_insn "cmpgtsf_t"
12254 [(set (reg:SI T_REG)
12255 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12256 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12257 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12259 [(set_attr "type" "fp_cmp")
12260 (set_attr "fp_mode" "single")])
12262 (define_insn "cmpeqsf_t"
12263 [(set (reg:SI T_REG)
12264 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12265 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12266 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12268 [(set_attr "type" "fp_cmp")
12269 (set_attr "fp_mode" "single")])
12271 (define_insn "ieee_ccmpeqsf_t"
12272 [(set (reg:SI T_REG)
12273 (ior:SI (reg:SI T_REG)
12274 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12275 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
12276 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12278 return output_ieee_ccmpeq (insn, operands);
12280 [(set_attr "length" "4")])
12283 (define_insn "cmpgtsf_t_i4"
12284 [(set (reg:SI T_REG)
12285 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12286 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12287 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12288 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12290 [(set_attr "type" "fp_cmp")
12291 (set_attr "fp_mode" "single")])
12293 (define_insn "cmpeqsf_t_i4"
12294 [(set (reg:SI T_REG)
12295 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12296 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12297 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12298 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12300 [(set_attr "type" "fp_cmp")
12301 (set_attr "fp_mode" "single")])
12303 (define_insn "*ieee_ccmpeqsf_t_4"
12304 [(set (reg:SI T_REG)
12305 (ior:SI (reg:SI T_REG)
12306 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12307 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12308 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12309 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12311 return output_ieee_ccmpeq (insn, operands);
12313 [(set_attr "length" "4")
12314 (set_attr "fp_mode" "single")])
12316 (define_insn "cmpeqsf_media"
12317 [(set (match_operand:SI 0 "register_operand" "=r")
12318 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12319 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12320 "TARGET_SHMEDIA_FPU"
12321 "fcmpeq.s %1, %2, %0"
12322 [(set_attr "type" "fcmp_media")])
12324 (define_insn "cmpgtsf_media"
12325 [(set (match_operand:SI 0 "register_operand" "=r")
12326 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12327 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12328 "TARGET_SHMEDIA_FPU"
12329 "fcmpgt.s %1, %2, %0"
12330 [(set_attr "type" "fcmp_media")])
12332 (define_insn "cmpgesf_media"
12333 [(set (match_operand:SI 0 "register_operand" "=r")
12334 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12335 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12336 "TARGET_SHMEDIA_FPU"
12337 "fcmpge.s %1, %2, %0"
12338 [(set_attr "type" "fcmp_media")])
12340 (define_insn "cmpunsf_media"
12341 [(set (match_operand:SI 0 "register_operand" "=r")
12342 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12343 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12344 "TARGET_SHMEDIA_FPU"
12345 "fcmpun.s %1, %2, %0"
12346 [(set_attr "type" "fcmp_media")])
12348 (define_expand "cbranchsf4"
12350 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12351 [(match_operand:SF 1 "arith_operand" "")
12352 (match_operand:SF 2 "arith_operand" "")])
12353 (match_operand 3 "" "")
12355 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12357 if (TARGET_SHMEDIA)
12358 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12361 sh_emit_compare_and_branch (operands, SFmode);
12365 (define_expand "negsf2"
12366 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12367 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12368 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12372 expand_sf_unop (&gen_negsf2_i, operands);
12377 (define_insn "*negsf2_media"
12378 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12379 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12380 "TARGET_SHMEDIA_FPU"
12382 [(set_attr "type" "fmove_media")])
12384 (define_insn "negsf2_i"
12385 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12386 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12387 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12390 [(set_attr "type" "fmove")
12391 (set_attr "fp_mode" "single")])
12393 (define_expand "sqrtsf2"
12394 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12395 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12396 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12400 expand_sf_unop (&gen_sqrtsf2_i, operands);
12405 (define_insn "*sqrtsf2_media"
12406 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12407 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12408 "TARGET_SHMEDIA_FPU"
12410 [(set_attr "type" "fdiv_media")])
12412 (define_insn "sqrtsf2_i"
12413 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12414 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12415 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12418 [(set_attr "type" "fdiv")
12419 (set_attr "fp_mode" "single")])
12421 (define_insn "rsqrtsf2"
12422 [(set (match_operand:SF 0 "register_operand" "=f")
12423 (div:SF (match_operand:SF 1 "immediate_operand" "i")
12424 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
12425 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12426 "TARGET_FPU_ANY && TARGET_FSRRA
12427 && operands[1] == CONST1_RTX (SFmode)"
12429 [(set_attr "type" "fsrra")
12430 (set_attr "fp_mode" "single")])
12432 ;; When the sincos pattern is defined, the builtin functions sin and cos
12433 ;; will be expanded to the sincos pattern and one of the output values will
12435 (define_expand "sincossf3"
12436 [(set (match_operand:SF 0 "nonimmediate_operand")
12437 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
12438 (set (match_operand:SF 1 "nonimmediate_operand")
12439 (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
12440 "TARGET_FPU_ANY && TARGET_FSCA"
12442 rtx scaled = gen_reg_rtx (SFmode);
12443 rtx truncated = gen_reg_rtx (SImode);
12444 rtx fsca = gen_reg_rtx (V2SFmode);
12445 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12447 emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12448 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
12449 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
12450 get_fpscr_rtx ()));
12452 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
12453 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
12457 (define_insn_and_split "fsca"
12458 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12460 (unspec:SF [(mult:SF
12461 (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12462 (match_operand:SF 2 "fsca_scale_factor" "i"))
12464 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12466 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12467 "TARGET_FPU_ANY && TARGET_FSCA"
12469 "&& !fpul_operand (operands[1], SImode)"
12472 /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12473 to a simple reg, otherwise reload will have trouble reloading the
12474 pseudo into fpul. */
12475 rtx x = XEXP (operands[1], 0);
12476 while (x != NULL_RTX && !fpul_operand (x, SImode))
12478 gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12482 gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12483 emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
12486 [(set_attr "type" "fsca")
12487 (set_attr "fp_mode" "single")])
12489 (define_expand "abssf2"
12490 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12491 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12492 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12496 expand_sf_unop (&gen_abssf2_i, operands);
12501 (define_insn "*abssf2_media"
12502 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12503 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12504 "TARGET_SHMEDIA_FPU"
12506 [(set_attr "type" "fmove_media")])
12508 (define_insn "abssf2_i"
12509 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12510 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12511 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12514 [(set_attr "type" "fmove")
12515 (set_attr "fp_mode" "single")])
12517 (define_expand "adddf3"
12518 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12519 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12520 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12521 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12523 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12525 expand_df_binop (&gen_adddf3_i, operands);
12530 (define_insn "*adddf3_media"
12531 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12532 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12533 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12534 "TARGET_SHMEDIA_FPU"
12535 "fadd.d %1, %2, %0"
12536 [(set_attr "type" "dfparith_media")])
12538 (define_insn "adddf3_i"
12539 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12540 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12541 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12542 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12543 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12545 [(set_attr "type" "dfp_arith")
12546 (set_attr "fp_mode" "double")])
12548 (define_expand "subdf3"
12549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12550 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12551 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12552 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12554 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12556 expand_df_binop (&gen_subdf3_i, operands);
12561 (define_insn "*subdf3_media"
12562 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12563 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12564 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12565 "TARGET_SHMEDIA_FPU"
12566 "fsub.d %1, %2, %0"
12567 [(set_attr "type" "dfparith_media")])
12569 (define_insn "subdf3_i"
12570 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12571 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12572 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12573 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12574 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12576 [(set_attr "type" "dfp_arith")
12577 (set_attr "fp_mode" "double")])
12579 (define_expand "muldf3"
12580 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12581 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12582 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12583 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12585 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12587 expand_df_binop (&gen_muldf3_i, operands);
12592 (define_insn "*muldf3_media"
12593 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12594 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12595 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12596 "TARGET_SHMEDIA_FPU"
12597 "fmul.d %1, %2, %0"
12598 [(set_attr "type" "dfmul_media")])
12600 (define_insn "muldf3_i"
12601 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12602 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12603 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12604 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12605 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12607 [(set_attr "type" "dfp_mul")
12608 (set_attr "fp_mode" "double")])
12610 (define_expand "divdf3"
12611 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12612 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12613 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12614 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12616 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12618 expand_df_binop (&gen_divdf3_i, operands);
12623 (define_insn "*divdf3_media"
12624 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12625 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12626 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12627 "TARGET_SHMEDIA_FPU"
12628 "fdiv.d %1, %2, %0"
12629 [(set_attr "type" "dfdiv_media")])
12631 (define_insn "divdf3_i"
12632 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12633 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12634 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12635 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12636 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12638 [(set_attr "type" "dfdiv")
12639 (set_attr "fp_mode" "double")])
12641 (define_insn "floatdidf2"
12642 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12643 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12644 "TARGET_SHMEDIA_FPU"
12646 [(set_attr "type" "dfpconv_media")])
12648 (define_expand "floatsidf2"
12649 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12650 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
12651 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12653 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12655 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
12656 get_fpscr_rtx ()));
12661 (define_insn "*floatsidf2_media"
12662 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12663 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12664 "TARGET_SHMEDIA_FPU"
12666 [(set_attr "type" "dfpconv_media")])
12668 (define_insn "floatsidf2_i"
12669 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12670 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
12671 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12672 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12674 [(set_attr "type" "dfp_conv")
12675 (set_attr "fp_mode" "double")])
12677 (define_insn "fix_truncdfdi2"
12678 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12679 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12680 "TARGET_SHMEDIA_FPU"
12682 [(set_attr "type" "dfpconv_media")])
12684 (define_expand "fix_truncdfsi2"
12685 [(set (match_operand:SI 0 "fpul_operand" "")
12686 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12687 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12689 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12691 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
12692 get_fpscr_rtx ()));
12697 (define_insn "*fix_truncdfsi2_media"
12698 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12699 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12700 "TARGET_SHMEDIA_FPU"
12702 [(set_attr "type" "dfpconv_media")])
12704 (define_insn "fix_truncdfsi2_i"
12705 [(set (match_operand:SI 0 "fpul_operand" "=y")
12706 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12707 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12708 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12710 [(set_attr "type" "dfp_conv")
12711 (set_attr "dfp_comp" "no")
12712 (set_attr "fp_mode" "double")])
12714 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
12715 ;; fix_truncdfsi2_i.
12716 ;; (define_insn "fix_truncdfsi2_i4"
12717 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12718 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12719 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12720 ;; (clobber (reg:SI FPUL_REG))]
12723 ;; [(set_attr "length" "4")
12724 ;; (set_attr "fp_mode" "double")])
12727 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12728 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12729 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12730 ;; (clobber (reg:SI FPUL_REG))]
12732 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12733 ;; (use (match_dup 2))])
12734 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
12736 (define_insn "cmpgtdf_t"
12737 [(set (reg:SI T_REG)
12738 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
12739 (match_operand:DF 1 "arith_reg_operand" "f")))
12740 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12741 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12743 [(set_attr "type" "dfp_cmp")
12744 (set_attr "fp_mode" "double")])
12746 (define_insn "cmpeqdf_t"
12747 [(set (reg:SI T_REG)
12748 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12749 (match_operand:DF 1 "arith_reg_operand" "f")))
12750 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12751 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12753 [(set_attr "type" "dfp_cmp")
12754 (set_attr "fp_mode" "double")])
12756 (define_insn "*ieee_ccmpeqdf_t"
12757 [(set (reg:SI T_REG)
12758 (ior:SI (reg:SI T_REG)
12759 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12760 (match_operand:DF 1 "arith_reg_operand" "f"))))
12761 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12762 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12764 return output_ieee_ccmpeq (insn, operands);
12766 [(set_attr "length" "4")
12767 (set_attr "fp_mode" "double")])
12769 (define_insn "cmpeqdf_media"
12770 [(set (match_operand:SI 0 "register_operand" "=r")
12771 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12772 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12773 "TARGET_SHMEDIA_FPU"
12774 "fcmpeq.d %1,%2,%0"
12775 [(set_attr "type" "fcmp_media")])
12777 (define_insn "cmpgtdf_media"
12778 [(set (match_operand:SI 0 "register_operand" "=r")
12779 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12780 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12781 "TARGET_SHMEDIA_FPU"
12782 "fcmpgt.d %1,%2,%0"
12783 [(set_attr "type" "fcmp_media")])
12785 (define_insn "cmpgedf_media"
12786 [(set (match_operand:SI 0 "register_operand" "=r")
12787 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12788 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12789 "TARGET_SHMEDIA_FPU"
12790 "fcmpge.d %1,%2,%0"
12791 [(set_attr "type" "fcmp_media")])
12793 (define_insn "cmpundf_media"
12794 [(set (match_operand:SI 0 "register_operand" "=r")
12795 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12796 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12797 "TARGET_SHMEDIA_FPU"
12798 "fcmpun.d %1,%2,%0"
12799 [(set_attr "type" "fcmp_media")])
12801 (define_expand "cbranchdf4"
12803 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12804 [(match_operand:DF 1 "arith_operand" "")
12805 (match_operand:DF 2 "arith_operand" "")])
12806 (match_operand 3 "" "")
12808 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12810 if (TARGET_SHMEDIA)
12811 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12814 sh_emit_compare_and_branch (operands, DFmode);
12819 (define_expand "negdf2"
12820 [(set (match_operand:DF 0 "arith_reg_operand" "")
12821 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12822 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12824 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12826 expand_df_unop (&gen_negdf2_i, operands);
12831 (define_insn "*negdf2_media"
12832 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12833 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12834 "TARGET_SHMEDIA_FPU"
12836 [(set_attr "type" "fmove_media")])
12838 (define_insn "negdf2_i"
12839 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12840 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12841 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12842 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12844 [(set_attr "type" "fmove")
12845 (set_attr "fp_mode" "double")])
12847 (define_expand "sqrtdf2"
12848 [(set (match_operand:DF 0 "arith_reg_operand" "")
12849 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12850 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12852 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12854 expand_df_unop (&gen_sqrtdf2_i, operands);
12859 (define_insn "*sqrtdf2_media"
12860 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12861 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12862 "TARGET_SHMEDIA_FPU"
12864 [(set_attr "type" "dfdiv_media")])
12866 (define_insn "sqrtdf2_i"
12867 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12868 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12869 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12870 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12872 [(set_attr "type" "dfdiv")
12873 (set_attr "fp_mode" "double")])
12875 (define_expand "absdf2"
12876 [(set (match_operand:DF 0 "arith_reg_operand" "")
12877 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12878 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12880 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12882 expand_df_unop (&gen_absdf2_i, operands);
12887 (define_insn "*absdf2_media"
12888 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12889 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12890 "TARGET_SHMEDIA_FPU"
12892 [(set_attr "type" "fmove_media")])
12894 (define_insn "absdf2_i"
12895 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12896 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12897 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12898 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12900 [(set_attr "type" "fmove")
12901 (set_attr "fp_mode" "double")])
12903 (define_expand "extendsfdf2"
12904 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12905 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
12906 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12908 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12910 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
12911 get_fpscr_rtx ()));
12916 (define_insn "*extendsfdf2_media"
12917 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12918 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12919 "TARGET_SHMEDIA_FPU"
12921 [(set_attr "type" "dfpconv_media")])
12923 (define_insn "extendsfdf2_i4"
12924 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12925 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
12926 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12927 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12929 [(set_attr "type" "fp")
12930 (set_attr "fp_mode" "double")])
12932 (define_expand "truncdfsf2"
12933 [(set (match_operand:SF 0 "fpul_operand" "")
12934 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12935 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12937 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12939 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
12940 get_fpscr_rtx ()));
12945 (define_insn "*truncdfsf2_media"
12946 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12947 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12948 "TARGET_SHMEDIA_FPU"
12950 [(set_attr "type" "dfpconv_media")])
12952 (define_insn "truncdfsf2_i4"
12953 [(set (match_operand:SF 0 "fpul_operand" "=y")
12954 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12955 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12956 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12958 [(set_attr "type" "fp")
12959 (set_attr "fp_mode" "double")])
12961 ;; Bit field extract patterns. These give better code for packed bitfields,
12962 ;; because they allow auto-increment addresses to be generated.
12964 (define_expand "insv"
12965 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
12966 (match_operand:SI 1 "immediate_operand" "")
12967 (match_operand:SI 2 "immediate_operand" ""))
12968 (match_operand:SI 3 "general_operand" ""))]
12969 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
12971 rtx addr_target, orig_address, shift_reg, qi_val;
12972 HOST_WIDE_INT bitsize, size, v = 0;
12973 rtx x = operands[3];
12975 if (TARGET_SH2A && TARGET_BITOPS
12976 && (satisfies_constraint_Sbw (operands[0])
12977 || satisfies_constraint_Sbv (operands[0]))
12978 && satisfies_constraint_M (operands[1])
12979 && satisfies_constraint_K03 (operands[2]))
12981 if (satisfies_constraint_N (operands[3]))
12983 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
12986 else if (satisfies_constraint_M (operands[3]))
12988 emit_insn (gen_bset_m2a (operands[0], operands[2]));
12991 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
12992 && satisfies_constraint_M (operands[1]))
12994 emit_insn (gen_bst_m2a (operands[0], operands[2]));
12997 else if (REG_P (operands[3])
12998 && satisfies_constraint_M (operands[1]))
13000 emit_insn (gen_bld_reg (operands[3], const0_rtx));
13001 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13005 /* ??? expmed doesn't care for non-register predicates. */
13006 if (! memory_operand (operands[0], VOIDmode)
13007 || ! immediate_operand (operands[1], VOIDmode)
13008 || ! immediate_operand (operands[2], VOIDmode)
13009 || ! general_operand (x, VOIDmode))
13011 /* If this isn't a 16 / 24 / 32 bit field, or if
13012 it doesn't start on a byte boundary, then fail. */
13013 bitsize = INTVAL (operands[1]);
13014 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13015 || (INTVAL (operands[2]) % 8) != 0)
13018 size = bitsize / 8;
13019 orig_address = XEXP (operands[0], 0);
13020 shift_reg = gen_reg_rtx (SImode);
13021 if (CONST_INT_P (x))
13024 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13028 emit_insn (gen_movsi (shift_reg, operands[3]));
13029 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13031 addr_target = copy_addr_to_reg (plus_constant (Pmode,
13032 orig_address, size - 1));
13034 operands[0] = replace_equiv_address (operands[0], addr_target);
13035 emit_insn (gen_movqi (operands[0], qi_val));
13039 if (CONST_INT_P (x))
13041 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13044 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13045 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13047 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13048 emit_insn (gen_movqi (operands[0], qi_val));
13054 (define_insn "movua"
13055 [(set (match_operand:SI 0 "register_operand" "=z")
13056 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13060 [(set_attr "type" "movua")])
13062 ;; We shouldn't need this, but cse replaces increments with references
13063 ;; to other regs before flow has a chance to create post_inc
13064 ;; addressing modes, and only postreload's cse_move2add brings the
13065 ;; increments back to a usable form.
13067 [(set (match_operand:SI 0 "register_operand" "")
13068 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
13069 (const_int 32) (const_int 0)))
13070 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13071 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
13072 [(set (match_operand:SI 0 "register_operand" "")
13073 (sign_extract:SI (mem:SI (post_inc:SI
13074 (match_operand:SI 1 "register_operand" "")))
13075 (const_int 32) (const_int 0)))]
13078 (define_expand "extv"
13079 [(set (match_operand:SI 0 "register_operand" "")
13080 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13081 (match_operand 2 "const_int_operand" "")
13082 (match_operand 3 "const_int_operand" "")))]
13083 "TARGET_SH4A_ARCH || TARGET_SH2A"
13085 if (TARGET_SH2A && TARGET_BITOPS
13086 && (satisfies_constraint_Sbw (operands[1])
13087 || satisfies_constraint_Sbv (operands[1]))
13088 && satisfies_constraint_M (operands[2])
13089 && satisfies_constraint_K03 (operands[3]))
13091 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
13092 if (REGNO (operands[0]) != T_REG)
13093 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13096 if (TARGET_SH4A_ARCH
13097 && INTVAL (operands[2]) == 32
13098 && INTVAL (operands[3]) == 0
13099 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13101 rtx src = adjust_address (operands[1], BLKmode, 0);
13102 set_mem_size (src, 4);
13103 emit_insn (gen_movua (operands[0], src));
13110 (define_expand "extzv"
13111 [(set (match_operand:SI 0 "register_operand" "")
13112 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13113 (match_operand 2 "const_int_operand" "")
13114 (match_operand 3 "const_int_operand" "")))]
13115 "TARGET_SH4A_ARCH || TARGET_SH2A"
13117 if (TARGET_SH2A && TARGET_BITOPS
13118 && (satisfies_constraint_Sbw (operands[1])
13119 || satisfies_constraint_Sbv (operands[1]))
13120 && satisfies_constraint_M (operands[2])
13121 && satisfies_constraint_K03 (operands[3]))
13123 emit_insn (gen_bld_m2a (operands[1], operands[3]));
13124 if (REGNO (operands[0]) != T_REG)
13125 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13128 if (TARGET_SH4A_ARCH
13129 && INTVAL (operands[2]) == 32
13130 && INTVAL (operands[3]) == 0
13131 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13133 rtx src = adjust_address (operands[1], BLKmode, 0);
13134 set_mem_size (src, 4);
13135 emit_insn (gen_movua (operands[0], src));
13142 ;; SH2A instructions for bitwise operations.
13144 ;; Clear a bit in a memory location.
13145 (define_insn "bclr_m2a"
13146 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13148 (not:QI (ashift:QI (const_int 1)
13149 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13151 "TARGET_SH2A && TARGET_BITOPS"
13154 bclr.b %1,@(0,%t0)"
13155 [(set_attr "length" "4,4")])
13157 (define_insn "bclrmem_m2a"
13158 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13159 (and:QI (match_dup 0)
13160 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
13161 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
13164 bclr.b %W1,@(0,%t0)"
13165 [(set_attr "length" "4,4")])
13167 ;; Set a bit in a memory location.
13168 (define_insn "bset_m2a"
13169 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13171 (ashift:QI (const_int 1)
13172 (match_operand:QI 1 "const_int_operand" "K03,K03"))
13174 "TARGET_SH2A && TARGET_BITOPS"
13177 bset.b %1,@(0,%t0)"
13178 [(set_attr "length" "4,4")])
13180 (define_insn "bsetmem_m2a"
13181 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13182 (ior:QI (match_dup 0)
13183 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
13184 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
13187 bset.b %V1,@(0,%t0)"
13188 [(set_attr "length" "4,4")])
13190 ;;; Transfer the contents of the T bit to a specified bit of memory.
13191 (define_insn "bst_m2a"
13192 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
13193 (if_then_else (eq (reg:SI T_REG) (const_int 0))
13195 (not:QI (ashift:QI (const_int 1)
13196 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13199 (ashift:QI (const_int 1) (match_dup 1))
13201 "TARGET_SH2A && TARGET_BITOPS"
13205 [(set_attr "length" "4")])
13207 ;; Store a specified bit of memory in the T bit.
13208 (define_insn "bld_m2a"
13209 [(set (reg:SI T_REG)
13211 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13213 (match_operand 1 "const_int_operand" "K03,K03")))]
13214 "TARGET_SH2A && TARGET_BITOPS"
13218 [(set_attr "length" "4,4")])
13220 ;; Store a specified bit of memory in the T bit.
13221 (define_insn "bldsign_m2a"
13222 [(set (reg:SI T_REG)
13224 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13226 (match_operand 1 "const_int_operand" "K03,K03")))]
13227 "TARGET_SH2A && TARGET_BITOPS"
13231 [(set_attr "length" "4,4")])
13233 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13234 (define_insn "bld_reg"
13235 [(set (reg:SI T_REG)
13236 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13238 (match_operand 1 "const_int_operand" "K03")))]
13242 (define_insn "*bld_regqi"
13243 [(set (reg:SI T_REG)
13244 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13246 (match_operand 1 "const_int_operand" "K03")))]
13250 ;; Take logical and of a specified bit of memory with the T bit and
13251 ;; store its result in the T bit.
13252 (define_insn "band_m2a"
13253 [(set (reg:SI T_REG)
13254 (and:SI (reg:SI T_REG)
13256 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13258 (match_operand 1 "const_int_operand" "K03,K03"))))]
13259 "TARGET_SH2A && TARGET_BITOPS"
13262 band.b %1,@(0,%t0)"
13263 [(set_attr "length" "4,4")])
13265 (define_insn "bandreg_m2a"
13266 [(set (match_operand:SI 0 "register_operand" "=r,r")
13267 (and:SI (zero_extract:SI
13268 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13270 (match_operand 2 "const_int_operand" "K03,K03"))
13271 (match_operand:SI 3 "register_operand" "r,r")))]
13272 "TARGET_SH2A && TARGET_BITOPS"
13274 static const char* alt[] =
13276 "band.b %2,%1" "\n"
13279 "band.b %2,@(0,%t1)" "\n"
13282 return alt[which_alternative];
13284 [(set_attr "length" "6,6")])
13286 ;; Take logical or of a specified bit of memory with the T bit and
13287 ;; store its result in the T bit.
13288 (define_insn "bor_m2a"
13289 [(set (reg:SI T_REG)
13290 (ior:SI (reg:SI T_REG)
13292 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13294 (match_operand 1 "const_int_operand" "K03,K03"))))]
13295 "TARGET_SH2A && TARGET_BITOPS"
13299 [(set_attr "length" "4,4")])
13301 (define_insn "borreg_m2a"
13302 [(set (match_operand:SI 0 "register_operand" "=r,r")
13303 (ior:SI (zero_extract:SI
13304 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13306 (match_operand 2 "const_int_operand" "K03,K03"))
13307 (match_operand:SI 3 "register_operand" "=r,r")))]
13308 "TARGET_SH2A && TARGET_BITOPS"
13310 static const char* alt[] =
13315 "bor.b %2,@(0,%t1)" "\n"
13318 return alt[which_alternative];
13320 [(set_attr "length" "6,6")])
13322 ;; Take exclusive or of a specified bit of memory with the T bit and
13323 ;; store its result in the T bit.
13324 (define_insn "bxor_m2a"
13325 [(set (reg:SI T_REG)
13326 (xor:SI (reg:SI T_REG)
13328 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13330 (match_operand 1 "const_int_operand" "K03,K03"))))]
13331 "TARGET_SH2A && TARGET_BITOPS"
13334 bxor.b %1,@(0,%t0)"
13335 [(set_attr "length" "4,4")])
13337 (define_insn "bxorreg_m2a"
13338 [(set (match_operand:SI 0 "register_operand" "=r,r")
13339 (xor:SI (zero_extract:SI
13340 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13342 (match_operand 2 "const_int_operand" "K03,K03"))
13343 (match_operand:SI 3 "register_operand" "=r,r")))]
13344 "TARGET_SH2A && TARGET_BITOPS"
13346 static const char* alt[] =
13348 "bxor.b %2,%1" "\n"
13351 "bxor.b %2,@(0,%t1)" "\n"
13354 return alt[which_alternative];
13356 [(set_attr "length" "6,6")])
13359 ;; -------------------------------------------------------------------------
13361 ;; -------------------------------------------------------------------------
13362 ;; This matches cases where the bit in a memory location is set.
13364 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13365 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13367 (ior:SI (match_dup 0)
13368 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
13370 (match_operand 3 "arith_reg_operand" "r,r"))]
13371 "TARGET_SH2A && TARGET_BITOPS
13372 && satisfies_constraint_Pso (operands[2])
13373 && REGNO (operands[0]) == REGNO (operands[3])"
13374 [(set (match_dup 1)
13375 (ior:QI (match_dup 1)
13379 ;; This matches cases where the bit in a memory location is cleared.
13381 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13382 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13384 (and:SI (match_dup 0)
13385 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
13387 (match_operand 3 "arith_reg_operand" "r,r"))]
13388 "TARGET_SH2A && TARGET_BITOPS
13389 && satisfies_constraint_Psz (operands[2])
13390 && REGNO (operands[0]) == REGNO (operands[3])"
13391 [(set (match_dup 1)
13392 (and:QI (match_dup 1)
13396 ;; This matches cases where a stack pointer increment at the start of the
13397 ;; epilogue combines with a stack slot read loading the return value.
13400 [(set (match_operand:SI 0 "arith_reg_operand" "")
13401 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13402 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13403 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13406 ;; See the comment on the dt combiner pattern above.
13409 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13410 (plus:SI (match_dup 0)
13412 (set (reg:SI T_REG)
13413 (eq:SI (match_dup 0)
13418 ;; The following peepholes fold load sequences for which reload was not
13419 ;; able to generate a displacement addressing move insn.
13420 ;; This can happen when reload has to transform a move insn
13421 ;; without displacement into one with displacement. Or when reload can't
13422 ;; fit a displacement into the insn's constraints. In the latter case, the
13423 ;; load destination reg remains at r0, which reload compensates by inserting
13424 ;; another mov insn.
13428 ;; mov.{b,w} @(r0,r15),r0
13431 ;; mov.{b,w} @(54,r15),r3
13434 [(set (match_operand:SI 0 "arith_reg_dest" "")
13435 (match_operand:SI 1 "const_int_operand" ""))
13436 (set (match_operand:SI 2 "arith_reg_dest" "")
13438 (mem:QI (plus:SI (match_dup 0)
13439 (match_operand:SI 3 "arith_reg_operand" "")))))
13440 (set (match_operand:QI 4 "arith_reg_dest" "")
13441 (match_operand:QI 5 "arith_reg_operand" ""))]
13443 && sh_legitimate_index_p (QImode, operands[1], true, true)
13444 && REGNO (operands[2]) == REGNO (operands[5])
13445 && peep2_reg_dead_p (3, operands[5])"
13446 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13450 [(set (match_operand:SI 0 "arith_reg_dest" "")
13451 (match_operand:SI 1 "const_int_operand" ""))
13452 (set (match_operand:SI 2 "arith_reg_dest" "")
13454 (mem:HI (plus:SI (match_dup 0)
13455 (match_operand:SI 3 "arith_reg_operand" "")))))
13456 (set (match_operand:HI 4 "arith_reg_dest" "")
13457 (match_operand:HI 5 "arith_reg_operand" ""))]
13459 && sh_legitimate_index_p (HImode, operands[1], true, true)
13460 && REGNO (operands[2]) == REGNO (operands[5])
13461 && peep2_reg_dead_p (3, operands[5])"
13462 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13467 ;; mov.{b,w} @(r0,r15),r1
13469 ;; mov.{b,w} @(54,r15),r1
13472 [(set (match_operand:SI 0 "arith_reg_dest" "")
13473 (match_operand:SI 1 "const_int_operand" ""))
13474 (set (match_operand:SI 2 "arith_reg_dest" "")
13476 (mem:QI (plus:SI (match_dup 0)
13477 (match_operand:SI 3 "arith_reg_operand" "")))))]
13479 && sh_legitimate_index_p (QImode, operands[1], true, true)
13480 && (peep2_reg_dead_p (2, operands[0])
13481 || REGNO (operands[0]) == REGNO (operands[2]))"
13482 [(set (match_dup 2)
13483 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13487 [(set (match_operand:SI 0 "arith_reg_dest" "")
13488 (match_operand:SI 1 "const_int_operand" ""))
13489 (set (match_operand:SI 2 "arith_reg_dest" "")
13491 (mem:HI (plus:SI (match_dup 0)
13492 (match_operand:SI 3 "arith_reg_operand" "")))))]
13494 && sh_legitimate_index_p (HImode, operands[1], true, true)
13495 && (peep2_reg_dead_p (2, operands[0])
13496 || REGNO (operands[0]) == REGNO (operands[2]))"
13497 [(set (match_dup 2)
13498 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13502 ;; mov.{b,w} @(r0,r15),r0
13505 ;; mov.{b,w} @(r0,r15),r3
13507 ;; This can happen when initially a displacement address is picked, where
13508 ;; the destination reg is fixed to r0, and then the address is transformed
13509 ;; into 'r0 + reg'.
13511 [(set (match_operand:SI 0 "arith_reg_dest" "")
13513 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13514 (match_operand:SI 2 "arith_reg_operand" "")))))
13515 (set (match_operand:QI 3 "arith_reg_dest" "")
13516 (match_operand:QI 4 "arith_reg_operand" ""))]
13518 && REGNO (operands[0]) == REGNO (operands[4])
13519 && peep2_reg_dead_p (2, operands[0])"
13520 [(set (match_dup 3)
13521 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13525 [(set (match_operand:SI 0 "arith_reg_dest" "")
13527 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13528 (match_operand:SI 2 "arith_reg_operand" "")))))
13529 (set (match_operand:HI 3 "arith_reg_dest" "")
13530 (match_operand:HI 4 "arith_reg_operand" ""))]
13532 && REGNO (operands[0]) == REGNO (operands[4])
13533 && peep2_reg_dead_p (2, operands[0])"
13534 [(set (match_dup 3)
13535 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13539 [(set (match_operand:SI 0 "register_operand" "=r")
13540 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13541 (set (mem:SF (match_dup 0))
13542 (match_operand:SF 2 "general_movsrc_operand" ""))]
13543 "TARGET_SH1 && REGNO (operands[0]) == 0
13544 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13545 || (GET_CODE (operands[2]) == SUBREG
13546 && REGNO (SUBREG_REG (operands[2])) < 16))
13547 && reg_unused_after (operands[0], insn)"
13548 "mov.l %2,@(%0,%1)")
13551 [(set (match_operand:SI 0 "register_operand" "=r")
13552 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13553 (set (match_operand:SF 2 "general_movdst_operand" "")
13555 (mem:SF (match_dup 0)))]
13556 "TARGET_SH1 && REGNO (operands[0]) == 0
13557 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13558 || (GET_CODE (operands[2]) == SUBREG
13559 && REGNO (SUBREG_REG (operands[2])) < 16))
13560 && reg_unused_after (operands[0], insn)"
13561 "mov.l @(%0,%1),%2")
13564 [(set (match_operand:SI 0 "register_operand" "=r")
13565 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13566 (set (mem:SF (match_dup 0))
13567 (match_operand:SF 2 "general_movsrc_operand" ""))]
13568 "TARGET_SH2E && REGNO (operands[0]) == 0
13569 && ((REG_P (operands[2])
13570 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13571 || (GET_CODE (operands[2]) == SUBREG
13572 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13573 && reg_unused_after (operands[0], insn)"
13574 "fmov{.s|} %2,@(%0,%1)")
13577 [(set (match_operand:SI 0 "register_operand" "=r")
13578 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13579 (set (match_operand:SF 2 "general_movdst_operand" "")
13581 (mem:SF (match_dup 0)))]
13582 "TARGET_SH2E && REGNO (operands[0]) == 0
13583 && ((REG_P (operands[2])
13584 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13585 || (GET_CODE (operands[2]) == SUBREG
13586 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13587 && reg_unused_after (operands[0], insn)"
13588 "fmov{.s|} @(%0,%1),%2")
13590 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13591 (define_insn "sp_switch_1"
13592 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
13595 return "mov.l r0,@-r15" "\n"
13596 " mov.l %0,r0" "\n"
13597 " mov.l @r0,r0" "\n"
13598 " mov.l r15,@-r0" "\n"
13601 [(set_attr "length" "10")])
13603 ;; Switch back to the original stack for interrupt functions with the
13604 ;; sp_switch attribute.
13605 (define_insn "sp_switch_2"
13609 return "mov.l @r15+,r15" "\n"
13612 [(set_attr "length" "4")])
13614 ;; Integer vector moves
13616 (define_expand "movv8qi"
13617 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
13618 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
13621 prepare_move_operands (operands, V8QImode);
13624 (define_insn "movv8qi_i"
13625 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
13626 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13628 && (register_operand (operands[0], V8QImode)
13629 || sh_register_operand (operands[1], V8QImode))"
13636 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13637 (set_attr "length" "4,4,16,4,4")])
13640 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
13641 (subreg:V8QI (const_int 0) 0))]
13643 [(set (match_dup 0)
13644 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
13645 (const_int 0) (const_int 0) (const_int 0)
13646 (const_int 0) (const_int 0)]))])
13649 [(set (match_operand 0 "arith_reg_dest" "")
13650 (match_operand 1 "sh_rep_vec" ""))]
13651 "TARGET_SHMEDIA && reload_completed
13652 && GET_MODE (operands[0]) == GET_MODE (operands[1])
13653 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
13654 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
13655 && (XVECEXP (operands[1], 0, 0) != const0_rtx
13656 || XVECEXP (operands[1], 0, 1) != const0_rtx)
13657 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
13658 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
13659 [(set (match_dup 0) (match_dup 1))
13662 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
13663 rtx elt1 = XVECEXP (operands[1], 0, 1);
13666 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
13670 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
13671 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
13673 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
13674 operands[1] = XVECEXP (operands[1], 0, 0);
13677 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
13679 = GEN_INT (TARGET_LITTLE_ENDIAN
13680 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
13681 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
13684 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
13686 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
13692 [(set (match_operand 0 "arith_reg_dest" "")
13693 (match_operand 1 "sh_const_vec" ""))]
13694 "TARGET_SHMEDIA && reload_completed
13695 && GET_MODE (operands[0]) == GET_MODE (operands[1])
13696 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
13697 [(set (match_dup 0) (match_dup 1))]
13699 rtx v = operands[1];
13700 enum machine_mode new_mode
13701 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
13703 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
13705 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
13708 (define_expand "movv2hi"
13709 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
13710 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
13713 prepare_move_operands (operands, V2HImode);
13716 (define_insn "movv2hi_i"
13717 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13718 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13720 && (register_operand (operands[0], V2HImode)
13721 || sh_register_operand (operands[1], V2HImode))"
13728 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13729 (set_attr "length" "4,4,16,4,4")
13730 (set (attr "highpart")
13731 (cond [(match_test "sh_contains_memref_p (insn)")
13732 (const_string "user")]
13733 (const_string "ignore")))])
13735 (define_expand "movv4hi"
13736 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
13737 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
13740 prepare_move_operands (operands, V4HImode);
13743 (define_insn "movv4hi_i"
13744 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13745 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13747 && (register_operand (operands[0], V4HImode)
13748 || sh_register_operand (operands[1], V4HImode))"
13755 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13756 (set_attr "length" "4,4,16,4,4")
13757 (set_attr "highpart" "depend")])
13759 (define_expand "movv2si"
13760 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
13761 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
13764 prepare_move_operands (operands, V2SImode);
13767 (define_insn "movv2si_i"
13768 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
13769 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13771 && (register_operand (operands[0], V2SImode)
13772 || sh_register_operand (operands[1], V2SImode))"
13779 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13780 (set_attr "length" "4,4,16,4,4")
13781 (set_attr "highpart" "depend")])
13783 ;; Multimedia Intrinsics
13785 (define_insn "absv2si2"
13786 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13787 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
13790 [(set_attr "type" "mcmp_media")
13791 (set_attr "highpart" "depend")])
13793 (define_insn "absv4hi2"
13794 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13795 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
13798 [(set_attr "type" "mcmp_media")
13799 (set_attr "highpart" "depend")])
13801 (define_insn "addv2si3"
13802 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13803 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13804 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13806 "madd.l %1, %2, %0"
13807 [(set_attr "type" "arith_media")
13808 (set_attr "highpart" "depend")])
13810 (define_insn "addv4hi3"
13811 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13812 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13813 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13815 "madd.w %1, %2, %0"
13816 [(set_attr "type" "arith_media")
13817 (set_attr "highpart" "depend")])
13819 (define_insn_and_split "addv2hi3"
13820 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13821 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
13822 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
13828 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13829 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13830 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13831 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13832 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13834 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
13835 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13838 [(set_attr "highpart" "must_split")])
13840 (define_insn "ssaddv2si3"
13841 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13842 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13843 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13845 "madds.l %1, %2, %0"
13846 [(set_attr "type" "mcmp_media")
13847 (set_attr "highpart" "depend")])
13849 (define_insn "usaddv8qi3"
13850 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13851 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
13852 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13854 "madds.ub %1, %2, %0"
13855 [(set_attr "type" "mcmp_media")
13856 (set_attr "highpart" "depend")])
13858 (define_insn "ssaddv4hi3"
13859 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13860 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13861 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13863 "madds.w %1, %2, %0"
13864 [(set_attr "type" "mcmp_media")
13865 (set_attr "highpart" "depend")])
13867 (define_insn "negcmpeqv8qi"
13868 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13869 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13870 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13872 "mcmpeq.b %N1, %N2, %0"
13873 [(set_attr "type" "mcmp_media")
13874 (set_attr "highpart" "depend")])
13876 (define_insn "negcmpeqv2si"
13877 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13878 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13879 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13881 "mcmpeq.l %N1, %N2, %0"
13882 [(set_attr "type" "mcmp_media")
13883 (set_attr "highpart" "depend")])
13885 (define_insn "negcmpeqv4hi"
13886 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13887 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13888 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13890 "mcmpeq.w %N1, %N2, %0"
13891 [(set_attr "type" "mcmp_media")
13892 (set_attr "highpart" "depend")])
13894 (define_insn "negcmpgtuv8qi"
13895 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13896 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13897 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13899 "mcmpgt.ub %N1, %N2, %0"
13900 [(set_attr "type" "mcmp_media")
13901 (set_attr "highpart" "depend")])
13903 (define_insn "negcmpgtv2si"
13904 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13905 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13906 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13908 "mcmpgt.l %N1, %N2, %0"
13909 [(set_attr "type" "mcmp_media")
13910 (set_attr "highpart" "depend")])
13912 (define_insn "negcmpgtv4hi"
13913 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13914 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13915 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13917 "mcmpgt.w %N1, %N2, %0"
13918 [(set_attr "type" "mcmp_media")
13919 (set_attr "highpart" "depend")])
13921 (define_insn "mcmv"
13922 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13923 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13924 (match_operand:DI 2 "arith_reg_operand" "r"))
13925 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
13926 (not:DI (match_dup 2)))))]
13929 [(set_attr "type" "arith_media")
13930 (set_attr "highpart" "depend")])
13932 (define_insn "mcnvs_lw"
13933 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13935 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
13936 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13938 "mcnvs.lw %N1, %N2, %0"
13939 [(set_attr "type" "mcmp_media")])
13941 (define_insn "mcnvs_wb"
13942 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13944 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13945 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13947 "mcnvs.wb %N1, %N2, %0"
13948 [(set_attr "type" "mcmp_media")])
13950 (define_insn "mcnvs_wub"
13951 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13953 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13954 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13956 "mcnvs.wub %N1, %N2, %0"
13957 [(set_attr "type" "mcmp_media")])
13959 (define_insn "mextr_rl"
13960 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13961 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13962 (match_operand:HI 3 "mextr_bit_offset" "i"))
13963 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13964 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
13965 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
13967 static char templ[21];
13968 sprintf (templ, "mextr%d %%N1, %%N2, %%0",
13969 (int) INTVAL (operands[3]) >> 3);
13972 [(set_attr "type" "arith_media")])
13974 (define_insn "*mextr_lr"
13975 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13976 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13977 (match_operand:HI 3 "mextr_bit_offset" "i"))
13978 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13979 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
13980 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
13982 static char templ[21];
13983 sprintf (templ, "mextr%d %%N2, %%N1, %%0",
13984 (int) INTVAL (operands[4]) >> 3);
13987 [(set_attr "type" "arith_media")])
13989 ; mextrN can be modelled with vec_select / vec_concat, but the selection
13990 ; vector then varies depending on endianness.
13991 (define_expand "mextr1"
13992 [(match_operand:DI 0 "arith_reg_dest" "")
13993 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13994 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13997 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13998 GEN_INT (1 * 8), GEN_INT (7 * 8)));
14002 (define_expand "mextr2"
14003 [(match_operand:DI 0 "arith_reg_dest" "")
14004 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14005 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14008 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14009 GEN_INT (2 * 8), GEN_INT (6 * 8)));
14013 (define_expand "mextr3"
14014 [(match_operand:DI 0 "arith_reg_dest" "")
14015 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14016 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14019 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14020 GEN_INT (3 * 8), GEN_INT (5 * 8)));
14024 (define_expand "mextr4"
14025 [(match_operand:DI 0 "arith_reg_dest" "")
14026 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14027 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14030 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14031 GEN_INT (4 * 8), GEN_INT (4 * 8)));
14035 (define_expand "mextr5"
14036 [(match_operand:DI 0 "arith_reg_dest" "")
14037 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14038 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14041 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14042 GEN_INT (5 * 8), GEN_INT (3 * 8)));
14046 (define_expand "mextr6"
14047 [(match_operand:DI 0 "arith_reg_dest" "")
14048 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14049 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14052 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14053 GEN_INT (6 * 8), GEN_INT (2 * 8)));
14057 (define_expand "mextr7"
14058 [(match_operand:DI 0 "arith_reg_dest" "")
14059 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14060 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14063 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14064 GEN_INT (7 * 8), GEN_INT (1 * 8)));
14068 (define_expand "mmacfx_wl"
14069 [(match_operand:V2SI 0 "arith_reg_dest" "")
14070 (match_operand:V2HI 1 "extend_reg_operand" "")
14071 (match_operand:V2HI 2 "extend_reg_operand" "")
14072 (match_operand:V2SI 3 "arith_reg_operand" "")]
14075 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
14076 operands[1], operands[2]));
14080 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
14082 (define_insn "mmacfx_wl_i"
14083 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14085 (match_operand:V2SI 1 "arith_reg_operand" "0")
14090 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14091 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14094 "mmacfx.wl %2, %3, %0"
14095 [(set_attr "type" "mac_media")
14096 (set_attr "highpart" "depend")])
14098 (define_expand "mmacnfx_wl"
14099 [(match_operand:V2SI 0 "arith_reg_dest" "")
14100 (match_operand:V2HI 1 "extend_reg_operand" "")
14101 (match_operand:V2HI 2 "extend_reg_operand" "")
14102 (match_operand:V2SI 3 "arith_reg_operand" "")]
14105 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
14106 operands[1], operands[2]));
14110 (define_insn "mmacnfx_wl_i"
14111 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14113 (match_operand:V2SI 1 "arith_reg_operand" "0")
14118 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14119 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14122 "mmacnfx.wl %2, %3, %0"
14123 [(set_attr "type" "mac_media")
14124 (set_attr "highpart" "depend")])
14126 (define_insn "mulv2si3"
14127 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14128 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14129 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14131 "mmul.l %1, %2, %0"
14132 [(set_attr "type" "d2mpy_media")
14133 (set_attr "highpart" "depend")])
14135 (define_insn "mulv4hi3"
14136 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14137 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14138 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14140 "mmul.w %1, %2, %0"
14141 [(set_attr "type" "dmpy_media")
14142 (set_attr "highpart" "depend")])
14144 (define_insn "mmulfx_l"
14145 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14149 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14150 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
14153 "mmulfx.l %1, %2, %0"
14154 [(set_attr "type" "d2mpy_media")
14155 (set_attr "highpart" "depend")])
14157 (define_insn "mmulfx_w"
14158 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14162 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14163 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14166 "mmulfx.w %1, %2, %0"
14167 [(set_attr "type" "dmpy_media")
14168 (set_attr "highpart" "depend")])
14170 (define_insn "mmulfxrp_w"
14171 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14176 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14177 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14181 "mmulfxrp.w %1, %2, %0"
14182 [(set_attr "type" "dmpy_media")
14183 (set_attr "highpart" "depend")])
14186 (define_expand "mmulhi_wl"
14187 [(match_operand:V2SI 0 "arith_reg_dest" "")
14188 (match_operand:V4HI 1 "arith_reg_operand" "")
14189 (match_operand:V4HI 2 "arith_reg_operand" "")]
14192 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
14193 (operands[0], operands[1], operands[2]));
14197 (define_expand "mmullo_wl"
14198 [(match_operand:V2SI 0 "arith_reg_dest" "")
14199 (match_operand:V4HI 1 "arith_reg_operand" "")
14200 (match_operand:V4HI 2 "arith_reg_operand" "")]
14203 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14204 (operands[0], operands[1], operands[2]));
14208 (define_insn "mmul23_wl"
14209 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14212 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14213 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14214 (parallel [(const_int 2) (const_int 3)])))]
14217 return (TARGET_LITTLE_ENDIAN
14218 ? "mmulhi.wl %1, %2, %0"
14219 : "mmullo.wl %1, %2, %0");
14221 [(set_attr "type" "dmpy_media")
14222 (set (attr "highpart")
14223 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14224 (const_string "user")))])
14226 (define_insn "mmul01_wl"
14227 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14230 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14231 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14232 (parallel [(const_int 0) (const_int 1)])))]
14235 return (TARGET_LITTLE_ENDIAN
14236 ? "mmullo.wl %1, %2, %0"
14237 : "mmulhi.wl %1, %2, %0");
14239 [(set_attr "type" "dmpy_media")
14240 (set (attr "highpart")
14241 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14242 (const_string "user")))])
14245 (define_expand "mmulsum_wq"
14246 [(match_operand:DI 0 "arith_reg_dest" "")
14247 (match_operand:V4HI 1 "arith_reg_operand" "")
14248 (match_operand:V4HI 2 "arith_reg_operand" "")
14249 (match_operand:DI 3 "arith_reg_operand" "")]
14252 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14253 operands[1], operands[2]));
14257 (define_insn "mmulsum_wq_i"
14258 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14259 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14264 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14265 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14266 (parallel [(const_int 0)]))
14267 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14268 (sign_extend:V4DI (match_dup 3)))
14269 (parallel [(const_int 1)])))
14271 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14272 (sign_extend:V4DI (match_dup 3)))
14273 (parallel [(const_int 2)]))
14274 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14275 (sign_extend:V4DI (match_dup 3)))
14276 (parallel [(const_int 3)]))))))]
14278 "mmulsum.wq %2, %3, %0"
14279 [(set_attr "type" "mac_media")])
14281 (define_expand "mperm_w"
14282 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14283 (match_operand:V4HI 1 "arith_reg_operand" "r")
14284 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14287 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14288 (operands[0], operands[1], operands[2]));
14292 ; This use of vec_select isn't exactly correct according to rtl.texi
14293 ; (because not constant), but it seems a straightforward extension.
14294 (define_insn "mperm_w_little"
14295 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14297 (match_operand:V4HI 1 "arith_reg_operand" "r")
14299 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14300 (const_int 2) (const_int 0))
14301 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14302 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14303 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14304 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14305 "mperm.w %1, %N2, %0"
14306 [(set_attr "type" "arith_media")])
14308 (define_insn "mperm_w_big"
14309 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14311 (match_operand:V4HI 1 "arith_reg_operand" "r")
14313 [(zero_extract:QI (not:QI (match_operand:QI 2
14314 "extend_reg_or_0_operand" "rZ"))
14315 (const_int 2) (const_int 0))
14316 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14317 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14318 (zero_extract:QI (not:QI (match_dup 2))
14319 (const_int 2) (const_int 6))])))]
14320 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
14321 "mperm.w %1, %N2, %0"
14322 [(set_attr "type" "arith_media")])
14324 (define_insn "mperm_w0"
14325 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14326 (vec_duplicate:V4HI (truncate:HI (match_operand 1
14327 "trunc_hi_operand" "r"))))]
14329 "mperm.w %1, r63, %0"
14330 [(set_attr "type" "arith_media")
14331 (set_attr "highpart" "ignore")])
14333 (define_expand "msad_ubq"
14334 [(match_operand:DI 0 "arith_reg_dest" "")
14335 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14336 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14337 (match_operand:DI 3 "arith_reg_operand" "")]
14340 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14341 operands[1], operands[2]));
14345 (define_insn "msad_ubq_i"
14346 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14351 (match_operand:DI 1 "arith_reg_operand" "0")
14352 (abs:DI (vec_select:DI
14355 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14357 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14358 (parallel [(const_int 0)]))))
14359 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14360 (zero_extend:V8DI (match_dup 3)))
14361 (parallel [(const_int 1)]))))
14363 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14364 (zero_extend:V8DI (match_dup 3)))
14365 (parallel [(const_int 2)])))
14366 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14367 (zero_extend:V8DI (match_dup 3)))
14368 (parallel [(const_int 3)])))))
14371 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14372 (zero_extend:V8DI (match_dup 3)))
14373 (parallel [(const_int 4)])))
14374 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14375 (zero_extend:V8DI (match_dup 3)))
14376 (parallel [(const_int 5)]))))
14378 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14379 (zero_extend:V8DI (match_dup 3)))
14380 (parallel [(const_int 6)])))
14381 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14382 (zero_extend:V8DI (match_dup 3)))
14383 (parallel [(const_int 7)])))))))]
14385 "msad.ubq %N2, %N3, %0"
14386 [(set_attr "type" "mac_media")])
14388 (define_insn "mshalds_l"
14389 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14392 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14393 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14394 (const_int 31)))))]
14396 "mshalds.l %1, %2, %0"
14397 [(set_attr "type" "mcmp_media")
14398 (set_attr "highpart" "depend")])
14400 (define_insn "mshalds_w"
14401 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14404 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14405 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14406 (const_int 15)))))]
14408 "mshalds.w %1, %2, %0"
14409 [(set_attr "type" "mcmp_media")
14410 (set_attr "highpart" "depend")])
14412 (define_insn "ashrv2si3"
14413 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14414 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14415 (match_operand:DI 2 "arith_reg_operand" "r")))]
14417 "mshard.l %1, %2, %0"
14418 [(set_attr "type" "arith_media")
14419 (set_attr "highpart" "depend")])
14421 (define_insn "ashrv4hi3"
14422 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14423 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14424 (match_operand:DI 2 "arith_reg_operand" "r")))]
14426 "mshard.w %1, %2, %0"
14427 [(set_attr "type" "arith_media")
14428 (set_attr "highpart" "depend")])
14430 (define_insn "mshards_q"
14431 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14433 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14434 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14436 "mshards.q %1, %N2, %0"
14437 [(set_attr "type" "mcmp_media")])
14439 (define_expand "mshfhi_b"
14440 [(match_operand:V8QI 0 "arith_reg_dest" "")
14441 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14442 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14445 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14446 (operands[0], operands[1], operands[2]));
14450 (define_expand "mshflo_b"
14451 [(match_operand:V8QI 0 "arith_reg_dest" "")
14452 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14453 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14456 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14457 (operands[0], operands[1], operands[2]));
14461 (define_insn "mshf4_b"
14463 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14465 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14466 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14467 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14468 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14471 return (TARGET_LITTLE_ENDIAN
14472 ? "mshfhi.b %N1, %N2, %0"
14473 : "mshflo.b %N1, %N2, %0");
14475 [(set_attr "type" "arith_media")
14476 (set (attr "highpart")
14477 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14478 (const_string "user")))])
14480 (define_insn "mshf0_b"
14482 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14484 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14485 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14486 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14487 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14490 return (TARGET_LITTLE_ENDIAN
14491 ? "mshflo.b %N1, %N2, %0"
14492 : "mshfhi.b %N1, %N2, %0");
14494 [(set_attr "type" "arith_media")
14495 (set (attr "highpart")
14496 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14497 (const_string "user")))])
14499 (define_expand "mshfhi_l"
14500 [(match_operand:V2SI 0 "arith_reg_dest" "")
14501 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14502 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14505 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14506 (operands[0], operands[1], operands[2]));
14510 (define_expand "mshflo_l"
14511 [(match_operand:V2SI 0 "arith_reg_dest" "")
14512 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14513 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14516 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14517 (operands[0], operands[1], operands[2]));
14521 (define_insn "mshf4_l"
14522 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14524 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14525 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14526 (parallel [(const_int 1) (const_int 3)])))]
14529 return (TARGET_LITTLE_ENDIAN
14530 ? "mshfhi.l %N1, %N2, %0"
14531 : "mshflo.l %N1, %N2, %0");
14533 [(set_attr "type" "arith_media")
14534 (set (attr "highpart")
14535 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14536 (const_string "user")))])
14538 (define_insn "mshf0_l"
14539 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14541 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14542 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14543 (parallel [(const_int 0) (const_int 2)])))]
14546 return (TARGET_LITTLE_ENDIAN
14547 ? "mshflo.l %N1, %N2, %0"
14548 : "mshfhi.l %N1, %N2, %0");
14550 [(set_attr "type" "arith_media")
14551 (set (attr "highpart")
14552 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14553 (const_string "user")))])
14555 (define_expand "mshfhi_w"
14556 [(match_operand:V4HI 0 "arith_reg_dest" "")
14557 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14558 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14561 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14562 (operands[0], operands[1], operands[2]));
14566 (define_expand "mshflo_w"
14567 [(match_operand:V4HI 0 "arith_reg_dest" "")
14568 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14569 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14572 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14573 (operands[0], operands[1], operands[2]));
14577 (define_insn "mshf4_w"
14578 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14580 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14581 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14582 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
14585 return (TARGET_LITTLE_ENDIAN
14586 ? "mshfhi.w %N1, %N2, %0"
14587 : "mshflo.w %N1, %N2, %0");
14589 [(set_attr "type" "arith_media")
14590 (set (attr "highpart")
14591 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14592 (const_string "user")))])
14594 (define_insn "mshf0_w"
14595 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14597 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14598 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14599 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
14602 return (TARGET_LITTLE_ENDIAN
14603 ? "mshflo.w %N1, %N2, %0"
14604 : "mshfhi.w %N1, %N2, %0");
14606 [(set_attr "type" "arith_media")
14607 (set (attr "highpart")
14608 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14609 (const_string "user")))])
14611 (define_insn "mshflo_w_x"
14612 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14614 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
14615 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
14616 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
14618 "mshflo.w %N1, %N2, %0"
14619 [(set_attr "type" "arith_media")
14620 (set_attr "highpart" "ignore")])
14622 ;; These are useful to expand ANDs and as combiner patterns.
14623 (define_insn_and_split "mshfhi_l_di"
14624 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
14625 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
14627 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
14628 (const_int -4294967296))))]
14631 mshfhi.l %N1, %N2, %0
14633 "TARGET_SHMEDIA && reload_completed
14634 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14635 [(set (match_dup 3) (match_dup 4))
14636 (set (match_dup 5) (match_dup 6))]
14638 operands[3] = gen_lowpart (SImode, operands[0]);
14639 operands[4] = gen_highpart (SImode, operands[1]);
14640 operands[5] = gen_highpart (SImode, operands[0]);
14641 operands[6] = gen_highpart (SImode, operands[2]);
14643 [(set_attr "type" "arith_media")])
14645 (define_insn "*mshfhi_l_di_rev"
14646 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14647 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14648 (const_int -4294967296))
14649 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14652 "mshfhi.l %N2, %N1, %0"
14653 [(set_attr "type" "arith_media")])
14656 [(set (match_operand:DI 0 "arith_reg_dest" "")
14657 (ior:DI (zero_extend:DI (match_operand:SI 1
14658 "extend_reg_or_0_operand" ""))
14659 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
14660 (const_int -4294967296))))
14661 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
14665 emit_insn (gen_ashldi3_media (operands[3],
14666 simplify_gen_subreg (DImode, operands[1],
14669 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
14673 (define_insn "mshflo_l_di"
14674 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14675 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14676 (const_int 4294967295))
14677 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14681 "mshflo.l %N1, %N2, %0"
14682 [(set_attr "type" "arith_media")
14683 (set_attr "highpart" "ignore")])
14685 (define_insn "*mshflo_l_di_rev"
14686 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14687 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14689 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14690 (const_int 4294967295))))]
14693 "mshflo.l %N2, %N1, %0"
14694 [(set_attr "type" "arith_media")
14695 (set_attr "highpart" "ignore")])
14697 ;; Combiner pattern for trampoline initialization.
14698 (define_insn_and_split "*double_shori"
14699 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14700 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
14702 (match_operand:DI 2 "const_int_operand" "n")))]
14704 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
14706 "rtx_equal_p (operands[0], operands[1])"
14709 HOST_WIDE_INT v = INTVAL (operands[2]);
14711 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
14712 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
14715 [(set_attr "highpart" "ignore")])
14718 (define_insn "*mshflo_l_di_x"
14719 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14720 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
14722 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14726 "mshflo.l %N1, %N2, %0"
14727 [(set_attr "type" "arith_media")
14728 (set_attr "highpart" "ignore")])
14730 (define_insn_and_split "concat_v2sf"
14731 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
14732 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
14733 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
14734 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
14738 mshflo.l %N1, %N2, %0
14741 "TARGET_SHMEDIA && reload_completed
14742 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14743 [(set (match_dup 3) (match_dup 1))
14744 (set (match_dup 4) (match_dup 2))]
14746 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
14747 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
14749 [(set_attr "type" "arith_media")
14750 (set_attr "highpart" "ignore")])
14752 (define_insn "*mshflo_l_di_x_rev"
14753 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14754 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14756 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
14759 "mshflo.l %N2, %N1, %0"
14760 [(set_attr "type" "arith_media")
14761 (set_attr "highpart" "ignore")])
14763 (define_insn "ashlv2si3"
14764 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14765 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14766 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14768 "mshlld.l %1, %2, %0"
14769 [(set_attr "type" "arith_media")
14770 (set_attr "highpart" "depend")])
14773 [(set (match_operand 0 "any_register_operand" "")
14774 (match_operator 3 "shift_operator"
14775 [(match_operand 1 "any_register_operand" "")
14776 (match_operand 2 "shift_count_reg_operand" "")]))]
14777 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
14778 [(set (match_dup 0) (match_dup 3))]
14780 rtx count = operands[2];
14781 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
14783 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
14784 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
14785 || GET_CODE (count) == TRUNCATE)
14786 count = XEXP (count, 0);
14787 inner_mode = GET_MODE (count);
14788 count = simplify_gen_subreg (outer_mode, count, inner_mode,
14789 subreg_lowpart_offset (outer_mode, inner_mode));
14790 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
14791 operands[1], count);
14794 (define_insn "ashlv4hi3"
14795 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14796 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14797 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14799 "mshlld.w %1, %2, %0"
14800 [(set_attr "type" "arith_media")
14801 (set_attr "highpart" "depend")])
14803 (define_insn "lshrv2si3"
14804 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14805 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14806 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14808 "mshlrd.l %1, %2, %0"
14809 [(set_attr "type" "arith_media")
14810 (set_attr "highpart" "depend")])
14812 (define_insn "lshrv4hi3"
14813 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14814 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14815 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14817 "mshlrd.w %1, %2, %0"
14818 [(set_attr "type" "arith_media")
14819 (set_attr "highpart" "depend")])
14821 (define_insn "subv2si3"
14822 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14823 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14824 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14826 "msub.l %N1, %2, %0"
14827 [(set_attr "type" "arith_media")
14828 (set_attr "highpart" "depend")])
14830 (define_insn "subv4hi3"
14831 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14832 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14833 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14835 "msub.w %N1, %2, %0"
14836 [(set_attr "type" "arith_media")
14837 (set_attr "highpart" "depend")])
14839 (define_insn_and_split "subv2hi3"
14840 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14841 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
14842 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
14848 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14849 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14850 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14851 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14852 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14854 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
14855 emit_insn (gen_truncdisi2 (si_dst, di_dst));
14858 [(set_attr "highpart" "must_split")])
14860 (define_insn "sssubv2si3"
14861 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14862 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14863 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14865 "msubs.l %N1, %2, %0"
14866 [(set_attr "type" "mcmp_media")
14867 (set_attr "highpart" "depend")])
14869 (define_insn "ussubv8qi3"
14870 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14871 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14872 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14874 "msubs.ub %N1, %2, %0"
14875 [(set_attr "type" "mcmp_media")
14876 (set_attr "highpart" "depend")])
14878 (define_insn "sssubv4hi3"
14879 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14880 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14881 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14883 "msubs.w %N1, %2, %0"
14884 [(set_attr "type" "mcmp_media")
14885 (set_attr "highpart" "depend")])
14887 ;; Floating Point Intrinsics
14889 (define_insn "fcosa_s"
14890 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14891 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14895 [(set_attr "type" "atrans_media")])
14897 (define_insn "fsina_s"
14898 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14899 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14903 [(set_attr "type" "atrans_media")])
14905 (define_insn "fipr"
14906 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14907 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
14908 "fp_arith_reg_operand" "f")
14909 (match_operand:V4SF 2
14910 "fp_arith_reg_operand" "f"))
14911 (parallel [(const_int 0)]))
14912 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14913 (parallel [(const_int 1)])))
14914 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14915 (parallel [(const_int 2)]))
14916 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14917 (parallel [(const_int 3)])))))]
14919 "fipr.s %1, %2, %0"
14920 [(set_attr "type" "fparith_media")])
14922 (define_insn "fsrra_s"
14923 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14924 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
14928 [(set_attr "type" "atrans_media")])
14930 (define_insn "ftrv"
14931 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
14935 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
14936 (parallel [(const_int 0) (const_int 5)
14937 (const_int 10) (const_int 15)]))
14938 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
14940 (vec_select:V4SF (match_dup 1)
14941 (parallel [(const_int 4) (const_int 9)
14942 (const_int 14) (const_int 3)]))
14943 (vec_select:V4SF (match_dup 2)
14944 (parallel [(const_int 1) (const_int 2)
14945 (const_int 3) (const_int 0)]))))
14948 (vec_select:V4SF (match_dup 1)
14949 (parallel [(const_int 8) (const_int 13)
14950 (const_int 2) (const_int 7)]))
14951 (vec_select:V4SF (match_dup 2)
14952 (parallel [(const_int 2) (const_int 3)
14953 (const_int 0) (const_int 1)])))
14955 (vec_select:V4SF (match_dup 1)
14956 (parallel [(const_int 12) (const_int 1)
14957 (const_int 6) (const_int 11)]))
14958 (vec_select:V4SF (match_dup 2)
14959 (parallel [(const_int 3) (const_int 0)
14960 (const_int 1) (const_int 2)]))))))]
14962 "ftrv.s %1, %2, %0"
14963 [(set_attr "type" "fparith_media")])
14965 (define_insn "ldhi_l"
14966 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
14968 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
14971 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
14975 [(set_attr "type" "load_media")])
14977 (define_insn "ldhi_q"
14978 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14980 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
14983 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
14987 [(set_attr "type" "load_media")])
14989 (define_insn_and_split "*ldhi_q_comb0"
14990 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14992 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
14993 "register_operand" "r")
14994 (match_operand:SI 2
14995 "ua_offset" "I06"))
14998 (plus:SI (and:SI (match_dup 1) (const_int 7))
15001 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15006 emit_insn (gen_ldhi_q (operands[0],
15007 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15011 (define_insn_and_split "*ldhi_q_comb1"
15012 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15014 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
15015 "register_operand" "r")
15016 (match_operand:SI 2
15017 "ua_offset" "I06"))
15020 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
15021 "ua_offset" "I06"))
15025 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15026 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15031 emit_insn (gen_ldhi_q (operands[0],
15032 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15036 (define_insn "ldlo_l"
15037 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15039 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15041 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
15042 (and:SI (match_dup 1) (const_int 3))))]
15045 [(set_attr "type" "load_media")])
15047 (define_insn "ldlo_q"
15048 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15050 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15052 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15053 (and:SI (match_dup 1) (const_int 7))))]
15056 [(set_attr "type" "load_media")])
15058 (define_insn_and_split "*ldlo_q_comb0"
15059 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15061 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15062 (match_operand:SI 2 "ua_offset" "I06"))
15064 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15065 (and:SI (match_dup 1) (const_int 7))))]
15066 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15071 emit_insn (gen_ldlo_q (operands[0],
15072 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15076 (define_insn_and_split "*ldlo_q_comb1"
15077 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15079 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15080 (match_operand:SI 2 "ua_offset" "I06"))
15082 (minus:SI (const_int 8)
15083 (and:SI (plus:SI (match_dup 1)
15084 (match_operand:SI 3 "ua_offset" "I06"))
15086 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
15087 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15088 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15093 emit_insn (gen_ldlo_q (operands[0],
15094 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15098 (define_insn "sthi_l"
15099 [(set (zero_extract:SI
15100 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15103 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
15105 (match_operand:SI 1 "arith_reg_operand" "r"))]
15108 [(set_attr "type" "ustore_media")])
15110 ;; All unaligned stores are considered to be 'narrow' because they typically
15111 ;; operate on less that a quadword, and when they operate on a full quadword,
15112 ;; the vanilla store high / store low sequence will cause a stall if not
15113 ;; scheduled apart.
15114 (define_insn "sthi_q"
15115 [(set (zero_extract:DI
15116 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15119 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15121 (match_operand:DI 1 "arith_reg_operand" "r"))]
15124 [(set_attr "type" "ustore_media")])
15126 (define_insn_and_split "*sthi_q_comb0"
15127 [(set (zero_extract:DI
15128 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
15129 "register_operand" "r")
15130 (match_operand:SI 1 "ua_offset"
15134 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15136 (match_operand:DI 2 "arith_reg_operand" "r"))]
15137 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15142 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15147 (define_insn_and_split "*sthi_q_comb1"
15148 [(set (zero_extract:DI
15149 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
15150 "register_operand" "r")
15151 (match_operand:SI 1 "ua_offset"
15155 (plus:SI (and:SI (plus:SI (match_dup 0)
15156 (match_operand:SI 2 "ua_offset" "I06"))
15160 (match_operand:DI 3 "arith_reg_operand" "r"))]
15161 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
15162 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15167 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15172 ;; This is highpart user because the address is used as full 64 bit.
15173 (define_insn "stlo_l"
15174 [(set (zero_extract:SI
15175 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15177 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
15178 (and:SI (match_dup 0) (const_int 3)))
15179 (match_operand:SI 1 "arith_reg_operand" "r"))]
15182 [(set_attr "type" "ustore_media")])
15184 (define_insn "stlo_q"
15185 [(set (zero_extract:DI
15186 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15188 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15189 (and:SI (match_dup 0) (const_int 7)))
15190 (match_operand:DI 1 "arith_reg_operand" "r"))]
15193 [(set_attr "type" "ustore_media")])
15195 (define_insn_and_split "*stlo_q_comb0"
15196 [(set (zero_extract:DI
15197 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15198 (match_operand:SI 1 "ua_offset" "I06"))
15200 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15201 (and:SI (match_dup 0) (const_int 7)))
15202 (match_operand:DI 2 "arith_reg_operand" "r"))]
15203 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15208 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15213 (define_insn_and_split "*stlo_q_comb1"
15214 [(set (zero_extract:DI
15215 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15216 (match_operand:SI 1 "ua_offset" "I06"))
15218 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
15219 (match_operand:SI 2
15220 "ua_offset" "I06"))
15222 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15223 (match_operand:DI 3 "arith_reg_operand" "r"))]
15224 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15229 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15234 (define_insn "ldhi_l64"
15235 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15237 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15240 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15244 [(set_attr "type" "load_media")])
15246 (define_insn "ldhi_q64"
15247 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15249 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15252 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15256 [(set_attr "type" "load_media")])
15258 (define_insn "ldlo_l64"
15259 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15261 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15263 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15264 (and:DI (match_dup 1) (const_int 3))))]
15267 [(set_attr "type" "load_media")])
15269 (define_insn "ldlo_q64"
15270 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15272 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15274 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15275 (and:DI (match_dup 1) (const_int 7))))]
15278 [(set_attr "type" "load_media")])
15280 (define_insn "sthi_l64"
15281 [(set (zero_extract:SI
15282 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15285 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15287 (match_operand:SI 1 "arith_reg_operand" "r"))]
15290 [(set_attr "type" "ustore_media")])
15292 (define_insn "sthi_q64"
15293 [(set (zero_extract:DI
15294 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15297 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15299 (match_operand:DI 1 "arith_reg_operand" "r"))]
15302 [(set_attr "type" "ustore_media")])
15304 (define_insn "stlo_l64"
15305 [(set (zero_extract:SI
15306 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15308 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15309 (and:DI (match_dup 0) (const_int 3)))
15310 (match_operand:SI 1 "arith_reg_operand" "r"))]
15313 [(set_attr "type" "ustore_media")])
15315 (define_insn "stlo_q64"
15316 [(set (zero_extract:DI
15317 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15319 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15320 (and:DI (match_dup 0) (const_int 7)))
15321 (match_operand:DI 1 "arith_reg_operand" "r"))]
15324 [(set_attr "type" "ustore_media")])
15327 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15328 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15332 [(set_attr "type" "arith_media")])
15334 (define_insn "nsbsi"
15335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15337 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15341 [(set_attr "type" "arith_media")])
15343 (define_insn "nsbdi"
15344 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15346 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15350 [(set_attr "type" "arith_media")])
15352 (define_expand "ffsdi2"
15353 [(set (match_operand:DI 0 "arith_reg_dest" "")
15354 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15357 rtx scratch = gen_reg_rtx (DImode);
15360 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15361 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15362 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15363 emit_insn (gen_nsbdi (scratch, scratch));
15364 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15365 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15366 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15367 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15372 (define_expand "ffssi2"
15373 [(set (match_operand:SI 0 "arith_reg_dest" "")
15374 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15377 rtx scratch = gen_reg_rtx (SImode);
15378 rtx discratch = gen_reg_rtx (DImode);
15381 emit_insn (gen_adddi3 (discratch,
15382 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15384 emit_insn (gen_andcdi3 (discratch,
15385 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15387 emit_insn (gen_nsbsi (scratch, discratch));
15388 last = emit_insn (gen_subsi3 (operands[0],
15389 force_reg (SImode, GEN_INT (63)), scratch));
15390 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15395 (define_insn "byterev"
15396 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15397 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15398 (parallel [(const_int 7) (const_int 6) (const_int 5)
15399 (const_int 4) (const_int 3) (const_int 2)
15400 (const_int 1) (const_int 0)])))]
15403 [(set_attr "type" "arith_media")])
15405 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15406 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
15407 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15408 (define_expand "prefetch"
15409 [(prefetch (match_operand 0 "address_operand" "")
15410 (match_operand:SI 1 "const_int_operand" "")
15411 (match_operand:SI 2 "const_int_operand" ""))]
15412 "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15413 && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15415 (define_insn "*prefetch"
15416 [(prefetch (match_operand:SI 0 "register_operand" "r")
15417 (match_operand:SI 1 "const_int_operand" "n")
15418 (match_operand:SI 2 "const_int_operand" "n"))]
15419 "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15421 [(set_attr "type" "other")])
15423 (define_insn "*prefetch_media"
15424 [(prefetch (match_operand:QI 0 "address_operand" "p")
15425 (match_operand:SI 1 "const_int_operand" "n")
15426 (match_operand:SI 2 "const_int_operand" "n"))]
15429 operands[0] = gen_rtx_MEM (QImode, operands[0]);
15430 output_asm_insn ("ld%M0.b %m0,r63", operands);
15433 [(set_attr "type" "other")])
15435 (define_insn "alloco_i"
15436 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15437 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15442 if (GET_CODE (operands[0]) == PLUS)
15444 xops[0] = XEXP (operands[0], 0);
15445 xops[1] = XEXP (operands[0], 1);
15449 xops[0] = operands[0];
15450 xops[1] = const0_rtx;
15452 output_asm_insn ("alloco %0, %1", xops);
15455 [(set_attr "type" "other")])
15458 [(set (match_operand 0 "any_register_operand" "")
15459 (match_operand 1 "" ""))]
15460 "TARGET_SHMEDIA && reload_completed"
15461 [(set (match_dup 0) (match_dup 1))]
15465 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
15470 ; Stack Protector Patterns
15472 (define_expand "stack_protect_set"
15473 [(set (match_operand 0 "memory_operand" "")
15474 (match_operand 1 "memory_operand" ""))]
15477 if (TARGET_SHMEDIA)
15479 if (TARGET_SHMEDIA64)
15480 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15482 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15485 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15490 (define_insn "stack_protect_set_si"
15491 [(set (match_operand:SI 0 "memory_operand" "=m")
15492 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15493 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15496 return "mov.l %1,%2" "\n"
15497 " mov.l %2,%0" "\n"
15500 [(set_attr "type" "other")
15501 (set_attr "length" "6")])
15503 (define_insn "stack_protect_set_si_media"
15504 [(set (match_operand:SI 0 "memory_operand" "=m")
15505 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15506 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15509 return "ld%M1.l %m1,%2" "\n"
15510 " st%M0.l %m0,%2" "\n"
15513 [(set_attr "type" "other")
15514 (set_attr "length" "12")])
15516 (define_insn "stack_protect_set_di_media"
15517 [(set (match_operand:DI 0 "memory_operand" "=m")
15518 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15519 (set (match_scratch:DI 2 "=&r") (const_int 0))]
15522 return "ld%M1.q %m1,%2" "\n"
15523 " st%M0.q %m0,%2" "\n"
15526 [(set_attr "type" "other")
15527 (set_attr "length" "12")])
15529 (define_expand "stack_protect_test"
15530 [(match_operand 0 "memory_operand" "")
15531 (match_operand 1 "memory_operand" "")
15532 (match_operand 2 "" "")]
15535 if (TARGET_SHMEDIA)
15537 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15540 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15541 if (TARGET_SHMEDIA64)
15543 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15545 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15549 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15551 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15556 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15557 emit_jump_insn (gen_branch_true (operands[2]));
15563 (define_insn "stack_protect_test_si"
15564 [(set (reg:SI T_REG)
15565 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15566 (match_operand:SI 1 "memory_operand" "m")]
15568 (set (match_scratch:SI 2 "=&r") (const_int 0))
15569 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15572 return "mov.l %0,%2" "\n"
15573 " mov.l %1,%3" "\n"
15574 " cmp/eq %2,%3" "\n"
15578 [(set_attr "type" "other")
15579 (set_attr "length" "10")])
15581 (define_insn "stack_protect_test_si_media"
15582 [(set (match_operand:SI 0 "register_operand" "=&r")
15583 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15584 (match_operand:SI 2 "memory_operand" "m")]
15586 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15589 return "ld%M1.l %m1,%0" "\n"
15590 " ld%M2.l %m2,%3" "\n"
15591 " cmpeq %0,%3,%0" "\n"
15594 [(set_attr "type" "other")
15595 (set_attr "length" "16")])
15597 (define_insn "stack_protect_test_di_media"
15598 [(set (match_operand:DI 0 "register_operand" "=&r")
15599 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
15600 (match_operand:DI 2 "memory_operand" "m")]
15602 (set (match_scratch:DI 3 "=&r") (const_int 0))]
15605 return "ld%M1.q %m1,%0" "\n"
15606 " ld%M2.q %m2,%3" "\n"
15607 " cmpeq %0,%3,%0" "\n"
15610 [(set_attr "type" "other")
15611 (set_attr "length" "16")])
15613 (include "sync.md")