1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993-2014 Free Software Foundation, Inc.
3 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
4 ;; Improved by Jim Wilson (wilson@cygnus.com).
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
23 ;; ??? Should prepend a * to all pattern names which are not used.
24 ;; This will make the compiler smaller, and rebuilds after changes faster.
26 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
27 ;; sequences. Especially the sequences for arithmetic right shifts.
29 ;; ??? Should check all DImode patterns for consistency and usefulness.
31 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
32 ;; way to generate them.
34 ;; BSR is not generated by the compiler proper, but when relaxing, it
35 ;; generates .uses pseudo-ops that allow linker relaxation to create
36 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
38 ;; Special constraints for SH machine description:
45 ;; Special formats used for outputting SH instructions:
47 ;; %. -- print a .s if insn needs delay slot
48 ;; %@ -- print rte/rts if is/isn't an interrupt function
49 ;; %# -- output a nop if there is nothing to put in the delay slot
50 ;; %O -- print a constant without the #
51 ;; %R -- print the lsw reg of a double
52 ;; %S -- print the msw reg of a double
53 ;; %T -- print next word of a double REG or MEM
55 ;; Special predicates:
57 ;; arith_operand -- operand is valid source for arithmetic op
58 ;; arith_reg_operand -- operand is valid register for arithmetic op
59 ;; general_movdst_operand -- operand is valid move destination
60 ;; general_movsrc_operand -- operand is valid move source
61 ;; logical_operand -- operand is valid source for logical op
63 ;; -------------------------------------------------------------------------
65 ;; -------------------------------------------------------------------------
79 ;; Virtual FPSCR - bits that are used by FP ops.
82 ;; Virtual FPSCR - bits that are updated by FP ops.
119 (FPSCR_PR 524288) ;; 1 << 19
120 (FPSCR_SZ 1048576) ;; 1 << 20
121 (FPSCR_FR 2097152) ;; 1 << 21
124 (define_c_enum "unspec" [
125 ;; These are used with unspec.
164 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
165 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
168 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
170 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
173 UNSPEC_BUILTIN_STRLEN
176 (define_c_enum "unspecv" [
177 ;; These are used with unspec_volatile.
194 ;; -------------------------------------------------------------------------
196 ;; -------------------------------------------------------------------------
201 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
202 (const (symbol_ref "sh_cpu_attr")))
204 (define_attr "endian" "big,little"
205 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
206 (const_string "little") (const_string "big"))))
208 ;; Indicate if the default fpu mode is single precision.
209 (define_attr "fpu_single" "yes,no"
210 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
211 (const_string "yes") (const_string "no"))))
213 (define_attr "fmovd" "yes,no"
214 (const (if_then_else (symbol_ref "TARGET_FMOVD")
215 (const_string "yes") (const_string "no"))))
217 (define_attr "pipe_model" "sh1,sh4,sh5media"
219 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
220 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
221 (const_string "sh1"))))
223 ;; cbranch conditional branch instructions
224 ;; jump unconditional jumps
225 ;; arith ordinary arithmetic
226 ;; arith3 a compound insn that behaves similarly to a sequence of
227 ;; three insns of type arith
228 ;; arith3b like above, but might end with a redirected branch
230 ;; load_si Likewise, SImode variant for general register.
231 ;; fload Likewise, but load to fp register.
233 ;; fstore floating point register to memory
234 ;; move general purpose register to register
235 ;; movi8 8-bit immediate to general purpose register
236 ;; mt_group other sh4 mt instructions
237 ;; fmove register to register, floating point
238 ;; smpy word precision integer multiply
239 ;; dmpy longword or doublelongword precision integer multiply
241 ;; pload load of pr reg, which can't be put into delay slot of rts
242 ;; prset copy register to pr reg, ditto
243 ;; pstore store of pr reg, which can't be put into delay slot of jsr
244 ;; prget copy pr to register, ditto
245 ;; pcload pc relative load of constant value
246 ;; pcfload Likewise, but load to fp register.
247 ;; pcload_si Likewise, SImode variant for general register.
248 ;; rte return from exception
249 ;; sfunc special function call with known used registers
250 ;; call function call
252 ;; fpscr_toggle toggle a bit in the fpscr
253 ;; fdiv floating point divide (or square root)
254 ;; gp_fpul move from general purpose register to fpul
255 ;; fpul_gp move from fpul to general purpose register
256 ;; mac_gp move from mac[lh] to general purpose register
257 ;; gp_mac move from general purpose register to mac[lh]
258 ;; mac_mem move from mac[lh] to memory
259 ;; mem_mac move from memory to mac[lh]
260 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
261 ;; ftrc_s fix_truncsfsi2_i4
262 ;; dfdiv double precision floating point divide (or square root)
263 ;; cwb ic_invalidate_line_i
264 ;; movua SH4a unaligned load
265 ;; fsrra square root reciprocal approximate
266 ;; fsca sine and cosine approximate
267 ;; tls_load load TLS related address
268 ;; arith_media SHmedia arithmetic, logical, and shift instructions
269 ;; cbranch_media SHmedia conditional branch instructions
270 ;; cmp_media SHmedia compare instructions
271 ;; dfdiv_media SHmedia double precision divide and square root
272 ;; dfmul_media SHmedia double precision multiply instruction
273 ;; dfparith_media SHmedia double precision floating point arithmetic
274 ;; dfpconv_media SHmedia double precision floating point conversions
275 ;; dmpy_media SHmedia longword multiply
276 ;; fcmp_media SHmedia floating point compare instructions
277 ;; fdiv_media SHmedia single precision divide and square root
278 ;; fload_media SHmedia floating point register load instructions
279 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
280 ;; fparith_media SHmedia single precision floating point arithmetic
281 ;; fpconv_media SHmedia single precision floating point conversions
282 ;; fstore_media SHmedia floating point register store instructions
283 ;; gettr_media SHmedia gettr instruction
284 ;; invalidate_line_media SHmedia invalidate_line sequence
285 ;; jump_media SHmedia unconditional branch instructions
286 ;; load_media SHmedia general register load instructions
287 ;; pt_media SHmedia pt instruction (expanded by assembler)
288 ;; ptabs_media SHmedia ptabs instruction
289 ;; store_media SHmedia general register store instructions
290 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
291 ;; mac_media SHmedia mac-style fixed point operations
292 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
293 ;; atrans_media SHmedia approximate transcendental functions
294 ;; ustore_media SHmedia unaligned stores
295 ;; nil no-op move, will be deleted.
298 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,
299 fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,
300 prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,
301 dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,
302 gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,
303 arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,
304 dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,
305 fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,
306 jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,
307 d2mpy_media,atrans_media,ustore_media,nil,other"
308 (const_string "other"))
310 ;; We define a new attribute namely "insn_class".We use
311 ;; this for the DFA based pipeline description.
313 ;; mt_group SH4 "mt" group instructions.
315 ;; ex_group SH4 "ex" group instructions.
317 ;; ls_group SH4 "ls" group instructions.
319 (define_attr "insn_class"
320 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
321 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
322 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
323 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,
324 store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
325 (eq_attr "type" "cbranch,jump") (const_string "br_group")
326 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
327 (const_string "fe_group")
328 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,
329 prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,
330 gp_mac,mac_mem,mem_mac") (const_string "co_group")]
331 (const_string "none")))
333 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
334 ;; so these do not belong in an insn group, although they are modeled
335 ;; with their own define_insn_reservations.
337 ;; Indicate what precision must be selected in fpscr for this insn, if any.
338 (define_attr "fp_mode" "single,double,none" (const_string "none"))
340 ;; Indicate if the fpu mode is set by this instruction
341 ;; "unknown" must have the value as "none" in fp_mode, and means
342 ;; that the instruction/abi has left the processor in an unknown
344 ;; "none" means that nothing has changed and no mode is set.
345 ;; This attribute is only used for the Renesas ABI.
346 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
348 ; If a conditional branch destination is within -252..258 bytes away
349 ; from the instruction it can be 2 bytes long. Something in the
350 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
351 ; branches are initially assumed to be 16 bytes long.
352 ; In machine_dependent_reorg, we split all branches that are longer than
355 ;; The maximum range used for SImode constant pool entries is 1018. A final
356 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
357 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
358 ;; instruction around the pool table, 2 bytes of alignment before the table,
359 ;; and 30 bytes of alignment after the table. That gives a maximum total
360 ;; pool size of 1058 bytes.
361 ;; Worst case code/pool content size ratio is 1:2 (using asms).
362 ;; Thus, in the worst case, there is one instruction in front of a maximum
363 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
364 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
365 ;; If we have a forward branch, the initial table will be put after the
366 ;; unconditional branch.
368 ;; ??? We could do much better by keeping track of the actual pcloads within
369 ;; the branch range and in the pcload range in front of the branch range.
371 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
373 (define_attr "short_cbranch_p" "no,yes"
374 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
378 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
380 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
382 ] (const_string "no")))
384 (define_attr "med_branch_p" "no,yes"
385 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
388 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
390 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
393 ] (const_string "no")))
395 (define_attr "med_cbranch_p" "no,yes"
396 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
399 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
404 ] (const_string "no")))
406 (define_attr "braf_branch_p" "no,yes"
407 (cond [(match_test "! TARGET_SH2")
409 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
412 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
414 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
417 ] (const_string "no")))
419 (define_attr "braf_cbranch_p" "no,yes"
420 (cond [(match_test "! TARGET_SH2")
422 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
425 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
427 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
430 ] (const_string "no")))
432 ;; An unconditional jump in the range -4092..4098 can be 2 bytes long.
433 ;; For wider ranges, we need a combination of a code and a data part.
434 ;; If we can get a scratch register for a long range jump, the code
435 ;; part can be 4 bytes long; otherwise, it must be 8 bytes long.
436 ;; If the jump is in the range -32764..32770, the data part can be 2 bytes
437 ;; long; otherwise, it must be 6 bytes long.
439 ;; All other instructions are two bytes long by default.
441 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
442 ;; but getattrtab doesn't understand this.
443 (define_attr "length" ""
444 (cond [(eq_attr "type" "cbranch")
445 (cond [(eq_attr "short_cbranch_p" "yes")
447 (eq_attr "med_cbranch_p" "yes")
449 (eq_attr "braf_cbranch_p" "yes")
451 ;; ??? using pc is not computed transitively.
452 (ne (match_dup 0) (match_dup 0))
454 (match_test "flag_pic")
457 (eq_attr "type" "jump")
458 (cond [(eq_attr "med_branch_p" "yes")
460 (and (match_test "prev_nonnote_insn (insn)")
461 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
463 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
464 (symbol_ref "code_for_indirect_jump_scratch"))))
465 (cond [(eq_attr "braf_branch_p" "yes")
467 (not (match_test "flag_pic"))
469 (match_test "TARGET_SH2")
470 (const_int 10)] (const_int 18))
471 (eq_attr "braf_branch_p" "yes")
473 ;; ??? using pc is not computed transitively.
474 (ne (match_dup 0) (match_dup 0))
476 (match_test "flag_pic")
479 (eq_attr "type" "pt_media")
480 (if_then_else (match_test "TARGET_SHMEDIA64")
481 (const_int 20) (const_int 12))
482 (and (eq_attr "type" "jump_media")
483 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
485 ] (if_then_else (match_test "TARGET_SHMEDIA")
489 ;; DFA descriptions for the pipelines
492 (include "shmedia.md")
495 (include "iterators.md")
496 (include "predicates.md")
497 (include "constraints.md")
499 ;; Definitions for filling delay slots
501 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
503 (define_attr "banked" "yes,no"
504 (cond [(match_test "sh_loads_bankedreg_p (insn)")
505 (const_string "yes")]
506 (const_string "no")))
508 ;; ??? This should be (nil) instead of (const_int 0)
509 (define_attr "hit_stack" "yes,no"
510 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
512 (const_string "yes")))
514 (define_attr "interrupt_function" "no,yes"
515 (const (symbol_ref "current_function_interrupt")))
517 (define_attr "in_delay_slot" "yes,no"
518 (cond [(eq_attr "type" "cbranch") (const_string "no")
519 (eq_attr "type" "pcload,pcload_si") (const_string "no")
520 (eq_attr "type" "fpscr_toggle") (const_string "no")
521 (eq_attr "needs_delay_slot" "yes") (const_string "no")
522 (eq_attr "length" "2") (const_string "yes")
523 ] (const_string "no")))
525 (define_attr "cond_delay_slot" "yes,no"
526 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
527 ] (const_string "no")))
529 (define_attr "is_sfunc" ""
530 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
532 (define_attr "is_mac_media" ""
533 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
535 (define_attr "branch_zero" "yes,no"
536 (cond [(eq_attr "type" "!cbranch") (const_string "no")
537 (ne (symbol_ref "(next_active_insn (insn)\
538 == (prev_active_insn\
539 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
540 && get_attr_length (next_active_insn (insn)) == 2")
542 (const_string "yes")]
543 (const_string "no")))
545 ;; SH4 Double-precision computation with double-precision result -
546 ;; the two halves are ready at different times.
547 (define_attr "dfp_comp" "yes,no"
548 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
549 (const_string "no")))
551 ;; Insns for which the latency of a preceding fp insn is decreased by one.
552 (define_attr "late_fp_use" "yes,no" (const_string "no"))
553 ;; And feeding insns for which this relevant.
554 (define_attr "any_fp_comp" "yes,no"
555 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
556 (const_string "yes")]
557 (const_string "no")))
559 (define_attr "any_int_load" "yes,no"
560 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
561 (const_string "yes")]
562 (const_string "no")))
564 (define_attr "highpart" "user, ignore, extend, depend, must_split"
565 (const_string "user"))
568 (eq_attr "needs_delay_slot" "yes")
569 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
571 ;; Since a normal return (rts) implicitly uses the PR register,
572 ;; we can't allow PR register loads in an rts delay slot.
573 ;; On the SH1* and SH2*, the rte instruction reads the return pc from the
574 ;; stack, and thus we can't put a pop instruction in its delay slot.
575 ;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
576 ;; pop instruction can go in the delay slot, unless it references a banked
577 ;; register (the register bank is switched by rte).
579 (eq_attr "type" "return")
580 [(and (eq_attr "in_delay_slot" "yes")
581 (ior (and (eq_attr "interrupt_function" "no")
582 (eq_attr "type" "!pload,prset"))
583 (and (eq_attr "interrupt_function" "yes")
584 (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
585 (eq_attr "banked" "no"))))
588 ;; Since a call implicitly uses the PR register, we can't allow
589 ;; a PR register store in a jsr delay slot.
592 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
593 [(and (eq_attr "in_delay_slot" "yes")
594 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
596 ;; Say that we have annulled true branches, since this gives smaller and
597 ;; faster code when branches are predicted as not taken.
599 ;; ??? The non-annulled condition should really be "in_delay_slot",
600 ;; but insns that can be filled in non-annulled get priority over insns
601 ;; that can only be filled in anulled.
604 (and (eq_attr "type" "cbranch")
605 (match_test "TARGET_SH2"))
606 ;; SH2e has a hardware bug that pretty much prohibits the use of
607 ;; annulled delay slots.
608 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
609 (not (eq_attr "cpu" "sh2e"))) (nil)])
611 ;; -------------------------------------------------------------------------
612 ;; SImode signed integer comparisons
613 ;; -------------------------------------------------------------------------
615 ;; Various patterns to generate the TST #imm, R0 instruction.
616 ;; Although this adds some pressure on the R0 register, it can potentially
617 ;; result in faster code, even if the operand has to be moved to R0 first.
618 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group
619 ;; instructions and thus will be executed in parallel. On SH4A TST #imm, R0
620 ;; is an EX group instruction but still can be executed in parallel with the
621 ;; MT group MOV Rm, Rn instruction.
623 ;; Usual TST #imm, R0 patterns for SI, HI and QI
624 ;; This is usually used for bit patterns other than contiguous bits
626 (define_insn "tstsi_t"
628 (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
629 (match_operand:SI 1 "logical_operand" "K08,r"))
633 [(set_attr "type" "mt_group")])
635 (define_insn "tsthi_t"
637 (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
638 (match_operand 1 "const_int_operand")) 0)
641 && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
643 [(set_attr "type" "mt_group")])
645 (define_insn "tstqi_t"
647 (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
648 (match_operand 1 "const_int_operand")) 0)
651 && (CONST_OK_FOR_K08 (INTVAL (operands[1]))
652 || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
654 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
657 [(set_attr "type" "mt_group")])
659 ;; Test low QI subreg against zero.
660 ;; This avoids unnecessary zero extension before the test.
661 (define_insn "*tstqi_t_zero"
663 (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
666 [(set_attr "type" "mt_group")])
668 ;; This pattern might be risky because it also tests the upper bits and not
669 ;; only the subreg. However, it seems that combine will get to this only
670 ;; when testing sign/zero extended values. In this case the extended upper
671 ;; bits do not matter.
672 (define_insn "*tst<mode>_t_zero"
676 (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
677 (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>)
679 "TARGET_SH1 && TARGET_LITTLE_ENDIAN"
681 [(set_attr "type" "mt_group")])
683 (define_insn "*tst<mode>_t_zero"
687 (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
688 (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>)
690 "TARGET_SH1 && TARGET_BIG_ENDIAN"
692 [(set_attr "type" "mt_group")])
694 ;; Extract LSB, negate and store in T bit.
695 (define_insn "tstsi_t_and_not"
697 (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
701 [(set_attr "type" "mt_group")])
703 ;; Extract contiguous bits and compare them against zero.
704 (define_insn "tst<mode>_t_zero_extract_eq"
706 (eq:SI (zero_extract:SI (match_operand:QIHISIDI 0 "logical_operand" "z")
707 (match_operand:SI 1 "const_int_operand")
708 (match_operand:SI 2 "const_int_operand"))
711 && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
713 operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
716 [(set_attr "type" "mt_group")])
718 ;; This split is required when testing bits in a QI subreg.
723 (zero_extract:SI (match_operand 0 "logical_operand")
724 (match_operand 1 "const_int_operand")
725 (match_operand 2 "const_int_operand"))
726 (match_operand 3 "const_int_operand")
730 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
731 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
732 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
735 if (GET_MODE (operands[0]) == QImode)
736 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
739 ;; Extract single bit, negate and store it in the T bit.
740 ;; Not used for SH4A.
741 (define_insn "tstsi_t_zero_extract_xor"
743 (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
744 (match_operand:SI 3 "const_int_operand"))
745 (match_operand:SI 1 "const_int_operand")
746 (match_operand:SI 2 "const_int_operand")))]
748 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
749 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
751 [(set_attr "type" "mt_group")])
753 ;; Extract single bit, negate and store it in the T bit.
754 ;; Used for SH4A little endian.
755 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
758 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
759 (match_operand:SI 3 "const_int_operand")) 0)
760 (match_operand:SI 1 "const_int_operand")
761 (match_operand:SI 2 "const_int_operand")))]
762 "TARGET_SH1 && TARGET_LITTLE_ENDIAN
763 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
764 == (INTVAL (operands[3]) & 255)
765 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
767 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
770 [(set_attr "type" "mt_group")])
772 ;; Extract single bit, negate and store it in the T bit.
773 ;; Used for SH4A big endian.
774 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
777 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
778 (match_operand:SI 3 "const_int_operand")) 3)
779 (match_operand:SI 1 "const_int_operand")
780 (match_operand:SI 2 "const_int_operand")))]
781 "TARGET_SH1 && TARGET_BIG_ENDIAN
782 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
783 == (INTVAL (operands[3]) & 255)
784 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
786 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
789 [(set_attr "type" "mt_group")])
791 (define_insn "cmpeqsi_t"
793 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
794 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
800 [(set_attr "type" "mt_group")])
802 ;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
803 ;; pattern by itself. What this actually does is:
804 ;; x == 0: (1 >> 0-0) & 1 = 1
805 ;; x != 0: (1 >> 0-x) & 1 = 0
806 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
807 (define_insn_and_split "*cmpeqsi_t"
811 (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
816 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
818 (define_insn "cmpgtsi_t"
820 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
821 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
826 [(set_attr "type" "mt_group")])
828 (define_insn "cmpgesi_t"
830 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
831 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
836 [(set_attr "type" "mt_group")])
838 ;; FIXME: This is actually wrong. There is no way to literally move a
839 ;; general reg to t reg. Luckily, it seems that this pattern will be only
840 ;; used when the general reg is known be either '0' or '1' during combine.
841 ;; What we actually need is reg != 0 -> T, but we have only reg == 0 -> T.
842 ;; Due to interactions with other patterns, combine fails to pick the latter
843 ;; and invert the dependent logic.
844 (define_insn "*negtstsi"
845 [(set (reg:SI T_REG) (match_operand:SI 0 "arith_reg_operand" "r"))]
848 [(set_attr "type" "mt_group")])
850 ;; Some integer sign comparison patterns can be realized with the div0s insn.
851 ;; div0s Rm,Rn T = (Rm >> 31) ^ (Rn >> 31)
852 (define_insn "cmp_div0s_0"
854 (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
855 (match_operand:SI 1 "arith_reg_operand" "r"))
859 [(set_attr "type" "arith")])
861 (define_insn "cmp_div0s_1"
863 (lt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
864 (match_operand:SI 1 "arith_reg_operand" "r"))
868 [(set_attr "type" "arith")])
870 (define_insn_and_split "*cmp_div0s_0"
871 [(set (match_operand:SI 0 "arith_reg_dest" "")
872 (lshiftrt:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
873 (match_operand:SI 2 "arith_reg_operand" ""))
875 (clobber (reg:SI T_REG))]
880 (lshiftrt:SI (xor:SI (match_dup 1) (match_dup 2)) (const_int 31)))
881 (set (match_dup 0) (reg:SI T_REG))])
883 (define_insn "*cmp_div0s_0"
885 (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand" "%r")
887 (ge:SI (match_operand:SI 1 "arith_reg_operand" "r")
891 [(set_attr "type" "arith")])
893 (define_insn_and_split "*cmp_div0s_1"
894 [(set (match_operand:SI 0 "arith_reg_dest" "")
895 (ge:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
896 (match_operand:SI 2 "arith_reg_operand" ""))
898 (clobber (reg:SI T_REG))]
901 "&& can_create_pseudo_p ()"
903 ;; We have to go through the movnegt expander here which will handle the
904 ;; SH2A vs non-SH2A cases.
906 emit_insn (gen_cmp_div0s_1 (operands[1], operands[2]));
907 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
911 (define_insn_and_split "*cmp_div0s_1"
913 (ge:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
914 (match_operand:SI 1 "arith_reg_operand" ""))
918 "&& can_create_pseudo_p ()"
919 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
921 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
923 (define_insn_and_split "*cmp_div0s_1"
925 (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
927 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
931 "&& can_create_pseudo_p ()"
932 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
934 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
936 ;; -------------------------------------------------------------------------
937 ;; SImode compare and branch
938 ;; -------------------------------------------------------------------------
940 (define_expand "cbranchsi4"
942 (if_then_else (match_operator 0 "comparison_operator"
943 [(match_operand:SI 1 "arith_operand" "")
944 (match_operand:SI 2 "arith_operand" "")])
945 (label_ref (match_operand 3 "" ""))
947 (clobber (reg:SI T_REG))]
951 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
952 operands[2], operands[3]));
954 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
959 ;; Combine patterns to invert compare and branch operations for which we
960 ;; don't have actual comparison insns. These patterns are used in cases
961 ;; which appear after the initial cbranchsi expansion, which also does
962 ;; some condition inversion.
965 (if_then_else (ne (match_operand:SI 0 "arith_reg_operand" "")
966 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
967 (label_ref (match_operand 2))
969 (clobber (reg:SI T_REG))]
971 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (match_dup 1)))
972 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
973 (label_ref (match_dup 2))
976 ;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
977 ;; and SH2A combine fails to simplify this pattern by itself.
978 ;; What this actually does is:
979 ;; x == 0: (1 >> 0-0) & 1 = 1
980 ;; x != 0: (1 >> 0-x) & 1 = 0
981 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
985 (eq (and:SI (lshiftrt:SI
987 (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
990 (label_ref (match_operand 2))
992 (clobber (reg:SI T_REG))]
994 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
995 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
996 (label_ref (match_dup 2))
999 ;; FIXME: These could probably use code iterators for the compare op.
1002 (if_then_else (le (match_operand:SI 0 "arith_reg_operand" "")
1003 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1004 (label_ref (match_operand 2))
1006 (clobber (reg:SI T_REG))]
1008 [(set (reg:SI T_REG) (gt:SI (match_dup 0) (match_dup 1)))
1009 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1010 (label_ref (match_dup 2))
1015 (if_then_else (lt (match_operand:SI 0 "arith_reg_operand" "")
1016 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1017 (label_ref (match_operand 2))
1019 (clobber (reg:SI T_REG))]
1021 [(set (reg:SI T_REG) (ge:SI (match_dup 0) (match_dup 1)))
1022 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1023 (label_ref (match_dup 2))
1028 (if_then_else (leu (match_operand:SI 0 "arith_reg_operand" "")
1029 (match_operand:SI 1 "arith_reg_operand" ""))
1030 (label_ref (match_operand 2))
1032 (clobber (reg:SI T_REG))]
1034 [(set (reg:SI T_REG) (gtu:SI (match_dup 0) (match_dup 1)))
1035 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1036 (label_ref (match_dup 2))
1041 (if_then_else (ltu (match_operand:SI 0 "arith_reg_operand" "")
1042 (match_operand:SI 1 "arith_reg_operand" ""))
1043 (label_ref (match_operand 2))
1045 (clobber (reg:SI T_REG))]
1047 [(set (reg:SI T_REG) (geu:SI (match_dup 0) (match_dup 1)))
1048 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1049 (label_ref (match_dup 2))
1052 ;; Compare and branch combine patterns for div0s comparisons.
1053 (define_insn_and_split "*cbranch_div0s"
1055 (if_then_else (lt (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1056 (match_operand:SI 1 "arith_reg_operand" ""))
1058 (label_ref (match_operand 2))
1060 (clobber (reg:SI T_REG))]
1064 [(set (reg:SI T_REG)
1065 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1067 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1068 (label_ref (match_dup 2))
1071 (define_insn_and_split "*cbranch_div0s"
1073 (if_then_else (ge (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1074 (match_operand:SI 1 "arith_reg_operand" ""))
1076 (label_ref (match_operand 2))
1078 (clobber (reg:SI T_REG))]
1082 [(set (reg:SI T_REG)
1083 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1085 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1086 (label_ref (match_dup 2))
1089 ;; -------------------------------------------------------------------------
1090 ;; SImode unsigned integer comparisons
1091 ;; -------------------------------------------------------------------------
1093 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1094 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1095 ;; might remain and we have to handle them. If the '>= 0' case wasn't
1096 ;; handled here, something else would just load a '0' into the second operand
1097 ;; and do the comparison. We can do slightly better by just setting the
1099 (define_insn_and_split "cmpgeusi_t"
1100 [(set (reg:SI T_REG)
1101 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1102 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1105 "&& satisfies_constraint_Z (operands[1])"
1106 [(set (reg:SI T_REG) (const_int 1))]
1108 [(set_attr "type" "mt_group")])
1110 (define_insn "cmpgtusi_t"
1111 [(set (reg:SI T_REG)
1112 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1113 (match_operand:SI 1 "arith_reg_operand" "r")))]
1116 [(set_attr "type" "mt_group")])
1118 ;; -------------------------------------------------------------------------
1119 ;; DImode compare and branch
1120 ;; -------------------------------------------------------------------------
1122 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1123 ;; Therefore, we aim to have a set of three branches that go straight to the
1124 ;; destination, i.e. only one of them is taken at any one time.
1125 ;; This mechanism should also be slightly better for the sh4-200.
1127 (define_expand "cbranchdi4"
1129 (if_then_else (match_operator 0 "comparison_operator"
1130 [(match_operand:DI 1 "arith_operand" "")
1131 (match_operand:DI 2 "arith_operand" "")])
1132 (label_ref (match_operand 3 "" ""))
1134 (clobber (match_dup 4))
1135 (clobber (reg:SI T_REG))]
1136 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1138 enum rtx_code comparison;
1142 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1143 operands[2], operands[3]));
1146 else if (!TARGET_CBRANCHDI4)
1148 sh_emit_compare_and_branch (operands, DImode);
1153 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1156 comparison = prepare_cbranch_operands (operands, DImode,
1157 LAST_AND_UNUSED_RTX_CODE);
1158 if (comparison != GET_CODE (operands[0]))
1160 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1161 operands[4] = gen_rtx_SCRATCH (SImode);
1165 (define_insn_and_split "cbranchdi4_i"
1167 (if_then_else (match_operator 0 "comparison_operator"
1168 [(match_operand:DI 1 "arith_operand" "r,r")
1169 (match_operand:DI 2 "arith_operand" "rN,I08")])
1170 (label_ref (match_operand 3 "" ""))
1172 (clobber (match_scratch:SI 4 "=X,&r"))
1173 (clobber (reg:SI T_REG))]
1176 "&& reload_completed"
1179 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1184 ;; -------------------------------------------------------------------------
1185 ;; DImode signed integer comparisons
1186 ;; -------------------------------------------------------------------------
1189 [(set (reg:SI T_REG)
1190 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1191 (match_operand:DI 1 "arith_operand" "r"))
1195 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1198 [(set_attr "length" "6")
1199 (set_attr "type" "arith3b")])
1201 (define_insn "cmpeqdi_t"
1202 [(set (reg:SI T_REG)
1203 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1204 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1207 static const char* alt[] =
1214 "cmp/eq %S1,%S0" "\n"
1216 " cmp/eq %R1,%R0" "\n"
1219 return alt[which_alternative];
1221 [(set_attr "length" "6")
1222 (set_attr "type" "arith3b")])
1225 [(set (reg:SI T_REG)
1226 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1227 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1228 ;; If we applied this split when not optimizing, it would only be
1229 ;; applied during the machine-dependent reorg, when no new basic blocks
1231 "TARGET_SH1 && reload_completed && optimize"
1232 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1233 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1234 (label_ref (match_dup 6))
1236 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1239 operands[2] = gen_highpart (SImode, operands[0]);
1240 operands[3] = operands[1] == const0_rtx
1242 : gen_highpart (SImode, operands[1]);
1243 operands[4] = gen_lowpart (SImode, operands[0]);
1244 operands[5] = gen_lowpart (SImode, operands[1]);
1245 operands[6] = gen_label_rtx ();
1248 (define_insn "cmpgtdi_t"
1249 [(set (reg:SI T_REG)
1250 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1251 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1254 static const char* alt[] =
1256 "cmp/eq %S1,%S0" "\n"
1258 " cmp/gt %S1,%S0" "\n"
1259 " cmp/hi %R1,%R0" "\n"
1265 " cmp/hi %S0,%R0" "\n"
1268 return alt[which_alternative];
1270 [(set_attr "length" "8")
1271 (set_attr "type" "arith3")])
1273 (define_insn "cmpgedi_t"
1274 [(set (reg:SI T_REG)
1275 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1276 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1279 static const char* alt[] =
1281 "cmp/eq %S1,%S0" "\n"
1283 " cmp/ge %S1,%S0" "\n"
1284 " cmp/hs %R1,%R0" "\n"
1289 return alt[which_alternative];
1291 [(set_attr "length" "8,2")
1292 (set_attr "type" "arith3,mt_group")])
1294 ;; -------------------------------------------------------------------------
1295 ;; DImode unsigned integer comparisons
1296 ;; -------------------------------------------------------------------------
1298 (define_insn "cmpgeudi_t"
1299 [(set (reg:SI T_REG)
1300 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1301 (match_operand:DI 1 "arith_reg_operand" "r")))]
1304 return "cmp/eq %S1,%S0" "\n"
1306 " cmp/hs %S1,%S0" "\n"
1307 " cmp/hs %R1,%R0" "\n"
1310 [(set_attr "length" "8")
1311 (set_attr "type" "arith3")])
1313 (define_insn "cmpgtudi_t"
1314 [(set (reg:SI T_REG)
1315 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1316 (match_operand:DI 1 "arith_reg_operand" "r")))]
1319 return "cmp/eq %S1,%S0" "\n"
1321 " cmp/hi %S1,%S0" "\n"
1322 " cmp/hi %R1,%R0" "\n"
1325 [(set_attr "length" "8")
1326 (set_attr "type" "arith3")])
1328 (define_insn "cmpeqsi_media"
1329 [(set (match_operand:SI 0 "register_operand" "=r")
1330 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1331 (match_operand:SI 2 "cmp_operand" "Nr")))]
1334 [(set_attr "type" "cmp_media")])
1336 (define_insn "cmpeqdi_media"
1337 [(set (match_operand:SI 0 "register_operand" "=r")
1338 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1339 (match_operand:DI 2 "cmp_operand" "Nr")))]
1342 [(set_attr "type" "cmp_media")])
1344 (define_insn "cmpgtsi_media"
1345 [(set (match_operand:SI 0 "register_operand" "=r")
1346 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1347 (match_operand:SI 2 "cmp_operand" "rN")))]
1349 "cmpgt %N1, %N2, %0"
1350 [(set_attr "type" "cmp_media")])
1352 (define_insn "cmpgtdi_media"
1353 [(set (match_operand:SI 0 "register_operand" "=r")
1354 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1355 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1357 "cmpgt %N1, %N2, %0"
1358 [(set_attr "type" "cmp_media")])
1360 (define_insn "cmpgtusi_media"
1361 [(set (match_operand:SI 0 "register_operand" "=r")
1362 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1363 (match_operand:SI 2 "cmp_operand" "rN")))]
1365 "cmpgtu %N1, %N2, %0"
1366 [(set_attr "type" "cmp_media")])
1368 (define_insn "cmpgtudi_media"
1369 [(set (match_operand:SI 0 "register_operand" "=r")
1370 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1371 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1373 "cmpgtu %N1, %N2, %0"
1374 [(set_attr "type" "cmp_media")])
1376 ; This pattern is for combine.
1377 (define_insn "*cmpne0sisi_media"
1378 [(set (match_operand:SI 0 "register_operand" "=r")
1379 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1382 [(set_attr "type" "cmp_media")])
1384 ;; -------------------------------------------------------------------------
1385 ;; Conditional move instructions
1386 ;; -------------------------------------------------------------------------
1388 ;; The insn names may seem reversed, but note that cmveq performs the move
1389 ;; if op1 == 0, and cmvne does it if op1 != 0.
1391 (define_insn "movdicc_false"
1392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1393 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1395 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1396 (match_operand:DI 3 "arith_reg_operand" "0")))]
1399 [(set_attr "type" "arith_media")])
1401 (define_insn "movdicc_true"
1402 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1403 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1405 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1406 (match_operand:DI 3 "arith_reg_operand" "0")))]
1409 [(set_attr "type" "arith_media")])
1412 [(set (match_operand:DI 0 "arith_reg_dest" "")
1413 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1414 [(match_operand:DI 1 "arith_reg_operand" "")
1416 (match_operand:DI 2 "arith_reg_dest" "")
1418 (set (match_dup 2) (match_dup 0))]
1419 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1421 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1423 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1424 VOIDmode, operands[1], CONST0_RTX (DImode));
1428 [(set (match_operand:DI 0 "general_movdst_operand" "")
1429 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1430 (set (match_operand:DI 2 "arith_reg_dest" "")
1431 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1432 [(match_operand:DI 3 "arith_reg_operand" "")
1436 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1438 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1441 (define_expand "movdicc"
1442 [(set (match_operand:DI 0 "register_operand" "")
1443 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1444 (match_operand:DI 2 "register_operand" "")
1445 (match_operand:DI 3 "register_operand" "")))]
1448 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1449 && GET_MODE (XEXP (operands[1], 0)) == DImode
1450 && XEXP (operands[1], 1) == const0_rtx)
1454 if (!can_create_pseudo_p ())
1457 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1458 GET_CODE (operands[1]),
1459 XEXP (operands[1], 0),
1460 XEXP (operands[1], 1));
1466 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1467 ;; SImode to DImode.
1468 (define_insn "movsicc_false"
1469 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1470 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1472 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1473 (match_operand:SI 3 "arith_reg_operand" "0")))]
1476 [(set_attr "type" "arith_media")])
1478 (define_insn "movsicc_true"
1479 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1482 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1483 (match_operand:SI 3 "arith_reg_operand" "0")))]
1486 [(set_attr "type" "arith_media")])
1489 [(set (match_operand:SI 0 "arith_reg_dest" "")
1490 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1491 [(match_operand:SI 1 "arith_reg_operand" "")
1493 (match_operand:SI 2 "arith_reg_dest" "")
1495 (set (match_dup 2) (match_dup 0))]
1496 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1498 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1500 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1501 VOIDmode, operands[1], CONST0_RTX (SImode));
1505 [(set (match_operand:SI 0 "general_movdst_operand" "")
1506 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1507 (set (match_operand:SI 2 "arith_reg_dest" "")
1508 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1509 [(match_operand:SI 3 "arith_reg_operand" "")
1513 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1514 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1516 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1518 replace_rtx (operands[4], operands[0], operands[1]);
1522 [(set (match_operand 0 "any_register_operand" "")
1523 (match_operand 1 "any_register_operand" ""))
1524 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1525 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1526 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1527 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1528 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1529 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1530 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1531 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1532 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1533 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1534 && (REGNO_REG_CLASS (REGNO (operands[0]))
1535 == REGNO_REG_CLASS (REGNO (operands[2])))
1536 && (REGNO_REG_CLASS (REGNO (operands[1]))
1537 == REGNO_REG_CLASS (REGNO (operands[0])))"
1538 [(set (match_dup 0) (match_dup 3))
1539 (set (match_dup 4) (match_dup 5))]
1542 rtx_insn *insn1, *insn2;
1543 rtx replacements[4];
1545 /* We want to replace occurrences of operands[0] with operands[1] and
1546 operands[2] with operands[0] in operands[4]/operands[5].
1547 Doing just two replace_rtx calls naively would result in the second
1548 replacement undoing all that the first did if operands[1] and operands[2]
1549 are identical, so we must do this simultaneously. */
1550 replacements[0] = operands[0];
1551 replacements[1] = operands[1];
1552 replacements[2] = operands[2];
1553 replacements[3] = operands[0];
1554 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1555 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1556 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1559 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1560 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1561 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1562 /* The operands array is aliased to recog_data.operand, which gets
1563 clobbered by extract_insn, so finish with it now. */
1564 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1565 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1566 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1567 always uses emit_insn. */
1568 /* Check that we don't violate matching constraints or earlyclobbers. */
1569 basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2));
1570 insn1 = emit_insn (set1);
1571 extract_insn (insn1);
1572 if (! constrain_operands (1, get_preferred_alternatives (insn1, bb)))
1574 insn2 = emit (set2);
1575 if (GET_CODE (insn2) == BARRIER)
1577 extract_insn (insn2);
1578 if (! constrain_operands (1, get_preferred_alternatives (insn2, bb)))
1581 std::swap (replacements[0], replacements[1]);
1582 std::swap (replacements[2], replacements[3]);
1583 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1584 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1585 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1591 ;; The register allocator is rather clumsy in handling multi-way conditional
1592 ;; moves, so allow the combiner to make them, and we split them up after
1594 (define_insn_and_split "*movsicc_umin"
1595 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1596 (umin:SI (if_then_else:SI
1597 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1599 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1600 (match_operand:SI 3 "register_operand" "0"))
1601 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1602 (clobber (match_scratch:SI 5 "=&r"))]
1603 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1605 "TARGET_SHMEDIA && reload_completed"
1608 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1610 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1611 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1616 (define_insn "*movsicc_t_false"
1617 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1618 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1619 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1620 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1621 "TARGET_PRETEND_CMOVE
1622 && (arith_reg_operand (operands[1], SImode)
1623 || (immediate_operand (operands[1], SImode)
1624 && satisfies_constraint_I08 (operands[1])))"
1630 [(set_attr "type" "mt_group,arith") ;; poor approximation
1631 (set_attr "length" "4")])
1633 (define_insn "*movsicc_t_true"
1634 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1635 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1636 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1637 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1638 "TARGET_PRETEND_CMOVE
1639 && (arith_reg_operand (operands[1], SImode)
1640 || (immediate_operand (operands[1], SImode)
1641 && satisfies_constraint_I08 (operands[1])))"
1647 [(set_attr "type" "mt_group,arith") ;; poor approximation
1648 (set_attr "length" "4")])
1650 (define_expand "movsicc"
1651 [(set (match_operand:SI 0 "arith_reg_dest" "")
1652 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1653 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1654 (match_operand:SI 3 "arith_reg_operand" "")))]
1655 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1657 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1658 && GET_MODE (XEXP (operands[1], 0)) == SImode
1660 || (REG_P (XEXP (operands[1], 0))
1661 && REGNO (XEXP (operands[1], 0)) == T_REG))
1662 && XEXP (operands[1], 1) == const0_rtx)
1665 else if (TARGET_PRETEND_CMOVE)
1667 enum rtx_code code = GET_CODE (operands[1]);
1668 enum rtx_code new_code = code;
1669 rtx op0 = XEXP (operands[1], 0);
1670 rtx op1 = XEXP (operands[1], 1);
1672 if (! currently_expanding_to_rtl)
1676 case LT: case LE: case LEU: case LTU:
1677 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1680 new_code = reverse_condition (code);
1682 case EQ: case GT: case GE: case GEU: case GTU:
1687 sh_emit_scc_to_t (new_code, op0, op1);
1688 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1689 gen_rtx_REG (SImode, T_REG), const0_rtx);
1693 if (!can_create_pseudo_p ())
1696 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1697 GET_CODE (operands[1]),
1698 XEXP (operands[1], 0),
1699 XEXP (operands[1], 1));
1705 (define_expand "movqicc"
1706 [(set (match_operand:QI 0 "register_operand" "")
1707 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1708 (match_operand:QI 2 "register_operand" "")
1709 (match_operand:QI 3 "register_operand" "")))]
1712 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1713 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1714 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1715 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1719 ;; -------------------------------------------------------------------------
1720 ;; Addition instructions
1721 ;; -------------------------------------------------------------------------
1723 (define_expand "adddi3"
1724 [(set (match_operand:DI 0 "arith_reg_operand")
1725 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1726 (match_operand:DI 2 "arith_operand")))]
1731 operands[2] = force_reg (DImode, operands[2]);
1732 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1737 (define_insn "*adddi3_media"
1738 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1739 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1740 (match_operand:DI 2 "arith_operand" "r,I10")))]
1745 [(set_attr "type" "arith_media")])
1747 (define_insn "*adddisi3_media"
1748 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1749 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1750 (match_operand:DI 2 "arith_operand" "r,I10")))]
1755 [(set_attr "type" "arith_media")
1756 (set_attr "highpart" "ignore")])
1758 (define_insn "adddi3z_media"
1759 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1761 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1762 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1764 "addz.l %1, %N2, %0"
1765 [(set_attr "type" "arith_media")
1766 (set_attr "highpart" "ignore")])
1768 (define_insn_and_split "adddi3_compact"
1769 [(set (match_operand:DI 0 "arith_reg_dest")
1770 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1771 (match_operand:DI 2 "arith_reg_operand")))
1772 (clobber (reg:SI T_REG))]
1775 "&& can_create_pseudo_p ()"
1778 emit_insn (gen_clrt ());
1779 emit_insn (gen_addc (gen_lowpart (SImode, operands[0]),
1780 gen_lowpart (SImode, operands[1]),
1781 gen_lowpart (SImode, operands[2])));
1782 emit_insn (gen_addc (gen_highpart (SImode, operands[0]),
1783 gen_highpart (SImode, operands[1]),
1784 gen_highpart (SImode, operands[2])));
1789 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1790 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1791 (match_operand:SI 2 "arith_reg_operand" "r"))
1794 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1797 [(set_attr "type" "arith")])
1799 ;; A simplified version of the addc insn, where the exact value of the
1800 ;; T bit doesn't matter. This is easier for combine to pick up.
1801 ;; We allow a reg or 0 for one of the operands in order to be able to
1802 ;; do 'reg + T' sequences. Reload will load the constant 0 into the reg
1804 ;; FIXME: The load of constant 0 should be split out before reload, or else
1805 ;; it will be difficult to hoist or combine the constant load.
1806 (define_insn "*addc"
1807 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1808 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1809 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1810 (match_operand:SI 3 "t_reg_operand" "")))
1811 (clobber (reg:SI T_REG))]
1814 [(set_attr "type" "arith")])
1816 ;; Split 'reg + reg + 1' into a sett addc sequence, as it can be scheduled
1817 ;; better, if the sett insn can be done early.
1818 (define_insn_and_split "*addc_r_r_1"
1819 [(set (match_operand:SI 0 "arith_reg_dest" "")
1820 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
1821 (match_operand:SI 2 "arith_reg_operand" ""))
1823 (clobber (reg:SI T_REG))]
1827 [(set (reg:SI T_REG) (const_int 1))
1828 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
1830 (clobber (reg:SI T_REG))])])
1832 ;; Left shifts by one are usually done with an add insn to avoid T_REG
1833 ;; clobbers. Thus addc can also be used to do something like '(x << 1) + 1'.
1834 (define_insn_and_split "*addc_2r_1"
1835 [(set (match_operand:SI 0 "arith_reg_dest")
1836 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
1839 (clobber (reg:SI T_REG))]
1843 [(set (reg:SI T_REG) (const_int 1))
1844 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
1846 (clobber (reg:SI T_REG))])])
1848 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1849 ;; matched. Split this up into a simple sub add sequence, as this will save
1850 ;; us one sett insn.
1851 (define_insn_and_split "*minus_plus_one"
1852 [(set (match_operand:SI 0 "arith_reg_dest" "")
1853 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1854 (match_operand:SI 2 "arith_reg_operand" ""))
1859 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1860 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
1862 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
1863 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1864 ;; operation, as opposed to sequences such as
1868 ;; Even if the constant is not CSE-ed, a sequence such as
1871 ;; can be scheduled much better since the load of the constant can be
1872 ;; done earlier, before any comparison insns that store the result in
1874 (define_insn_and_split "*addc_t_r"
1875 [(set (match_operand:SI 0 "arith_reg_dest")
1876 (plus:SI (match_operand:SI 1 "t_reg_operand")
1877 (match_operand:SI 2 "arith_reg_operand")))
1878 (clobber (reg:SI T_REG))]
1882 [(parallel [(set (match_dup 0)
1883 (plus:SI (plus:SI (match_dup 2) (const_int 0))
1885 (clobber (reg:SI T_REG))])])
1887 (define_insn_and_split "*addc_r_t"
1888 [(set (match_operand:SI 0 "arith_reg_dest")
1889 (plus:SI (match_operand:SI 1 "arith_reg_operand")
1890 (match_operand:SI 2 "t_reg_operand")))
1891 (clobber (reg:SI T_REG))]
1895 [(parallel [(set (match_dup 0)
1896 (plus:SI (plus:SI (match_dup 1) (const_int 0))
1898 (clobber (reg:SI T_REG))])])
1900 ;; Use shlr-addc to do 'reg + (reg & 1)'.
1901 (define_insn_and_split "*addc_r_lsb"
1902 [(set (match_operand:SI 0 "arith_reg_dest")
1903 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1905 (match_operand:SI 2 "arith_reg_operand")))
1906 (clobber (reg:SI T_REG))]
1909 "&& can_create_pseudo_p ()"
1910 [(parallel [(set (match_dup 0) (plus:SI (reg:SI T_REG) (match_dup 2)))
1911 (clobber (reg:SI T_REG))])]
1913 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[1]));
1916 ;; Use shlr-addc to do 'reg + reg + (reg & 1)'.
1917 (define_insn_and_split "*addc_r_r_lsb"
1918 [(set (match_operand:SI 0 "arith_reg_dest")
1919 (plus:SI (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1921 (match_operand:SI 2 "arith_reg_operand"))
1922 (match_operand:SI 3 "arith_reg_operand")))
1923 (clobber (reg:SI T_REG))]
1926 "&& can_create_pseudo_p ()"
1927 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
1929 (clobber (reg:SI T_REG))])]
1931 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[1]));
1934 ;; Canonicalize 'reg + (reg & 1) + reg' into 'reg + reg + (reg & 1)'.
1935 (define_insn_and_split "*addc_r_lsb_r"
1936 [(set (match_operand:SI 0 "arith_reg_dest")
1937 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1939 (plus:SI (match_operand:SI 2 "arith_reg_operand")
1940 (match_operand:SI 3 "arith_reg_operand"))))
1941 (clobber (reg:SI T_REG))]
1944 "&& can_create_pseudo_p ()"
1945 [(parallel [(set (match_dup 0)
1946 (plus:SI (plus:SI (and:SI (match_dup 1) (const_int 1))
1949 (clobber (reg:SI T_REG))])])
1951 ;; Canonicalize '2 * reg + (reg & 1)' into 'reg + reg + (reg & 1)'.
1952 (define_insn_and_split "*addc_2r_lsb"
1953 [(set (match_operand:SI 0 "arith_reg_dest")
1954 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1956 (mult:SI (match_operand:SI 2 "arith_reg_operand")
1958 (clobber (reg:SI T_REG))]
1961 "&& can_create_pseudo_p ()"
1962 [(parallel [(set (match_dup 0)
1963 (plus:SI (plus:SI (and:SI (match_dup 1) (const_int 1))
1966 (clobber (reg:SI T_REG))])])
1968 ;; Use shll-addc to do 'reg + ((unsigned int)reg >> 31)'.
1969 (define_insn_and_split "*addc_r_msb"
1970 [(set (match_operand:SI 0 "arith_reg_dest")
1971 (plus:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
1973 (match_operand:SI 2 "arith_reg_operand")))
1974 (clobber (reg:SI T_REG))]
1977 "&& can_create_pseudo_p ()"
1978 [(parallel [(set (match_dup 0) (plus:SI (reg:SI T_REG) (match_dup 2)))
1979 (clobber (reg:SI T_REG))])]
1981 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[1]));
1984 ;; Use shll-addc to do 'reg + reg + ((unsigned int)reg >> 31)'.
1985 (define_insn_and_split "*addc_r_r_msb"
1986 [(set (match_operand:SI 0 "arith_reg_dest")
1987 (plus:SI (plus:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
1989 (match_operand:SI 2 "arith_reg_operand"))
1990 (match_operand:SI 3 "arith_reg_operand")))
1991 (clobber (reg:SI T_REG))]
1994 "&& can_create_pseudo_p ()"
1995 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
1997 (clobber (reg:SI T_REG))])]
1999 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[1]));
2002 ;; Canonicalize '2 * reg + ((unsigned int)reg >> 31)'
2003 ;; into 'reg + reg + (reg & 1)'.
2004 (define_insn_and_split "*addc_2r_msb"
2005 [(set (match_operand:SI 0 "arith_reg_dest")
2006 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
2008 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
2010 (clobber (reg:SI T_REG))]
2013 "&& can_create_pseudo_p ()"
2014 [(parallel [(set (match_dup 0)
2015 (plus:SI (plus:SI (lshiftrt:SI (match_dup 2) (const_int 31))
2018 (clobber (reg:SI T_REG))])])
2020 (define_expand "addsi3"
2021 [(set (match_operand:SI 0 "arith_reg_operand" "")
2022 (plus:SI (match_operand:SI 1 "arith_operand" "")
2023 (match_operand:SI 2 "arith_or_int_operand" "")))]
2027 operands[1] = force_reg (SImode, operands[1]);
2028 else if (! arith_operand (operands[2], SImode))
2030 if (reg_overlap_mentioned_p (operands[0], operands[1]))
2035 (define_insn "addsi3_media"
2036 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2037 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
2038 (match_operand:SI 2 "arith_operand" "r,I10")))]
2043 [(set_attr "type" "arith_media")
2044 (set_attr "highpart" "ignore")])
2046 (define_insn "addsidi3_media"
2047 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
2048 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
2050 (match_operand:SI 2 "arith_operand"
2056 [(set_attr "type" "arith_media")
2057 (set_attr "highpart" "ignore")])
2059 ;; The *addsi3_compact is made an insn_and_split and accepts actually
2060 ;; impossible constraints to make LRA's register elimination work well on SH.
2061 ;; The problem is that LRA expects something like
2062 ;; (set rA (plus rB (const_int N)))
2063 ;; to work. We can do that, but we have to split out an additional reg-reg
2064 ;; copy before the actual add insn.
2065 (define_insn_and_split "*addsi3_compact"
2066 [(set (match_operand:SI 0 "arith_reg_dest" "=r,&r")
2067 (plus:SI (match_operand:SI 1 "arith_operand" "%0,r")
2068 (match_operand:SI 2 "arith_or_int_operand" "rI08,rn")))]
2070 && ((rtx_equal_p (operands[0], operands[1])
2071 && arith_operand (operands[2], SImode))
2072 || ! reg_overlap_mentioned_p (operands[0], operands[1]))"
2077 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2078 [(set (match_dup 0) (match_dup 2))
2079 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
2081 [(set_attr "type" "arith")])
2083 ;; -------------------------------------------------------------------------
2084 ;; Subtraction instructions
2085 ;; -------------------------------------------------------------------------
2087 (define_expand "subdi3"
2088 [(set (match_operand:DI 0 "arith_reg_operand" "")
2089 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
2090 (match_operand:DI 2 "arith_reg_operand" "")))]
2095 operands[1] = force_reg (DImode, operands[1]);
2096 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
2101 (define_insn "*subdi3_media"
2102 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2103 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2104 (match_operand:DI 2 "arith_reg_operand" "r")))]
2107 [(set_attr "type" "arith_media")])
2109 (define_insn "subdisi3_media"
2110 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
2111 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2112 (match_operand:DI 2 "arith_reg_operand" "r")))]
2115 [(set_attr "type" "arith_media")
2116 (set_attr "highpart" "ignore")])
2118 (define_insn_and_split "subdi3_compact"
2119 [(set (match_operand:DI 0 "arith_reg_dest")
2120 (minus:DI (match_operand:DI 1 "arith_reg_operand")
2121 (match_operand:DI 2 "arith_reg_operand")))
2122 (clobber (reg:SI T_REG))]
2125 "&& can_create_pseudo_p ()"
2128 emit_insn (gen_clrt ());
2129 emit_insn (gen_subc (gen_lowpart (SImode, operands[0]),
2130 gen_lowpart (SImode, operands[1]),
2131 gen_lowpart (SImode, operands[2])));
2132 emit_insn (gen_subc (gen_highpart (SImode, operands[0]),
2133 gen_highpart (SImode, operands[1]),
2134 gen_highpart (SImode, operands[2])));
2139 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2140 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2141 (match_operand:SI 2 "arith_reg_operand" "r"))
2144 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
2149 [(set_attr "type" "arith")])
2151 ;; A simplified version of the subc insn, where the exact value of the
2152 ;; T bit doesn't matter. This is easier for combine to pick up.
2153 ;; We allow a reg or 0 for one of the operands in order to be able to
2154 ;; do 'reg - T' sequences. Reload will load the constant 0 into the reg
2156 (define_insn "*subc"
2157 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2158 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2159 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
2160 (match_operand:SI 3 "t_reg_operand" "")))
2161 (clobber (reg:SI T_REG))]
2164 [(set_attr "type" "arith")])
2166 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
2167 ;; better, if the sett insn can be done early.
2168 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
2169 (define_insn_and_split "*subc"
2170 [(set (match_operand:SI 0 "arith_reg_dest" "")
2171 (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
2172 (match_operand:SI 2 "arith_reg_operand" "")))
2173 (clobber (reg:SI T_REG))]
2177 [(set (reg:SI T_REG) (const_int 1))
2178 (parallel [(set (match_dup 0)
2179 (minus:SI (minus:SI (match_dup 2) (match_dup 1))
2181 (clobber (reg:SI T_REG))])])
2183 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
2184 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2185 ;; operation, as opposed to sequences such as
2189 ;; Even if the constant is not CSE-ed, a sequence such as
2192 ;; can be scheduled much better since the load of the constant can be
2193 ;; done earlier, before any comparison insns that store the result in
2195 (define_insn_and_split "*subc"
2196 [(set (match_operand:SI 0 "arith_reg_dest" "")
2197 (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2198 (match_operand:SI 2 "t_reg_operand" "")))
2199 (clobber (reg:SI T_REG))]
2203 [(parallel [(set (match_dup 0)
2204 (minus:SI (minus:SI (match_dup 1) (const_int 0))
2206 (clobber (reg:SI T_REG))])])
2208 (define_insn "*subsi3_internal"
2209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2210 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2211 (match_operand:SI 2 "arith_reg_operand" "r")))]
2214 [(set_attr "type" "arith")])
2216 (define_insn_and_split "*subsi3_media"
2217 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2218 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2219 (match_operand:SI 2 "extend_reg_operand" "r")))]
2221 && (operands[1] != constm1_rtx
2222 || (GET_CODE (operands[2]) != TRUNCATE
2223 && GET_CODE (operands[2]) != SUBREG))"
2225 "operands[1] == constm1_rtx"
2226 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2228 [(set_attr "type" "arith_media")
2229 (set_attr "highpart" "ignore")])
2232 [(set (match_operand:SI 0 "arith_reg_dest" "")
2233 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2234 "general_extend_operand"
2236 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2237 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2238 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2242 [(set (match_operand:SI 0 "arith_reg_dest" "")
2243 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2244 "general_extend_operand"
2246 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
2247 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2248 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2256 ;; since this will sometimes save one instruction.
2257 ;; Otherwise we might get a sequence like
2261 ;; if the source and dest regs are the same.
2262 (define_expand "subsi3"
2263 [(set (match_operand:SI 0 "arith_reg_operand" "")
2264 (minus:SI (match_operand:SI 1 "arith_operand" "")
2265 (match_operand:SI 2 "arith_reg_operand" "")))]
2268 if (TARGET_SH1 && CONST_INT_P (operands[1]))
2270 emit_insn (gen_negsi2 (operands[0], operands[2]));
2271 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2276 if (!can_create_pseudo_p ()
2277 && ! arith_reg_or_0_operand (operands[1], SImode))
2279 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2280 operands[1] = force_reg (SImode, operands[1]);
2284 ;; -------------------------------------------------------------------------
2285 ;; Division instructions
2286 ;; -------------------------------------------------------------------------
2288 ;; We take advantage of the library routines which don't clobber as many
2289 ;; registers as a normal function call would.
2291 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2292 ;; also has an effect on the register that holds the address of the sfunc.
2293 ;; To make this work, we have an extra dummy insn that shows the use
2294 ;; of this register for reorg.
2296 (define_insn "use_sfunc_addr"
2297 [(set (reg:SI PR_REG)
2298 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2299 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2301 [(set_attr "length" "0")])
2303 (define_insn "udivsi3_sh2a"
2304 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2305 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2306 (match_operand:SI 2 "arith_reg_operand" "z")))]
2309 [(set_attr "type" "arith")
2310 (set_attr "in_delay_slot" "no")])
2312 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2313 ;; hard register 0. If we used hard register 0, then the next instruction
2314 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
2315 ;; gets allocated to a stack slot that needs its address reloaded, then
2316 ;; there is nothing to prevent reload from using r0 to reload the address.
2317 ;; This reload would clobber the value in r0 we are trying to store.
2318 ;; If we let reload allocate r0, then this problem can never happen.
2319 (define_insn "udivsi3_i1"
2320 [(set (match_operand:SI 0 "register_operand" "=z")
2321 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2322 (clobber (reg:SI T_REG))
2323 (clobber (reg:SI PR_REG))
2324 (clobber (reg:SI R1_REG))
2325 (clobber (reg:SI R4_REG))
2326 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2327 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2329 [(set_attr "type" "sfunc")
2330 (set_attr "needs_delay_slot" "yes")])
2332 ; Since shmedia-nofpu code could be linked against shcompact code, and
2333 ; the udivsi3 libcall has the same name, we must consider all registers
2334 ; clobbered that are in the union of the registers clobbered by the
2335 ; shmedia and the shcompact implementation. Note, if the shcompact
2336 ; implementation actually used shcompact code, we'd need to clobber
2337 ; also r23 and fr23.
2338 (define_insn "udivsi3_i1_media"
2339 [(set (match_operand:SI 0 "register_operand" "=z")
2340 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2341 (clobber (reg:SI T_MEDIA_REG))
2342 (clobber (reg:SI PR_MEDIA_REG))
2343 (clobber (reg:SI R20_REG))
2344 (clobber (reg:SI R21_REG))
2345 (clobber (reg:SI R22_REG))
2346 (clobber (reg:DI TR0_REG))
2347 (clobber (reg:DI TR1_REG))
2348 (clobber (reg:DI TR2_REG))
2349 (use (match_operand 1 "target_reg_operand" "b"))]
2350 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2352 [(set_attr "type" "sfunc")
2353 (set_attr "needs_delay_slot" "yes")])
2355 (define_expand "udivsi3_i4_media"
2357 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2359 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2360 (set (match_dup 5) (float:DF (match_dup 3)))
2361 (set (match_dup 6) (float:DF (match_dup 4)))
2362 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2363 (set (match_dup 8) (fix:DI (match_dup 7)))
2364 (set (match_operand:SI 0 "register_operand" "")
2365 (truncate:SI (match_dup 8)))]
2366 "TARGET_SHMEDIA_FPU"
2368 operands[3] = gen_reg_rtx (DImode);
2369 operands[4] = gen_reg_rtx (DImode);
2370 operands[5] = gen_reg_rtx (DFmode);
2371 operands[6] = gen_reg_rtx (DFmode);
2372 operands[7] = gen_reg_rtx (DFmode);
2373 operands[8] = gen_reg_rtx (DImode);
2376 (define_insn "udivsi3_i4"
2377 [(set (match_operand:SI 0 "register_operand" "=y")
2378 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2379 (clobber (reg:SI T_REG))
2380 (clobber (reg:SI PR_REG))
2381 (clobber (reg:DF DR0_REG))
2382 (clobber (reg:DF DR2_REG))
2383 (clobber (reg:DF DR4_REG))
2384 (clobber (reg:SI R0_REG))
2385 (clobber (reg:SI R1_REG))
2386 (clobber (reg:SI R4_REG))
2387 (clobber (reg:SI R5_REG))
2388 (clobber (reg:SI FPSCR_STAT_REG))
2389 (use (reg:SI FPSCR_MODES_REG))
2390 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2391 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2393 [(set_attr "type" "sfunc")
2394 (set_attr "fp_mode" "double")
2395 (set_attr "needs_delay_slot" "yes")])
2397 (define_insn "udivsi3_i4_single"
2398 [(set (match_operand:SI 0 "register_operand" "=y")
2399 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2400 (clobber (reg:SI T_REG))
2401 (clobber (reg:SI PR_REG))
2402 (clobber (reg:DF DR0_REG))
2403 (clobber (reg:DF DR2_REG))
2404 (clobber (reg:DF DR4_REG))
2405 (clobber (reg:SI R0_REG))
2406 (clobber (reg:SI R1_REG))
2407 (clobber (reg:SI R4_REG))
2408 (clobber (reg:SI R5_REG))
2409 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2410 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2411 && TARGET_FPU_SINGLE"
2413 [(set_attr "type" "sfunc")
2414 (set_attr "needs_delay_slot" "yes")])
2416 (define_insn "udivsi3_i4_int"
2417 [(set (match_operand:SI 0 "register_operand" "=z")
2418 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2419 (clobber (reg:SI T_REG))
2420 (clobber (reg:SI R1_REG))
2421 (clobber (reg:SI PR_REG))
2422 (clobber (reg:SI MACH_REG))
2423 (clobber (reg:SI MACL_REG))
2424 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2427 [(set_attr "type" "sfunc")
2428 (set_attr "needs_delay_slot" "yes")])
2431 (define_expand "udivsi3"
2432 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2433 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2434 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2435 (parallel [(set (match_operand:SI 0 "register_operand" "")
2436 (udiv:SI (reg:SI R4_REG)
2438 (clobber (reg:SI T_REG))
2439 (clobber (reg:SI PR_REG))
2440 (clobber (reg:SI R4_REG))
2441 (use (match_dup 3))])]
2446 operands[3] = gen_reg_rtx (Pmode);
2447 /* Emit the move of the address to a pseudo outside of the libcall. */
2448 if (TARGET_DIVIDE_CALL_TABLE)
2450 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2451 that causes problems when the divide code is supposed to come from a
2452 separate library. Division by zero is undefined, so dividing 1 can be
2453 implemented by comparing with the divisor. */
2454 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2456 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2457 emit_insn (gen_cstoresi4 (operands[0], test,
2458 operands[1], operands[2]));
2461 else if (operands[2] == const0_rtx)
2463 emit_move_insn (operands[0], operands[2]);
2466 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2467 last = gen_udivsi3_i4_int (operands[0], operands[3]);
2469 else if (TARGET_DIVIDE_CALL_FP)
2471 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2472 if (TARGET_FPU_SINGLE)
2473 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2475 last = gen_udivsi3_i4 (operands[0], operands[3]);
2477 else if (TARGET_SHMEDIA_FPU)
2479 operands[1] = force_reg (SImode, operands[1]);
2480 operands[2] = force_reg (SImode, operands[2]);
2481 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2484 else if (TARGET_SH2A)
2486 operands[1] = force_reg (SImode, operands[1]);
2487 operands[2] = force_reg (SImode, operands[2]);
2488 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2491 else if (TARGET_SH5)
2493 function_symbol (operands[3],
2494 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2498 last = gen_udivsi3_i1_media (operands[0], operands[3]);
2499 else if (TARGET_FPU_ANY)
2500 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2502 last = gen_udivsi3_i1 (operands[0], operands[3]);
2506 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2507 last = gen_udivsi3_i1 (operands[0], operands[3]);
2509 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2510 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2515 (define_insn "divsi3_sh2a"
2516 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2517 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2518 (match_operand:SI 2 "arith_reg_operand" "z")))]
2521 [(set_attr "type" "arith")
2522 (set_attr "in_delay_slot" "no")])
2524 (define_insn "divsi3_i1"
2525 [(set (match_operand:SI 0 "register_operand" "=z")
2526 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2527 (clobber (reg:SI T_REG))
2528 (clobber (reg:SI PR_REG))
2529 (clobber (reg:SI R1_REG))
2530 (clobber (reg:SI R2_REG))
2531 (clobber (reg:SI R3_REG))
2532 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2533 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2535 [(set_attr "type" "sfunc")
2536 (set_attr "needs_delay_slot" "yes")])
2538 (define_insn "divsi3_i1_media"
2539 [(set (match_operand:SI 0 "register_operand" "=z")
2540 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2541 (clobber (reg:SI T_MEDIA_REG))
2542 (clobber (reg:SI PR_MEDIA_REG))
2543 (clobber (reg:SI R1_REG))
2544 (clobber (reg:SI R20_REG))
2545 (clobber (reg:SI R21_REG))
2546 (clobber (reg:SI TR0_REG))
2547 (use (match_operand 1 "target_reg_operand" "b"))]
2548 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2550 [(set_attr "type" "sfunc")])
2552 (define_insn "divsi3_media_2"
2553 [(set (match_operand:SI 0 "register_operand" "=z")
2554 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2555 (clobber (reg:SI T_MEDIA_REG))
2556 (clobber (reg:SI PR_MEDIA_REG))
2557 (clobber (reg:SI R1_REG))
2558 (clobber (reg:SI R21_REG))
2559 (clobber (reg:SI TR0_REG))
2560 (use (reg:SI R20_REG))
2561 (use (match_operand 1 "target_reg_operand" "b"))]
2562 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2564 [(set_attr "type" "sfunc")])
2566 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2567 ;; hard reg clobbers and data dependencies that we need when we want
2568 ;; to rematerialize the division into a call.
2569 (define_insn_and_split "divsi_inv_call"
2570 [(set (match_operand:SI 0 "register_operand" "=r")
2571 (div:SI (match_operand:SI 1 "register_operand" "r")
2572 (match_operand:SI 2 "register_operand" "r")))
2573 (clobber (reg:SI R4_REG))
2574 (clobber (reg:SI R5_REG))
2575 (clobber (reg:SI T_MEDIA_REG))
2576 (clobber (reg:SI PR_MEDIA_REG))
2577 (clobber (reg:SI R1_REG))
2578 (clobber (reg:SI R21_REG))
2579 (clobber (reg:SI TR0_REG))
2580 (clobber (reg:SI R20_REG))
2581 (use (match_operand:SI 3 "register_operand" "r"))]
2584 "&& (reload_in_progress || reload_completed)"
2585 [(set (match_dup 0) (match_dup 3))]
2587 [(set_attr "highpart" "must_split")])
2589 ;; This is the combiner pattern for -mdiv=inv:call .
2590 (define_insn_and_split "*divsi_inv_call_combine"
2591 [(set (match_operand:SI 0 "register_operand" "=z")
2592 (div:SI (match_operand:SI 1 "register_operand" "r")
2593 (match_operand:SI 2 "register_operand" "r")))
2594 (clobber (reg:SI R4_REG))
2595 (clobber (reg:SI R5_REG))
2596 (clobber (reg:SI T_MEDIA_REG))
2597 (clobber (reg:SI PR_MEDIA_REG))
2598 (clobber (reg:SI R1_REG))
2599 (clobber (reg:SI R21_REG))
2600 (clobber (reg:SI TR0_REG))
2601 (clobber (reg:SI R20_REG))
2602 (use (unspec:SI [(match_dup 1)
2603 (match_operand:SI 3 "" "")
2604 (unspec:SI [(match_operand:SI 4 "" "")
2606 (match_operand:DI 5 "" "")]
2608 (match_operand:DI 6 "" "")
2611 UNSPEC_DIV_INV_M3))]
2614 "&& (reload_in_progress || reload_completed)"
2617 const char *name = sh_divsi3_libfunc;
2618 enum sh_function_kind kind = SFUNC_GOT;
2621 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2622 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2623 while (TARGET_DIVIDE_INV_CALL2)
2625 rtx x = operands[3];
2627 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2629 x = XVECEXP (x, 0, 0);
2630 name = "__sdivsi3_2";
2631 kind = SFUNC_STATIC;
2632 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2635 sym = function_symbol (NULL, name, kind);
2636 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2639 [(set_attr "highpart" "must_split")])
2641 (define_expand "divsi3_i4_media"
2642 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2643 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2644 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2645 (set (match_operand:SI 0 "register_operand" "=r")
2646 (fix:SI (match_dup 5)))]
2647 "TARGET_SHMEDIA_FPU"
2649 operands[3] = gen_reg_rtx (DFmode);
2650 operands[4] = gen_reg_rtx (DFmode);
2651 operands[5] = gen_reg_rtx (DFmode);
2654 (define_insn "divsi3_i4"
2655 [(set (match_operand:SI 0 "register_operand" "=y")
2656 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2657 (clobber (reg:SI PR_REG))
2658 (clobber (reg:DF DR0_REG))
2659 (clobber (reg:DF DR2_REG))
2660 (clobber (reg:SI FPSCR_STAT_REG))
2661 (use (reg:SI FPSCR_MODES_REG))
2662 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2663 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2665 [(set_attr "type" "sfunc")
2666 (set_attr "fp_mode" "double")
2667 (set_attr "needs_delay_slot" "yes")])
2669 (define_insn "divsi3_i4_single"
2670 [(set (match_operand:SI 0 "register_operand" "=y")
2671 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2672 (clobber (reg:SI PR_REG))
2673 (clobber (reg:DF DR0_REG))
2674 (clobber (reg:DF DR2_REG))
2675 (clobber (reg:SI R2_REG))
2676 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2677 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2678 && TARGET_FPU_SINGLE"
2680 [(set_attr "type" "sfunc")
2681 (set_attr "needs_delay_slot" "yes")])
2683 (define_insn "divsi3_i4_int"
2684 [(set (match_operand:SI 0 "register_operand" "=z")
2685 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2686 (clobber (reg:SI T_REG))
2687 (clobber (reg:SI PR_REG))
2688 (clobber (reg:SI R1_REG))
2689 (clobber (reg:SI MACH_REG))
2690 (clobber (reg:SI MACL_REG))
2691 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2694 [(set_attr "type" "sfunc")
2695 (set_attr "needs_delay_slot" "yes")])
2697 (define_expand "divsi3"
2698 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2699 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2700 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2701 (parallel [(set (match_operand:SI 0 "register_operand" "")
2702 (div:SI (reg:SI R4_REG)
2704 (clobber (reg:SI T_REG))
2705 (clobber (reg:SI PR_REG))
2706 (clobber (reg:SI R1_REG))
2707 (clobber (reg:SI R2_REG))
2708 (clobber (reg:SI R3_REG))
2709 (use (match_dup 3))])]
2714 operands[3] = gen_reg_rtx (Pmode);
2715 /* Emit the move of the address to a pseudo outside of the libcall. */
2716 if (TARGET_DIVIDE_CALL_TABLE)
2718 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2719 last = gen_divsi3_i4_int (operands[0], operands[3]);
2721 else if (TARGET_DIVIDE_CALL_FP)
2723 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2724 if (TARGET_FPU_SINGLE)
2725 last = gen_divsi3_i4_single (operands[0], operands[3]);
2727 last = gen_divsi3_i4 (operands[0], operands[3]);
2729 else if (TARGET_SH2A)
2731 operands[1] = force_reg (SImode, operands[1]);
2732 operands[2] = force_reg (SImode, operands[2]);
2733 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2736 else if (TARGET_DIVIDE_INV)
2738 rtx dividend = operands[1];
2739 rtx divisor = operands[2];
2741 rtx nsb_res = gen_reg_rtx (DImode);
2742 rtx norm64 = gen_reg_rtx (DImode);
2743 rtx tab_ix = gen_reg_rtx (DImode);
2744 rtx norm32 = gen_reg_rtx (SImode);
2745 rtx i92 = force_reg (DImode, GEN_INT (92));
2746 rtx scratch0a = gen_reg_rtx (DImode);
2747 rtx scratch0b = gen_reg_rtx (DImode);
2748 rtx inv0 = gen_reg_rtx (SImode);
2749 rtx scratch1a = gen_reg_rtx (DImode);
2750 rtx scratch1b = gen_reg_rtx (DImode);
2751 rtx shift = gen_reg_rtx (DImode);
2753 rtx inv1 = gen_reg_rtx (SImode);
2754 rtx scratch2a = gen_reg_rtx (DImode);
2755 rtx scratch2b = gen_reg_rtx (SImode);
2756 rtx inv2 = gen_reg_rtx (SImode);
2757 rtx scratch3a = gen_reg_rtx (DImode);
2758 rtx scratch3b = gen_reg_rtx (DImode);
2759 rtx scratch3c = gen_reg_rtx (DImode);
2760 rtx scratch3d = gen_reg_rtx (SImode);
2761 rtx scratch3e = gen_reg_rtx (DImode);
2762 rtx result = gen_reg_rtx (SImode);
2764 if (! arith_reg_or_0_operand (dividend, SImode))
2765 dividend = force_reg (SImode, dividend);
2766 if (! arith_reg_operand (divisor, SImode))
2767 divisor = force_reg (SImode, divisor);
2768 if (flag_pic && Pmode != DImode)
2770 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2771 tab_base = gen_datalabel_ref (tab_base);
2772 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2776 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2777 tab_base = gen_datalabel_ref (tab_base);
2778 tab_base = force_reg (DImode, tab_base);
2780 if (TARGET_DIVIDE_INV20U)
2781 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2783 i2p27 = GEN_INT (0);
2784 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2785 i43 = force_reg (DImode, GEN_INT (43));
2788 emit_insn (gen_nsbdi (nsb_res,
2789 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2790 emit_insn (gen_ashldi3_media (norm64,
2791 gen_rtx_SUBREG (DImode, divisor, 0),
2793 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2794 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2795 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2796 inv0, scratch0a, scratch0b,
2797 scratch1a, scratch1b));
2798 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2799 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2801 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2803 scratch3a, scratch3b, scratch3c,
2804 scratch2a, scratch2b, scratch3d, scratch3e));
2805 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2806 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2807 else if (TARGET_DIVIDE_INV_FP)
2808 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2809 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2810 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2811 gen_reg_rtx (DFmode)));
2813 emit_move_insn (operands[0], result);
2816 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2818 operands[1] = force_reg (SImode, operands[1]);
2819 operands[2] = force_reg (SImode, operands[2]);
2820 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2823 else if (TARGET_SH5)
2825 if (TARGET_DIVIDE_CALL2)
2827 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2828 tab_base = gen_datalabel_ref (tab_base);
2829 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2831 if (TARGET_FPU_ANY && TARGET_SH1)
2832 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2833 else if (TARGET_DIVIDE_CALL2)
2834 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2836 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2839 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2840 (operands[0], operands[3]));
2841 else if (TARGET_FPU_ANY)
2842 last = gen_divsi3_i4_single (operands[0], operands[3]);
2844 last = gen_divsi3_i1 (operands[0], operands[3]);
2848 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2849 last = gen_divsi3_i1 (operands[0], operands[3]);
2851 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2852 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2857 ;; operands: scratch, tab_base, tab_ix
2858 ;; These are unspecs because we could generate an indexed addressing mode
2859 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2860 ;; confuse reload. See PR27117.
2861 (define_insn "divsi_inv_qitable"
2862 [(set (match_operand:DI 0 "register_operand" "=r")
2863 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2864 (match_operand:DI 2 "register_operand" "r")]
2865 UNSPEC_DIV_INV_TABLE)))]
2868 [(set_attr "type" "load_media")
2869 (set_attr "highpart" "user")])
2871 ;; operands: scratch, tab_base, tab_ix
2872 (define_insn "divsi_inv_hitable"
2873 [(set (match_operand:DI 0 "register_operand" "=r")
2874 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2875 (match_operand:DI 2 "register_operand" "r")]
2876 UNSPEC_DIV_INV_TABLE)))]
2879 [(set_attr "type" "load_media")
2880 (set_attr "highpart" "user")])
2882 ;; operands: inv0, tab_base, tab_ix, norm32
2883 ;; scratch equiv in sdivsi3_2: r19, r21
2884 (define_expand "divsi_inv_m0"
2885 [(set (match_operand:SI 0 "register_operand" "=r")
2886 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2887 (match_operand:DI 2 "register_operand" "r")
2888 (match_operand:SI 3 "register_operand" "r")]
2890 (clobber (match_operand:DI 4 "register_operand" "=r"))
2891 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2898 ldx.ub r20, r21, r19 // u0.8
2900 muls.l r25, r19, r19 // s2.38
2901 ldx.w r20, r21, r21 // s2.14
2902 shari r19, 24, r19 // truncate to s2.14
2903 sub r21, r19, r19 // some 11 bit inverse in s1.14
2906 rtx inv0 = operands[0];
2907 rtx tab_base = operands[1];
2908 rtx tab_ix = operands[2];
2909 rtx norm32 = operands[3];
2910 rtx scratch0 = operands[4];
2911 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2912 rtx scratch1 = operands[5];
2914 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2915 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2916 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2917 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2918 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2919 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2923 ;; operands: inv1, tab_base, tab_ix, norm32
2924 (define_insn_and_split "divsi_inv_m1"
2925 [(set (match_operand:SI 0 "register_operand" "=r")
2926 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2927 (match_operand:DI 2 "register_operand" "r")
2928 (match_operand:SI 3 "register_operand" "r")]
2930 (clobber (match_operand:SI 4 "register_operand" "=r"))
2931 (clobber (match_operand:DI 5 "register_operand" "=r"))
2932 (clobber (match_operand:DI 6 "register_operand" "=r"))
2933 (clobber (match_operand:DI 7 "register_operand" "=r"))
2934 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2937 "&& !can_create_pseudo_p ()"
2941 muls.l r19, r19, r18 // u0.28
2942 muls.l r25, r18, r18 // s2.58
2943 shlli r19, 45, r0 // multiply by two and convert to s2.58
2945 shari r18, 28, r18 // some 18 bit inverse in s1.30
2948 rtx inv1 = operands[0];
2949 rtx tab_base = operands[1];
2950 rtx tab_ix = operands[2];
2951 rtx norm32 = operands[3];
2952 rtx inv0 = operands[4];
2953 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2954 rtx scratch0a = operands[5];
2955 rtx scratch0b = operands[6];
2956 rtx scratch0 = operands[7];
2957 rtx scratch1 = operands[8];
2958 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2960 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2961 scratch0a, scratch0b));
2962 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2963 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2964 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2965 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2966 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2970 ;; operands: inv2, norm32, inv1, i92
2971 (define_insn_and_split "divsi_inv_m2"
2972 [(set (match_operand:SI 0 "register_operand" "=r")
2973 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2974 (match_operand:SI 2 "register_operand" "r")
2975 (match_operand:DI 3 "register_operand" "r")]
2977 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2980 "&& !can_create_pseudo_p ()"
2984 muls.l r18, r25, r0 // s2.60
2985 shari r0, 16, r0 // s-16.44
2987 muls.l r0, r18, r19 // s-16.74
2988 shari r19, 30, r19 // s-16.44
2990 rtx inv2 = operands[0];
2991 rtx norm32 = operands[1];
2992 rtx inv1 = operands[2];
2993 rtx i92 = operands[3];
2994 rtx scratch0 = operands[4];
2995 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2997 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2998 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2999 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
3000 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
3001 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
3005 (define_insn_and_split "divsi_inv_m3"
3006 [(set (match_operand:SI 0 "register_operand" "=r")
3007 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3008 (match_operand:SI 2 "register_operand" "r")
3009 (match_operand:SI 3 "register_operand" "r")
3010 (match_operand:DI 4 "register_operand" "r")
3011 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
3012 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
3014 (clobber (match_operand:DI 7 "register_operand" "=r"))
3015 (clobber (match_operand:DI 8 "register_operand" "=r"))
3016 (clobber (match_operand:DI 9 "register_operand" "=r"))
3017 (clobber (match_operand:DI 10 "register_operand" "=r"))
3018 (clobber (match_operand:SI 11 "register_operand" "=r"))
3019 (clobber (match_operand:SI 12 "register_operand" "=r"))
3020 (clobber (match_operand:DI 13 "register_operand" "=r"))]
3023 "&& !can_create_pseudo_p ()"
3027 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
3028 r0: scratch0 r19: scratch1 r21: scratch2
3030 muls.l r18, r4, r25 // s32.30
3031 muls.l r19, r4, r19 // s15.30
3033 shari r19, 14, r19 // s18.-14
3039 rtx result = operands[0];
3040 rtx dividend = operands[1];
3041 rtx inv1 = operands[2];
3042 rtx inv2 = operands[3];
3043 rtx shift = operands[4];
3044 rtx scratch0 = operands[7];
3045 rtx scratch1 = operands[8];
3046 rtx scratch2 = operands[9];
3048 if (satisfies_constraint_N (dividend))
3050 emit_move_insn (result, dividend);
3054 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
3055 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
3056 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
3057 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
3058 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
3059 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
3060 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
3064 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
3065 ;; inv1: tab_base, tab_ix, norm32
3066 ;; inv2: norm32, inv1, i92
3067 (define_insn_and_split "divsi_inv_m1_3"
3068 [(set (match_operand:SI 0 "register_operand" "=r")
3069 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3070 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
3071 (match_operand:DI 3 "register_operand" "r")
3072 (match_operand:SI 4 "register_operand" "r")]
3074 (unspec:SI [(match_dup 4)
3075 (unspec:SI [(match_dup 2)
3077 (match_dup 4)] UNSPEC_DIV_INV_M1)
3078 (match_operand:SI 5 "" "")]
3080 (match_operand:DI 6 "register_operand" "r")
3081 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
3082 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
3084 (clobber (match_operand:DI 9 "register_operand" "=r"))
3085 (clobber (match_operand:DI 10 "register_operand" "=r"))
3086 (clobber (match_operand:DI 11 "register_operand" "=r"))
3087 (clobber (match_operand:DI 12 "register_operand" "=r"))
3088 (clobber (match_operand:SI 13 "register_operand" "=r"))
3089 (clobber (match_operand:SI 14 "register_operand" "=r"))
3090 (clobber (match_operand:DI 15 "register_operand" "=r"))]
3092 && (TARGET_DIVIDE_INV_MINLAT
3093 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3095 "&& !can_create_pseudo_p ()"
3098 rtx result = operands[0];
3099 rtx dividend = operands[1];
3100 rtx tab_base = operands[2];
3101 rtx tab_ix = operands[3];
3102 rtx norm32 = operands[4];
3103 /* rtx i92 = operands[5]; */
3104 rtx shift = operands[6];
3105 rtx i2p27 = operands[7];
3106 rtx i43 = operands[8];
3107 rtx scratch0 = operands[9];
3108 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3109 rtx scratch1 = operands[10];
3110 rtx scratch1_si = gen_lowpart (SImode, scratch1);
3111 rtx scratch2 = operands[11];
3112 rtx scratch3 = operands[12];
3113 rtx scratch4 = operands[13];
3114 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
3115 rtx scratch5 = operands[14];
3116 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
3117 rtx scratch6 = operands[15];
3119 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
3120 scratch0, scratch1));
3121 /* inv0 == scratch4 */
3122 if (! TARGET_DIVIDE_INV20U)
3124 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
3126 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
3130 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
3131 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
3133 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
3134 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
3135 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
3136 /* inv1 == scratch4 */
3138 if (TARGET_DIVIDE_INV_MINLAT)
3140 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
3141 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
3142 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
3143 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
3144 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
3145 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
3146 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
3147 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
3148 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
3149 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
3150 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
3154 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
3155 /* Use separate scratch regs for nsb and sign to allow scheduling. */
3156 emit_insn (gen_nsbdi (scratch6,
3157 simplify_gen_subreg (DImode, dividend, SImode, 0)));
3158 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
3159 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
3160 emit_insn (gen_divsi_inv20 (scratch2,
3161 norm32, scratch4, dividend,
3162 scratch6, scratch3, i43,
3163 /* scratch0 may be shared with i2p27. */
3164 scratch0, scratch1, scratch5,
3165 label, label, i2p27));
3167 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
3168 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
3172 (define_insn "divsi_inv20"
3173 [(set (match_operand:DI 0 "register_operand" "=&r")
3174 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
3175 (match_operand:SI 2 "register_operand" "r")
3176 (match_operand:SI 3 "register_operand" "r")
3177 (match_operand:DI 4 "register_operand" "r")
3178 (match_operand:DI 5 "register_operand" "r")
3179 (match_operand:DI 6 "register_operand" "r")
3180 (match_operand:DI 12 "register_operand" "r")
3181 (match_operand 10 "target_operand" "b")
3182 (match_operand 11 "immediate_operand" "i")]
3184 (clobber (match_operand:DI 7 "register_operand" "=&r"))
3185 (clobber (match_operand:DI 8 "register_operand" "=&r"))
3186 (clobber (match_operand:SI 9 "register_operand" "=r"))]
3188 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3190 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
3191 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
3192 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
3193 %10 label (tr), %11 label (imm)
3195 muls.l inv1, norm32, scratch0 // s2.60
3196 muls.l inv1, dividend, result // s32.30
3197 xor i2p27, result_sign, round_scratch
3198 bge/u dividend_nsb, i43, tr.. (label)
3199 shari scratch0, 16, scratch0 // s-16.44
3200 muls.l sratch0_si, inv1, scratch0 // s-16.74
3201 sub result, round_scratch, result
3202 shari dividend, 14, scratch1 // s19.-14
3203 shari scratch0, 30, scratch0 // s-16.44
3204 muls.l scratch0, scratch1, round_scratch // s15.30
3206 sub result, round_scratch, result */
3208 const bool likely = TARGET_DIVIDE_INV20L;
3211 "muls.l %2, %3, %0" "\n"
3212 " xor %12, %5, %7" "\n"
3213 " bge/l %4, %6, %10" "\n"
3214 " muls.l %2, %1, %8" "\n"
3215 " shari %8, 16, %8" "\n"
3216 " muls.l %8, %2, %8" "\n"
3217 " shari %3, 14, %9" "\n"
3218 " shari %8, 30, %8" "\n"
3219 " muls.l %8, %9, %8" "\n"
3220 " sub %0, %8, %0" "\n"
3221 "%11: add %0, %7, %0";
3224 "muls.l %2, %1, %8" "\n"
3225 " muls.l %2, %3, %0" "\n"
3226 " xor %12, %5, %7" "\n"
3227 " bge/u %4, %6, %10" "\n"
3228 " shari %8, 16, %8" "\n"
3229 " muls.l %8, %2, %8" "\n"
3230 " sub %0, %7, %0" "\n"
3231 " shari %3, 14, %9" "\n"
3232 " shari %8, 30, %8" "\n"
3233 " muls.l %8, %9, %7" "\n"
3234 "%11: sub %0, %7, %0";
3237 (define_insn_and_split "divsi_inv_fp"
3238 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3239 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3240 (match_operand:SI 2 "register_operand" "rf")))
3241 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3242 (clobber (match_operand:SI 4 "register_operand" "=r"))
3243 (clobber (match_operand:SI 5 "register_operand" "=r"))
3244 (clobber (match_operand:DF 6 "register_operand" "=r"))
3245 (clobber (match_operand:DF 7 "register_operand" "=r"))
3246 (clobber (match_operand:DF 8 "register_operand" "=r"))]
3247 "TARGET_SHMEDIA_FPU"
3249 "&& (reload_in_progress || reload_completed)"
3250 [(set (match_dup 0) (match_dup 3))]
3252 [(set_attr "highpart" "must_split")])
3254 ;; If a matching group of divide-by-inverse instructions is in the same
3255 ;; basic block after gcse & loop optimizations, we want to transform them
3256 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3257 (define_insn_and_split "*divsi_inv_fp_combine"
3258 [(set (match_operand:SI 0 "register_operand" "=f")
3259 (div:SI (match_operand:SI 1 "register_operand" "f")
3260 (match_operand:SI 2 "register_operand" "f")))
3261 (use (unspec:SI [(match_dup 1)
3262 (match_operand:SI 3 "" "")
3263 (unspec:SI [(match_operand:SI 4 "" "")
3265 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3266 (match_operand:DI 6 "" "")
3268 (const_int 0)] UNSPEC_DIV_INV_M3))
3269 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3270 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3271 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3272 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3273 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3274 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3277 [(set (match_dup 9) (float:DF (match_dup 1)))
3278 (set (match_dup 10) (float:DF (match_dup 2)))
3279 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3281 (fix:SI (match_dup 11)))
3282 (set (match_dup 0) (match_dup 8))]
3284 if (! fp_arith_reg_operand (operands[1], SImode))
3286 emit_move_insn (operands[7], operands[1]);
3287 operands[1] = operands[7];
3289 if (! fp_arith_reg_operand (operands[2], SImode))
3291 emit_move_insn (operands[8], operands[2]);
3292 operands[2] = operands[8];
3295 [(set_attr "highpart" "must_split")])
3297 ;; -------------------------------------------------------------------------
3298 ;; Multiplication instructions
3299 ;; -------------------------------------------------------------------------
3301 (define_insn "umulhisi3_i"
3302 [(set (reg:SI MACL_REG)
3303 (mult:SI (zero_extend:SI
3304 (match_operand:HI 0 "arith_reg_operand" "r"))
3306 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3309 [(set_attr "type" "smpy")])
3311 (define_insn "mulhisi3_i"
3312 [(set (reg:SI MACL_REG)
3313 (mult:SI (sign_extend:SI
3314 (match_operand:HI 0 "arith_reg_operand" "r"))
3316 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3319 [(set_attr "type" "smpy")])
3321 (define_expand "mulhisi3"
3322 [(set (reg:SI MACL_REG)
3323 (mult:SI (sign_extend:SI
3324 (match_operand:HI 1 "arith_reg_operand" ""))
3326 (match_operand:HI 2 "arith_reg_operand" ""))))
3327 (set (match_operand:SI 0 "arith_reg_operand" "")
3334 macl = gen_rtx_REG (SImode, MACL_REG);
3336 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3337 insn = get_insns ();
3339 /* expand_binop can't find a suitable code in umul_widen_optab to
3340 make a REG_EQUAL note from, so make one here.
3341 See also smulsi3_highpart.
3342 ??? Alternatively, we could put this at the calling site of expand_binop,
3343 i.e. expand_expr. */
3344 /* Use emit_libcall_block for loop invariant code motion and to make
3345 a REG_EQUAL note. */
3346 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3351 (define_expand "umulhisi3"
3352 [(set (reg:SI MACL_REG)
3353 (mult:SI (zero_extend:SI
3354 (match_operand:HI 1 "arith_reg_operand" ""))
3356 (match_operand:HI 2 "arith_reg_operand" ""))))
3357 (set (match_operand:SI 0 "arith_reg_operand" "")
3364 macl = gen_rtx_REG (SImode, MACL_REG);
3366 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3367 insn = get_insns ();
3369 /* expand_binop can't find a suitable code in umul_widen_optab to
3370 make a REG_EQUAL note from, so make one here.
3371 See also smulsi3_highpart.
3372 ??? Alternatively, we could put this at the calling site of expand_binop,
3373 i.e. expand_expr. */
3374 /* Use emit_libcall_block for loop invariant code motion and to make
3375 a REG_EQUAL note. */
3376 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3381 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3382 ;; a call to a routine which clobbers known registers.
3384 [(set (match_operand:SI 1 "register_operand" "=z")
3385 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3386 (clobber (reg:SI MACL_REG))
3387 (clobber (reg:SI T_REG))
3388 (clobber (reg:SI PR_REG))
3389 (clobber (reg:SI R3_REG))
3390 (clobber (reg:SI R2_REG))
3391 (clobber (reg:SI R1_REG))
3392 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3395 [(set_attr "type" "sfunc")
3396 (set_attr "needs_delay_slot" "yes")])
3398 (define_expand "mulsi3_call"
3399 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3400 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3401 (parallel[(set (match_operand:SI 0 "register_operand" "")
3402 (mult:SI (reg:SI R4_REG)
3404 (clobber (reg:SI MACL_REG))
3405 (clobber (reg:SI T_REG))
3406 (clobber (reg:SI PR_REG))
3407 (clobber (reg:SI R3_REG))
3408 (clobber (reg:SI R2_REG))
3409 (clobber (reg:SI R1_REG))
3410 (use (match_operand:SI 3 "register_operand" ""))])]
3414 (define_insn "mul_r"
3415 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3416 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3417 (match_operand:SI 2 "arith_reg_operand" "z")))]
3420 [(set_attr "type" "dmpy")])
3422 (define_insn "mul_l"
3423 [(set (reg:SI MACL_REG)
3424 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3425 (match_operand:SI 1 "arith_reg_operand" "r")))]
3428 [(set_attr "type" "dmpy")])
3430 (define_expand "mulsi3"
3431 [(set (reg:SI MACL_REG)
3432 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
3433 (match_operand:SI 2 "arith_reg_operand" "")))
3434 (set (match_operand:SI 0 "arith_reg_operand" "")
3440 /* The address must be set outside the libcall,
3441 since it goes into a pseudo. */
3442 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3443 rtx addr = force_reg (SImode, sym);
3444 rtx insns = gen_mulsi3_call (operands[0], operands[1],
3450 rtx macl = gen_rtx_REG (SImode, MACL_REG);
3452 emit_insn (gen_mul_l (operands[1], operands[2]));
3453 /* consec_sets_giv can only recognize the first insn that sets a
3454 giv as the giv insn. So we must tag this also with a REG_EQUAL
3456 emit_insn (gen_movsi_i ((operands[0]), macl));
3461 (define_insn "mulsidi3_i"
3462 [(set (reg:SI MACH_REG)
3466 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3467 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3469 (set (reg:SI MACL_REG)
3470 (mult:SI (match_dup 0)
3474 [(set_attr "type" "dmpy")])
3476 (define_expand "mulsidi3"
3477 [(set (match_operand:DI 0 "arith_reg_dest" "")
3478 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3479 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3480 "TARGET_SH2 || TARGET_SHMEDIA"
3484 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3489 (define_insn "mulsidi3_media"
3490 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3491 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3492 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3495 [(set_attr "type" "dmpy_media")
3496 (set_attr "highpart" "ignore")])
3498 (define_insn_and_split "mulsidi3_compact"
3499 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3501 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3502 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3503 (clobber (reg:SI MACH_REG))
3504 (clobber (reg:SI MACL_REG))]
3510 rtx low_dst = gen_lowpart (SImode, operands[0]);
3511 rtx high_dst = gen_highpart (SImode, operands[0]);
3513 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3515 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3516 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3517 /* We need something to tag the possible REG_EQUAL notes on to. */
3518 emit_move_insn (operands[0], operands[0]);
3522 (define_insn "umulsidi3_i"
3523 [(set (reg:SI MACH_REG)
3527 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3528 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3530 (set (reg:SI MACL_REG)
3531 (mult:SI (match_dup 0)
3535 [(set_attr "type" "dmpy")])
3537 (define_expand "umulsidi3"
3538 [(set (match_operand:DI 0 "arith_reg_dest" "")
3539 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3540 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3541 "TARGET_SH2 || TARGET_SHMEDIA"
3545 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3550 (define_insn "umulsidi3_media"
3551 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3552 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3553 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3556 [(set_attr "type" "dmpy_media")
3557 (set_attr "highpart" "ignore")])
3559 (define_insn_and_split "umulsidi3_compact"
3560 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3562 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3563 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3564 (clobber (reg:SI MACH_REG))
3565 (clobber (reg:SI MACL_REG))]
3571 rtx low_dst = gen_lowpart (SImode, operands[0]);
3572 rtx high_dst = gen_highpart (SImode, operands[0]);
3574 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3576 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3577 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3578 /* We need something to tag the possible REG_EQUAL notes on to. */
3579 emit_move_insn (operands[0], operands[0]);
3583 (define_insn "smulsi3_highpart_i"
3584 [(set (reg:SI MACH_REG)
3588 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3589 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3591 (clobber (reg:SI MACL_REG))]
3594 [(set_attr "type" "dmpy")])
3596 (define_expand "smulsi3_highpart"
3598 [(set (reg:SI MACH_REG)
3602 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3603 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3605 (clobber (reg:SI MACL_REG))])
3606 (set (match_operand:SI 0 "arith_reg_operand" "")
3613 mach = gen_rtx_REG (SImode, MACH_REG);
3615 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3616 insn = get_insns ();
3618 /* expand_binop can't find a suitable code in mul_highpart_optab to
3619 make a REG_EQUAL note from, so make one here.
3620 See also {,u}mulhisi.
3621 ??? Alternatively, we could put this at the calling site of expand_binop,
3622 i.e. expand_mult_highpart. */
3623 /* Use emit_libcall_block for loop invariant code motion and to make
3624 a REG_EQUAL note. */
3625 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3630 (define_insn "umulsi3_highpart_i"
3631 [(set (reg:SI MACH_REG)
3635 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3636 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3638 (clobber (reg:SI MACL_REG))]
3641 [(set_attr "type" "dmpy")])
3643 (define_expand "umulsi3_highpart"
3645 [(set (reg:SI MACH_REG)
3649 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3650 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3652 (clobber (reg:SI MACL_REG))])
3653 (set (match_operand:SI 0 "arith_reg_operand" "")
3660 mach = gen_rtx_REG (SImode, MACH_REG);
3662 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3663 insn = get_insns ();
3665 /* Use emit_libcall_block for loop invariant code motion and to make
3666 a REG_EQUAL note. */
3667 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3672 (define_insn_and_split "muldi3"
3673 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3674 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3675 (match_operand:DI 2 "arith_reg_operand" "r")))
3676 (clobber (match_scratch:DI 3 "=&r"))
3677 (clobber (match_scratch:DI 4 "=r"))]
3683 rtx op3_v2si, op2_v2si;
3685 op3_v2si = operands[3];
3686 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3688 op3_v2si = XEXP (op3_v2si, 0);
3689 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3691 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3692 op2_v2si = operands[2];
3693 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3695 op2_v2si = XEXP (op2_v2si, 0);
3696 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3698 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3699 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3700 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3701 emit_insn (gen_umulsidi3_media (operands[4],
3702 sh_gen_truncate (SImode, operands[1], 0),
3703 sh_gen_truncate (SImode, operands[2], 0)));
3704 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3705 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3706 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3707 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3711 ;; -------------------------------------------------------------------------
3712 ;; Logical operations
3713 ;; -------------------------------------------------------------------------
3715 (define_expand "andsi3"
3716 [(set (match_operand:SI 0 "arith_reg_operand" "")
3717 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3718 (match_operand:SI 2 "logical_and_operand" "")))]
3721 /* If it is possible to turn the and insn into a zero extension
3722 already, redundant zero extensions will be folded, which results
3724 Ideally the splitter of *andsi_compact would be enough, if redundant
3725 zero extensions were detected after the combine pass, which does not
3726 happen at the moment. */
3729 if (satisfies_constraint_Jmb (operands[2]))
3731 emit_insn (gen_zero_extendqisi2 (operands[0],
3732 gen_lowpart (QImode, operands[1])));
3735 else if (satisfies_constraint_Jmw (operands[2]))
3737 emit_insn (gen_zero_extendhisi2 (operands[0],
3738 gen_lowpart (HImode, operands[1])));
3744 (define_insn_and_split "*andsi_compact"
3745 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3746 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3747 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3755 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3757 if (satisfies_constraint_Jmb (operands[2]))
3758 operands[1] = gen_lowpart (QImode, operands[1]);
3759 else if (satisfies_constraint_Jmw (operands[2]))
3760 operands[1] = gen_lowpart (HImode, operands[1]);
3764 [(set_attr "type" "arith")])
3766 (define_insn "*andsi3_media"
3767 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3768 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3769 (match_operand:SI 2 "logical_operand" "r,I10")))]
3774 [(set_attr "type" "arith_media")])
3776 (define_insn "*andsi3_bclr"
3777 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3778 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3779 (match_operand:SI 2 "const_int_operand" "Psz")))]
3780 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3782 [(set_attr "type" "arith")])
3784 (define_insn_and_split "anddi3"
3785 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3786 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3787 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3794 && ! logical_operand (operands[2], DImode)"
3797 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3798 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3800 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3803 [(set_attr "type" "arith_media")])
3805 (define_insn "andcsi3"
3806 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3807 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3808 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3811 [(set_attr "type" "arith_media")])
3813 (define_insn "andcdi3"
3814 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3815 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3816 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3819 [(set_attr "type" "arith_media")])
3821 (define_expand "iorsi3"
3822 [(set (match_operand:SI 0 "arith_reg_operand" "")
3823 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3824 (match_operand:SI 2 "logical_operand" "")))]
3828 (define_insn "*iorsi3_compact"
3829 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3830 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3831 (match_operand:SI 2 "logical_operand" "r,K08")))]
3833 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3835 [(set_attr "type" "arith")])
3837 (define_insn "*iorsi3_media"
3838 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3839 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3840 (match_operand:SI 2 "logical_operand" "r,I10")))]
3845 [(set_attr "type" "arith_media")])
3847 (define_insn "*iorsi3_bset"
3848 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3849 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3850 (match_operand:SI 2 "const_int_operand" "Pso")))]
3851 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3853 [(set_attr "type" "arith")])
3855 (define_insn "iordi3"
3856 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3857 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3858 (match_operand:DI 2 "logical_operand" "r,I10")))]
3863 [(set_attr "type" "arith_media")])
3865 (define_insn_and_split "*logical_sidi3"
3866 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3867 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3868 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3869 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3872 "&& reload_completed"
3873 [(set (match_dup 0) (match_dup 3))]
3876 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3877 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3878 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3881 (define_insn_and_split "*logical_sidisi3"
3882 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3883 (truncate:SI (sign_extend:DI
3884 (match_operator:SI 3 "logical_operator"
3885 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3886 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3890 [(set (match_dup 0) (match_dup 3))])
3892 (define_insn_and_split "*logical_sidi3_2"
3893 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3894 (sign_extend:DI (truncate:SI (sign_extend:DI
3895 (match_operator:SI 3 "logical_operator"
3896 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3897 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3901 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3903 (define_expand "xorsi3"
3904 [(set (match_operand:SI 0 "arith_reg_operand" "")
3905 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3906 (match_operand:SI 2 "xor_operand" "")))]
3910 (define_insn "*xorsi3_compact"
3911 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3912 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3913 (match_operand:SI 2 "logical_operand" "K08,r")))]
3916 [(set_attr "type" "arith")])
3918 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
3919 ;; of results where one of the inputs is a T bit store. Notice that this
3920 ;; pattern must not match during reload. If reload picks this pattern it
3921 ;; will be impossible to split it afterwards.
3922 (define_insn_and_split "*logical_op_t"
3923 [(set (match_operand:SI 0 "arith_reg_dest")
3924 (match_operator:SI 3 "logical_operator"
3925 [(match_operand:SI 1 "arith_reg_operand")
3926 (match_operand:SI 2 "t_reg_operand")]))]
3927 "TARGET_SH1 && can_create_pseudo_p ()"
3930 [(set (match_dup 4) (reg:SI T_REG))
3931 (set (match_dup 0) (match_dup 3))]
3933 operands[4] = gen_reg_rtx (SImode);
3934 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3935 operands[1], operands[4]);
3938 (define_insn "*xorsi3_media"
3939 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3940 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3941 (match_operand:SI 2 "xor_operand" "r,I06")))]
3946 [(set_attr "type" "arith_media")])
3948 (define_insn "xordi3"
3949 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3950 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3951 (match_operand:DI 2 "xor_operand" "r,I06")))]
3956 [(set_attr "type" "arith_media")])
3958 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3959 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3961 [(set (match_operand:DI 0 "arith_reg_dest" "")
3962 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3963 [(match_operand 1 "any_register_operand" "")
3964 (match_operand 2 "any_register_operand" "")])))]
3966 [(set (match_dup 5) (match_dup 4))
3967 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3969 machine_mode inmode = GET_MODE (operands[1]);
3972 if (GET_CODE (operands[0]) == SUBREG)
3974 offset = SUBREG_BYTE (operands[0]);
3975 operands[0] = SUBREG_REG (operands[0]);
3977 gcc_assert (REG_P (operands[0]));
3978 if (TARGET_BIG_ENDIAN)
3979 offset += 8 - GET_MODE_SIZE (inmode);
3980 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3983 ;; -------------------------------------------------------------------------
3984 ;; Shifts and rotates
3985 ;; -------------------------------------------------------------------------
3987 (define_expand "rotldi3"
3988 [(set (match_operand:DI 0 "arith_reg_dest" "")
3989 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
3990 (match_operand:HI 2 "mextr_bit_offset" "")))]
3993 if (! mextr_bit_offset (operands[2], HImode))
3997 (define_insn "rotldi3_mextr"
3998 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3999 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
4000 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4003 static char templ[16];
4004 sprintf (templ, "mextr%d %%1,%%1,%%0",
4005 8 - (int) (INTVAL (operands[2]) >> 3));
4008 [(set_attr "type" "arith_media")])
4010 (define_expand "rotrdi3"
4011 [(set (match_operand:DI 0 "arith_reg_dest" "")
4012 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
4013 (match_operand:HI 2 "mextr_bit_offset" "")))]
4016 if (! mextr_bit_offset (operands[2], HImode))
4020 (define_insn "rotrdi3_mextr"
4021 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4022 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
4023 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4026 static char templ[16];
4027 sprintf (templ, "mextr%d %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
4030 [(set_attr "type" "arith_media")])
4033 [(set (match_operand:DI 0 "arith_reg_dest" "")
4034 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
4035 "ua_address_operand" "")))
4036 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
4038 (clobber (match_operand:DI 3 "register_operand" ""))]
4040 [(match_dup 4) (match_dup 5)]
4042 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
4043 (operands[3], operands[1]));
4044 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
4045 GEN_INT (56), GEN_INT (8));
4048 (define_expand "rotrsi3"
4049 [(set (match_operand:SI 0 "arith_reg_dest")
4050 (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
4051 (match_operand:SI 2 "const_int_operand")))]
4054 HOST_WIDE_INT ival = INTVAL (operands[2]);
4057 emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
4064 (define_insn "rotrsi3_1"
4065 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4066 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4069 (and:SI (match_dup 1) (const_int 1)))]
4072 [(set_attr "type" "arith")])
4074 ;; A slimplified version of rotr for combine.
4075 (define_insn "*rotrsi3_1"
4076 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4077 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4079 (clobber (reg:SI T_REG))]
4082 [(set_attr "type" "arith")])
4084 (define_insn "rotlsi3_1"
4085 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4086 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4089 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4092 [(set_attr "type" "arith")])
4094 ;; A simplified version of rotl for combine.
4095 (define_insn "*rotlsi3_1"
4096 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4097 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4099 (clobber (reg:SI T_REG))]
4102 [(set_attr "type" "arith")])
4104 (define_insn "rotlsi3_31"
4105 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4106 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4108 (clobber (reg:SI T_REG))]
4111 [(set_attr "type" "arith")])
4113 (define_insn "rotlsi3_16"
4114 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4115 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
4119 [(set_attr "type" "arith")])
4121 (define_expand "rotlsi3"
4122 [(set (match_operand:SI 0 "arith_reg_dest")
4123 (rotate:SI (match_operand:SI 1 "arith_reg_operand")
4124 (match_operand:SI 2 "const_int_operand")))]
4127 static const char rot_tab[] = {
4128 000, 000, 000, 000, 000, 000, 010, 001,
4129 001, 001, 011, 013, 003, 003, 003, 003,
4130 003, 003, 003, 003, 003, 013, 012, 002,
4131 002, 002, 010, 000, 000, 000, 000, 000,
4134 int count = INTVAL (operands[2]);
4135 int choice = rot_tab[count];
4136 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
4142 emit_move_insn (operands[0], operands[1]);
4143 count -= (count & 16) * 2;
4146 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
4153 parts[0] = gen_reg_rtx (SImode);
4154 parts[1] = gen_reg_rtx (SImode);
4155 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
4156 emit_move_insn (parts[choice-1], operands[1]);
4157 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
4158 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
4159 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
4160 count = (count & ~16) - 8;
4164 for (; count > 0; count--)
4165 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
4166 for (; count < 0; count++)
4167 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4172 (define_insn "rotlhi3_8"
4173 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4174 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
4178 [(set_attr "type" "arith")])
4180 (define_expand "rotlhi3"
4181 [(set (match_operand:HI 0 "arith_reg_operand")
4182 (rotate:HI (match_operand:HI 1 "arith_reg_operand")
4183 (match_operand:HI 2 "const_int_operand")))]
4186 if (INTVAL (operands[2]) != 8)
4190 ;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
4191 ;; They can also be used to implement things like
4193 ;; int x0 = (y >> 1) | (t << 31); // rotcr
4194 ;; int x1 = (y << 1) | t; // rotcl
4195 (define_insn "rotcr"
4196 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4197 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4199 (ashift:SI (match_operand:SI 2 "t_reg_operand")
4202 (and:SI (match_dup 1) (const_int 1)))]
4205 [(set_attr "type" "arith")])
4207 (define_insn "rotcl"
4208 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4209 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4211 (match_operand:SI 2 "t_reg_operand")))
4213 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4216 [(set_attr "type" "arith")])
4218 ;; Simplified rotcr version for combine, which allows arbitrary shift
4219 ;; amounts for the reg. If the shift amount is '1' rotcr can be used
4220 ;; directly. Otherwise we have to insert a shift in between.
4221 (define_insn_and_split "*rotcr"
4222 [(set (match_operand:SI 0 "arith_reg_dest")
4223 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4224 (match_operand:SI 2 "const_int_operand"))
4225 (ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4227 (clobber (reg:SI T_REG))]
4230 "&& can_create_pseudo_p ()"
4233 if (INTVAL (operands[2]) > 1)
4235 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4236 rtx prev_set_t_insn = NULL_RTX;
4237 rtx tmp_t_reg = NULL_RTX;
4239 /* If we're going to emit a shift sequence that clobbers the T_REG,
4240 try to find the previous insn that sets the T_REG and emit the
4241 shift insn before that insn, to remove the T_REG dependency.
4242 If the insn that sets the T_REG cannot be found, store the T_REG
4243 in a temporary reg and restore it after the shift. */
4244 if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4245 && ! sh_dynamicalize_shift_p (shift_count))
4247 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4249 /* Skip the nott insn, which was probably inserted by the splitter
4250 of *rotcr_neg_t. Don't use one of the recog functions
4251 here during insn splitting, since that causes problems in later
4253 if (prev_set_t_insn != NULL_RTX)
4255 rtx pat = PATTERN (prev_set_t_insn);
4256 if (GET_CODE (pat) == SET
4257 && t_reg_operand (XEXP (pat, 0), SImode)
4258 && negt_reg_operand (XEXP (pat, 1), SImode))
4259 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4262 if (! (prev_set_t_insn != NULL_RTX
4263 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4264 && ! reg_referenced_p (get_t_reg_rtx (),
4265 PATTERN (prev_set_t_insn))))
4267 prev_set_t_insn = NULL_RTX;
4268 tmp_t_reg = gen_reg_rtx (SImode);
4269 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4273 rtx shift_result = gen_reg_rtx (SImode);
4274 rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4275 operands[1] = shift_result;
4277 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4278 if (prev_set_t_insn != NULL_RTX)
4279 emit_insn_before (shift_insn, prev_set_t_insn);
4281 emit_insn (shift_insn);
4283 /* Restore T_REG if it has been saved before. */
4284 if (tmp_t_reg != NULL_RTX)
4285 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4288 /* For the rotcr insn to work, operands[3] must be in T_REG.
4289 If it is not we can get it there by shifting it right one bit.
4290 In this case T_REG is not an input for this insn, thus we don't have to
4291 pay attention as of where to insert the shlr insn. */
4292 if (! t_reg_operand (operands[3], SImode))
4294 /* We don't care about the shifted result here, only the T_REG. */
4295 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4296 operands[3] = get_t_reg_rtx ();
4299 emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4303 ;; If combine tries the same as above but with swapped operands, split
4304 ;; it so that it will try the pattern above.
4306 [(set (match_operand:SI 0 "arith_reg_dest")
4307 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4309 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4310 (match_operand:SI 3 "const_int_operand"))))]
4311 "TARGET_SH1 && can_create_pseudo_p ()"
4312 [(parallel [(set (match_dup 0)
4313 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4314 (ashift:SI (match_dup 1) (const_int 31))))
4315 (clobber (reg:SI T_REG))])])
4317 ;; Basically the same as the rotcr pattern above, but for rotcl.
4318 ;; FIXME: Fold copy pasted split code for rotcr and rotcl.
4319 (define_insn_and_split "*rotcl"
4320 [(set (match_operand:SI 0 "arith_reg_dest")
4321 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4322 (match_operand:SI 2 "const_int_operand"))
4323 (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4325 (clobber (reg:SI T_REG))]
4328 "&& can_create_pseudo_p ()"
4331 gcc_assert (INTVAL (operands[2]) > 0);
4333 if (INTVAL (operands[2]) > 1)
4335 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4336 rtx prev_set_t_insn = NULL_RTX;
4337 rtx tmp_t_reg = NULL_RTX;
4339 /* If we're going to emit a shift sequence that clobbers the T_REG,
4340 try to find the previous insn that sets the T_REG and emit the
4341 shift insn before that insn, to remove the T_REG dependency.
4342 If the insn that sets the T_REG cannot be found, store the T_REG
4343 in a temporary reg and restore it after the shift. */
4344 if (sh_ashlsi_clobbers_t_reg_p (shift_count)
4345 && ! sh_dynamicalize_shift_p (shift_count))
4347 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4349 /* Skip the nott insn, which was probably inserted by the splitter
4350 of *rotcl_neg_t. Don't use one of the recog functions
4351 here during insn splitting, since that causes problems in later
4353 if (prev_set_t_insn != NULL_RTX)
4355 rtx pat = PATTERN (prev_set_t_insn);
4356 if (GET_CODE (pat) == SET
4357 && t_reg_operand (XEXP (pat, 0), SImode)
4358 && negt_reg_operand (XEXP (pat, 1), SImode))
4359 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4362 if (! (prev_set_t_insn != NULL_RTX
4363 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4364 && ! reg_referenced_p (get_t_reg_rtx (),
4365 PATTERN (prev_set_t_insn))))
4367 prev_set_t_insn = NULL_RTX;
4368 tmp_t_reg = gen_reg_rtx (SImode);
4369 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4373 rtx shift_result = gen_reg_rtx (SImode);
4374 rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
4375 operands[1] = shift_result;
4377 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4378 if (prev_set_t_insn != NULL_RTX)
4379 emit_insn_before (shift_insn, prev_set_t_insn);
4381 emit_insn (shift_insn);
4383 /* Restore T_REG if it has been saved before. */
4384 if (tmp_t_reg != NULL_RTX)
4385 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4388 /* For the rotcl insn to work, operands[3] must be in T_REG.
4389 If it is not we can get it there by shifting it right one bit.
4390 In this case T_REG is not an input for this insn, thus we don't have to
4391 pay attention as of where to insert the shlr insn. */
4392 if (! t_reg_operand (operands[3], SImode))
4394 /* We don't care about the shifted result here, only the T_REG. */
4395 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4396 operands[3] = get_t_reg_rtx ();
4399 emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
4403 ;; rotcl combine pattern variations
4404 (define_insn_and_split "*rotcl"
4405 [(set (match_operand:SI 0 "arith_reg_dest")
4406 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4407 (match_operand:SI 2 "const_int_operand"))
4408 (match_operand:SI 3 "t_reg_operand")))
4409 (clobber (reg:SI T_REG))]
4412 "&& can_create_pseudo_p ()"
4413 [(parallel [(set (match_dup 0)
4414 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4415 (and:SI (match_dup 3) (const_int 1))))
4416 (clobber (reg:SI T_REG))])])
4418 (define_insn_and_split "*rotcl"
4419 [(set (match_operand:SI 0 "arith_reg_dest")
4420 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4422 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4423 (match_operand:SI 3 "const_int_operand"))))
4424 (clobber (reg:SI T_REG))]
4427 "&& can_create_pseudo_p ()"
4428 [(parallel [(set (match_dup 0)
4429 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4430 (and:SI (match_dup 1) (const_int 1))))
4431 (clobber (reg:SI T_REG))])])
4433 (define_insn_and_split "*rotcl"
4434 [(set (match_operand:SI 0 "arith_reg_dest")
4435 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4436 (match_operand:SI 2 "const_int_operand"))
4437 (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4439 (clobber (reg:SI T_REG))]
4442 "&& can_create_pseudo_p ()"
4443 [(parallel [(set (match_dup 0)
4444 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4445 (and:SI (reg:SI T_REG) (const_int 1))))
4446 (clobber (reg:SI T_REG))])]
4448 /* We don't care about the result of the left shift, only the T_REG. */
4449 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4452 (define_insn_and_split "*rotcl"
4453 [(set (match_operand:SI 0 "arith_reg_dest")
4454 (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4456 (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4457 (match_operand:SI 2 "const_int_operand"))))
4458 (clobber (reg:SI T_REG))]
4461 "&& can_create_pseudo_p ()"
4462 [(parallel [(set (match_dup 0)
4463 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4464 (and:SI (reg:SI T_REG) (const_int 1))))
4465 (clobber (reg:SI T_REG))])]
4467 /* We don't care about the result of the left shift, only the T_REG. */
4468 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4471 ;; rotcr combine bridge pattern which will make combine try out more
4472 ;; complex patterns.
4473 (define_insn_and_split "*rotcr"
4474 [(set (match_operand:SI 0 "arith_reg_dest")
4475 (ashift:SI (match_operand:SI 1 "t_reg_operand") (const_int 31)))]
4479 [(set (match_dup 0) (match_dup 1))
4480 (parallel [(set (match_dup 0)
4481 (ior:SI (lshiftrt:SI (match_dup 0) (const_int 1))
4482 (ashift:SI (match_dup 1) (const_int 31))))
4484 (and:SI (match_dup 0) (const_int 1)))])])
4486 (define_insn_and_split "*rotcr"
4487 [(set (match_operand:SI 0 "arith_reg_dest")
4488 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4489 (const_int -2147483648)) ;; 0xffffffff80000000
4490 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4492 (clobber (reg:SI T_REG))]
4495 "&& can_create_pseudo_p ()"
4498 rtx tmp = gen_reg_rtx (SImode);
4499 emit_insn (gen_shll (tmp, operands[1]));
4500 emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4504 ;; rotcr combine patterns for rotating in the negated T_REG value.
4505 (define_insn_and_split "*rotcr_neg_t"
4506 [(set (match_operand:SI 0 "arith_reg_dest")
4507 (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4508 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4509 (match_operand:SI 3 "const_int_operand"))))
4510 (clobber (reg:SI T_REG))]
4513 "&& can_create_pseudo_p ()"
4514 [(parallel [(set (match_dup 0)
4515 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4516 (ashift:SI (reg:SI T_REG) (const_int 31))))
4517 (clobber (reg:SI T_REG))])]
4519 emit_insn (gen_nott (get_t_reg_rtx ()));
4522 (define_insn_and_split "*rotcr_neg_t"
4523 [(set (match_operand:SI 0 "arith_reg_dest")
4524 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4525 (match_operand:SI 2 "const_int_operand"))
4526 (match_operand:SI 3 "negt_reg_shl31_operand")))
4527 (clobber (reg:SI T_REG))]
4530 "&& can_create_pseudo_p ()"
4531 [(parallel [(set (match_dup 0)
4532 (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4533 (ashift:SI (reg:SI T_REG) (const_int 31))))
4534 (clobber (reg:SI T_REG))])]
4536 emit_insn (gen_nott (get_t_reg_rtx ()));
4539 ;; rotcl combine patterns for rotating in the negated T_REG value.
4540 ;; For some strange reason these have to be specified as splits which combine
4541 ;; will pick up. If they are specified as insn_and_split like the
4542 ;; *rotcr_neg_t patterns above, combine would recognize them successfully
4543 ;; but not emit them on non-SH2A targets.
4545 [(set (match_operand:SI 0 "arith_reg_dest")
4546 (ior:SI (match_operand:SI 1 "negt_reg_operand")
4547 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4548 (match_operand:SI 3 "const_int_operand"))))]
4550 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4551 (parallel [(set (match_dup 0)
4552 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4553 (and:SI (reg:SI T_REG) (const_int 1))))
4554 (clobber (reg:SI T_REG))])])
4557 [(set (match_operand:SI 0 "arith_reg_dest")
4558 (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4559 (match_operand:SI 3 "const_int_operand"))
4560 (match_operand:SI 1 "negt_reg_operand")))]
4562 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4563 (parallel [(set (match_dup 0)
4564 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4565 (and:SI (reg:SI T_REG) (const_int 1))))
4566 (clobber (reg:SI T_REG))])])
4568 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4569 ;; SImode shift left
4571 (define_expand "ashlsi3"
4572 [(set (match_operand:SI 0 "arith_reg_operand" "")
4573 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4574 (match_operand:SI 2 "shift_count_operand" "")))]
4579 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4581 operands[2] = GEN_INT (-INTVAL (operands[2]));
4582 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4585 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4589 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4590 operands[2] = force_reg (SImode, operands[2]);
4592 /* If the ashlsi3_* insn is going to clobber the T_REG it must be
4594 if (CONST_INT_P (operands[2])
4595 && sh_ashlsi_clobbers_t_reg_p (operands[2])
4596 && ! sh_dynamicalize_shift_p (operands[2]))
4598 emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4603 /* Expand a library call for the dynamic shift. */
4604 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4606 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4607 rtx funcaddr = gen_reg_rtx (Pmode);
4608 function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4609 emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4615 (define_insn "ashlsi3_k"
4616 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4617 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4618 (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4623 [(set_attr "type" "arith")])
4625 (define_insn_and_split "ashlsi3_d"
4626 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4627 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4628 (match_operand:SI 2 "shift_count_operand" "r")))]
4631 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4632 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4635 if (satisfies_constraint_P27 (operands[2]))
4637 emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
4640 else if (! satisfies_constraint_P27 (operands[2]))
4642 /* This must happen before reload, otherwise the constant will be moved
4643 into a register due to the "r" constraint, after which this split
4644 cannot be done anymore.
4645 Unfortunately the move insn will not always be eliminated.
4646 Also, here we must not create a shift sequence that clobbers the
4648 emit_move_insn (operands[0], operands[1]);
4649 gen_shifty_op (ASHIFT, operands);
4655 [(set_attr "type" "dyn_shift")])
4657 ;; If dynamic shifts are not available use a library function.
4658 ;; By specifying the pattern we reduce the number of call clobbered regs.
4659 ;; In order to make combine understand the truncation of the shift amount
4660 ;; operand we have to allow it to use pseudo regs for the shift operands.
4661 (define_insn "ashlsi3_d_call"
4662 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4663 (ashift:SI (reg:SI R4_REG)
4664 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4666 (use (match_operand:SI 2 "arith_reg_operand" "r"))
4667 (clobber (reg:SI T_REG))
4668 (clobber (reg:SI PR_REG))]
4669 "TARGET_SH1 && !TARGET_DYNSHIFT"
4671 [(set_attr "type" "sfunc")
4672 (set_attr "needs_delay_slot" "yes")])
4674 (define_insn_and_split "ashlsi3_n"
4675 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4676 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4677 (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
4678 "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4680 "&& (reload_completed
4681 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4684 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4686 /* If this pattern was picked and dynamic shifts are supported, switch
4687 to dynamic shift pattern before reload. */
4688 operands[2] = force_reg (SImode, operands[2]);
4689 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4692 gen_shifty_op (ASHIFT, operands);
4697 (define_insn_and_split "ashlsi3_n_clobbers_t"
4698 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4699 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4700 (match_operand:SI 2 "not_p27_shift_count_operand" "")))
4701 (clobber (reg:SI T_REG))]
4702 "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
4704 "&& (reload_completed || INTVAL (operands[2]) == 31
4705 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4708 if (INTVAL (operands[2]) == 31)
4710 /* If the shift amount is 31 we split into a different sequence before
4711 reload so that it gets a chance to allocate R0 for the sequence.
4712 If it fails to do so (due to pressure on R0), it will take one insn
4713 more for the and. */
4714 emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
4715 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4717 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4719 /* If this pattern was picked and dynamic shifts are supported, switch
4720 to dynamic shift pattern before reload. */
4721 operands[2] = force_reg (SImode, operands[2]);
4722 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4725 gen_shifty_op (ASHIFT, operands);
4731 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4732 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4734 (lt:SI (match_dup 1) (const_int 0)))]
4737 [(set_attr "type" "arith")])
4739 (define_insn "*ashlsi_c_void"
4740 [(set (reg:SI T_REG)
4741 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
4742 (clobber (match_scratch:SI 1 "=0"))]
4743 "TARGET_SH1 && cse_not_expected"
4745 [(set_attr "type" "arith")])
4748 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
4750 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
4752 && peep2_reg_dead_p (2, operands[0])
4753 && peep2_reg_dead_p (2, operands[1])"
4756 emit_insn (gen_shll (operands[1], operands[1]));
4760 (define_insn "ashlsi3_media"
4761 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4762 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4763 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4768 [(set_attr "type" "arith_media")
4769 (set_attr "highpart" "ignore")])
4771 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4772 ;; HImode shift left
4774 (define_expand "ashlhi3"
4775 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
4776 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
4777 (match_operand:SI 2 "nonmemory_operand" "")))
4778 (clobber (reg:SI T_REG))])]
4781 if (!CONST_INT_P (operands[2]))
4783 /* It may be possible to call gen_ashlhi3 directly with more generic
4784 operands. Make sure operands[1] is a HImode register here. */
4785 if (!arith_reg_operand (operands[1], HImode))
4786 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4789 (define_insn "ashlhi3_k"
4790 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4791 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
4792 (match_operand:HI 2 "const_int_operand" "M,P27")))]
4793 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
4797 [(set_attr "type" "arith")])
4799 (define_insn_and_split "*ashlhi3_n"
4800 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4801 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
4802 (match_operand:HI 2 "const_int_operand" "n")))
4803 (clobber (reg:SI T_REG))]
4806 "&& reload_completed"
4807 [(use (reg:SI R0_REG))]
4809 gen_shifty_hi_op (ASHIFT, operands);
4813 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4814 ;; DImode shift left
4816 (define_expand "ashldi3"
4817 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4818 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4819 (match_operand:DI 2 "immediate_operand" "")))
4820 (clobber (reg:SI T_REG))])]
4825 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4827 operands[2] = GEN_INT (-INTVAL (operands[2]));
4828 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4831 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4834 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
4836 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4839 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
4841 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4848 ;; Expander for DImode shift left with SImode operations.
4849 (define_expand "ashldi3_std"
4850 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4851 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4852 (match_operand:DI 2 "const_int_operand" "n")))]
4853 "TARGET_SH1 && INTVAL (operands[2]) < 32"
4855 rtx low_src = gen_lowpart (SImode, operands[1]);
4856 rtx high_src = gen_highpart (SImode, operands[1]);
4857 rtx dst = gen_reg_rtx (DImode);
4858 rtx low_dst = gen_lowpart (SImode, dst);
4859 rtx high_dst = gen_highpart (SImode, dst);
4860 rtx tmp0 = gen_reg_rtx (SImode);
4861 rtx tmp1 = gen_reg_rtx (SImode);
4863 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4864 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
4865 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
4866 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4867 emit_move_insn (operands[0], dst);
4871 (define_insn_and_split "ashldi3_k"
4872 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4873 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
4875 (clobber (reg:SI T_REG))]
4878 "&& reload_completed"
4881 rtx high = gen_highpart (SImode, operands[0]);
4882 rtx low = gen_lowpart (SImode, operands[0]);
4883 emit_insn (gen_shll (low, low));
4884 emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
4888 (define_insn "ashldi3_media"
4889 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4890 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4891 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4896 [(set_attr "type" "arith_media")])
4898 (define_insn "*ashldisi3_media"
4899 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4900 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4901 (match_operand:DI 2 "const_int_operand" "n")))]
4902 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4903 "shlli.l %1, %2, %0"
4904 [(set_attr "type" "arith_media")
4905 (set_attr "highpart" "ignore")])
4907 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4908 ;; SImode arithmetic shift right
4910 ;; We can't do HImode right shifts correctly unless we start out with an
4911 ;; explicit zero / sign extension; doing that would result in worse overall
4912 ;; code, so just let the machine independent code widen the mode.
4913 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
4915 (define_expand "ashrsi3"
4916 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4917 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4918 (match_operand:SI 2 "nonmemory_operand" "")))
4919 (clobber (reg:SI T_REG))])]
4924 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4926 operands[2] = GEN_INT (-INTVAL (operands[2]));
4927 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4930 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4933 if (expand_ashiftrt (operands))
4940 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4941 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4944 (and:SI (match_dup 1) (const_int 1)))]
4947 [(set_attr "type" "arith")])
4949 (define_insn "ashrsi3_k"
4950 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4951 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4952 (match_operand:SI 2 "const_int_operand" "M")))
4953 (clobber (reg:SI T_REG))]
4954 "TARGET_SH1 && INTVAL (operands[2]) == 1"
4956 [(set_attr "type" "arith")])
4958 (define_insn_and_split "ashrsi2_16"
4959 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4960 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
4965 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
4966 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
4968 operands[2] = gen_lowpart (HImode, operands[0]);
4971 (define_insn_and_split "ashrsi2_31"
4972 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4973 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4975 (clobber (reg:SI T_REG))]
4981 emit_insn (gen_shll (operands[0], operands[1]));
4982 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
4986 (define_insn "ashrsi3_d"
4987 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4988 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4989 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4992 [(set_attr "type" "dyn_shift")])
4994 (define_insn "ashrsi3_n"
4995 [(set (reg:SI R4_REG)
4996 (ashiftrt:SI (reg:SI R4_REG)
4997 (match_operand:SI 0 "const_int_operand" "i")))
4998 (clobber (reg:SI T_REG))
4999 (clobber (reg:SI PR_REG))
5000 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
5003 [(set_attr "type" "sfunc")
5004 (set_attr "needs_delay_slot" "yes")])
5006 (define_insn "ashrsi3_media"
5007 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5008 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5009 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5014 [(set_attr "type" "arith_media")
5015 (set_attr "highpart" "ignore")])
5017 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5018 ;; DImode arithmetic shift right
5020 (define_expand "ashrdi3"
5021 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5022 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5023 (match_operand:DI 2 "immediate_operand" "")))
5024 (clobber (reg:SI T_REG))])]
5029 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5031 operands[2] = GEN_INT (-INTVAL (operands[2]));
5032 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5035 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
5038 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5042 (define_insn_and_split "ashrdi3_k"
5043 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5044 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5046 (clobber (reg:SI T_REG))]
5049 "&& reload_completed"
5052 rtx high = gen_highpart (SImode, operands[0]);
5053 rtx low = gen_lowpart (SImode, operands[0]);
5054 emit_insn (gen_shar (high, high));
5055 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5059 (define_insn "ashrdi3_media"
5060 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5061 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5062 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5064 && (arith_reg_dest (operands[0], DImode)
5065 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
5069 [(set_attr "type" "arith_media")])
5071 (define_insn "*ashrdisi3_media"
5072 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5073 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5074 (match_operand:DI 2 "const_int_operand" "n")))]
5075 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5076 "shari.l %1, %2, %0"
5077 [(set_attr "type" "arith_media")
5078 (set_attr "highpart" "ignore")])
5080 (define_insn "ashrdisi3_media_high"
5081 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5083 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5084 (match_operand:DI 2 "const_int_operand" "n"))))]
5085 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
5087 [(set_attr "type" "arith_media")])
5089 (define_insn "ashrdisi3_media_opaque"
5090 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5091 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
5092 (match_operand:DI 2 "const_int_operand" "n")]
5096 [(set_attr "type" "arith_media")])
5098 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5099 ;; SImode logical shift right
5101 (define_expand "lshrsi3"
5102 [(set (match_operand:SI 0 "arith_reg_dest" "")
5103 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
5104 (match_operand:SI 2 "shift_count_operand" "")))]
5109 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5111 operands[2] = GEN_INT (-INTVAL (operands[2]));
5112 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
5115 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
5119 /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
5120 here, otherwise the pattern will never match due to the shift amount reg
5123 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
5125 rtx neg_count = force_reg (SImode,
5126 gen_int_mode (- INTVAL (operands[2]), SImode));
5127 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5131 if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
5133 rtx neg_count = gen_reg_rtx (SImode);
5134 emit_insn (gen_negsi2 (neg_count, operands[2]));
5135 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5139 /* If the lshrsi3_* insn is going to clobber the T_REG it must be
5141 if (CONST_INT_P (operands[2])
5142 && sh_lshrsi_clobbers_t_reg_p (operands[2])
5143 && ! sh_dynamicalize_shift_p (operands[2]))
5145 emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
5150 /* Expand a library call for the dynamic shift. */
5151 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
5153 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
5154 rtx funcaddr = gen_reg_rtx (Pmode);
5155 function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
5156 emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
5161 (define_insn "lshrsi3_k"
5162 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5163 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5164 (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
5167 [(set_attr "type" "arith")])
5169 (define_insn_and_split "lshrsi3_d"
5170 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5171 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5172 (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
5175 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
5176 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5179 if (satisfies_constraint_P27 (operands[2]))
5181 /* This will not be done for a shift amount of 1, because it would
5182 clobber the T_REG. */
5183 emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
5186 else if (! satisfies_constraint_P27 (operands[2]))
5188 /* This must happen before reload, otherwise the constant will be moved
5189 into a register due to the "r" constraint, after which this split
5190 cannot be done anymore.
5191 Unfortunately the move insn will not always be eliminated.
5192 Also, here we must not create a shift sequence that clobbers the
5194 emit_move_insn (operands[0], operands[1]);
5195 gen_shifty_op (LSHIFTRT, operands);
5201 [(set_attr "type" "dyn_shift")])
5203 ;; If dynamic shifts are not available use a library function.
5204 ;; By specifying the pattern we reduce the number of call clobbered regs.
5205 ;; In order to make combine understand the truncation of the shift amount
5206 ;; operand we have to allow it to use pseudo regs for the shift operands.
5207 (define_insn "lshrsi3_d_call"
5208 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
5209 (lshiftrt:SI (reg:SI R4_REG)
5210 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5212 (use (match_operand:SI 2 "arith_reg_operand" "r"))
5213 (clobber (reg:SI T_REG))
5214 (clobber (reg:SI PR_REG))]
5215 "TARGET_SH1 && !TARGET_DYNSHIFT"
5217 [(set_attr "type" "sfunc")
5218 (set_attr "needs_delay_slot" "yes")])
5220 (define_insn_and_split "lshrsi3_n"
5221 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5222 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5223 (match_operand:SI 2 "not_p27_rshift_count_operand")))]
5224 "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5226 "&& (reload_completed
5227 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5230 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5232 /* If this pattern was picked and dynamic shifts are supported, switch
5233 to dynamic shift pattern before reload. */
5234 operands[2] = force_reg (SImode,
5235 gen_int_mode (- INTVAL (operands[2]), SImode));
5236 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5239 gen_shifty_op (LSHIFTRT, operands);
5244 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
5245 ;; the shlr pattern.
5246 (define_insn_and_split "lshrsi3_n_clobbers_t"
5247 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5248 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5249 (match_operand:SI 2 "not_p27_rshift_count_operand")))
5250 (clobber (reg:SI T_REG))]
5251 "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
5253 "&& (reload_completed || INTVAL (operands[2]) == 31
5254 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5257 if (INTVAL (operands[2]) == 31)
5259 emit_insn (gen_shll (operands[0], operands[1]));
5260 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
5262 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5264 /* If this pattern was picked and dynamic shifts are supported, switch
5265 to dynamic shift pattern before reload. */
5266 operands[2] = force_reg (SImode,
5267 gen_int_mode (- INTVAL (operands[2]), SImode));
5268 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5271 gen_shifty_op (LSHIFTRT, operands);
5277 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5278 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5281 (and:SI (match_dup 1) (const_int 1)))]
5284 [(set_attr "type" "arith")])
5286 (define_insn "lshrsi3_media"
5287 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5288 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5289 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5294 [(set_attr "type" "arith_media")
5295 (set_attr "highpart" "ignore")])
5297 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5298 ;; DImode logical shift right
5300 (define_expand "lshrdi3"
5301 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5302 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5303 (match_operand:DI 2 "immediate_operand" "")))
5304 (clobber (reg:SI T_REG))])]
5309 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5311 operands[2] = GEN_INT (-INTVAL (operands[2]));
5312 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5315 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
5318 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5322 (define_insn_and_split "lshrdi3_k"
5323 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5324 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5326 (clobber (reg:SI T_REG))]
5329 "&& reload_completed"
5332 rtx high = gen_highpart (SImode, operands[0]);
5333 rtx low = gen_lowpart (SImode, operands[0]);
5334 emit_insn (gen_shlr (high, high));
5335 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5339 (define_insn "lshrdi3_media"
5340 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5341 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5342 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5344 && (arith_reg_dest (operands[0], DImode)
5345 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
5349 [(set_attr "type" "arith_media")])
5351 (define_insn "*lshrdisi3_media"
5352 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5353 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5354 (match_operand:DI 2 "const_int_operand" "n")))]
5355 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5356 "shlri.l %1, %2, %0"
5357 [(set_attr "type" "arith_media")
5358 (set_attr "highpart" "ignore")])
5360 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5361 ;; Combined left/right shifts
5364 [(set (match_operand:SI 0 "register_operand" "")
5365 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5366 (match_operand:SI 2 "const_int_operand" ""))
5367 (match_operand:SI 3 "const_int_operand" "")))]
5368 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5369 [(use (reg:SI R0_REG))]
5371 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5377 [(set (match_operand:SI 0 "register_operand" "")
5378 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5379 (match_operand:SI 2 "const_int_operand" ""))
5380 (match_operand:SI 3 "const_int_operand" "")))
5381 (clobber (reg:SI T_REG))]
5382 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5383 [(use (reg:SI R0_REG))]
5385 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5391 [(set (match_operand:SI 0 "register_operand" "=r")
5392 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5393 (match_operand:SI 2 "const_int_operand" "n"))
5394 (match_operand:SI 3 "const_int_operand" "n")))
5395 (clobber (reg:SI T_REG))]
5396 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
5398 [(set (attr "length")
5399 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5401 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5403 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5405 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
5407 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
5409 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
5411 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
5412 (const_string "16")]
5413 (const_string "18")))
5414 (set_attr "type" "arith")])
5417 [(set (match_operand:SI 0 "register_operand" "=z")
5418 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5419 (match_operand:SI 2 "const_int_operand" "n"))
5420 (match_operand:SI 3 "const_int_operand" "n")))
5421 (clobber (reg:SI T_REG))]
5422 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
5424 [(set (attr "length")
5425 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5427 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5429 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5431 (const_string "10")))
5432 (set_attr "type" "arith")])
5434 ;; shift left / and combination with a scratch register: The combine pass
5435 ;; does not accept the individual instructions, even though they are
5436 ;; cheap. But it needs a precise description so that it is usable after
5438 (define_insn "and_shl_scratch"
5439 [(set (match_operand:SI 0 "register_operand" "=r,&r")
5443 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5444 (match_operand:SI 2 "const_int_operand" "N,n"))
5445 (match_operand:SI 3 "" "0,r"))
5446 (match_operand:SI 4 "const_int_operand" "n,n"))
5447 (match_operand:SI 5 "const_int_operand" "n,n")))
5448 (clobber (reg:SI T_REG))]
5451 [(set (attr "length")
5452 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5454 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5456 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5458 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5459 (const_string "10")]
5460 (const_string "12")))
5461 (set_attr "type" "arith")])
5464 [(set (match_operand:SI 0 "register_operand" "")
5468 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5469 (match_operand:SI 2 "const_int_operand" ""))
5470 (match_operand:SI 3 "register_operand" ""))
5471 (match_operand:SI 4 "const_int_operand" ""))
5472 (match_operand:SI 5 "const_int_operand" "")))
5473 (clobber (reg:SI T_REG))]
5475 [(use (reg:SI R0_REG))]
5477 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5479 if (INTVAL (operands[2]))
5481 gen_shifty_op (LSHIFTRT, operands);
5483 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5484 operands[2] = operands[4];
5485 gen_shifty_op (ASHIFT, operands);
5486 if (INTVAL (operands[5]))
5488 operands[2] = operands[5];
5489 gen_shifty_op (LSHIFTRT, operands);
5494 ;; signed left/right shift combination.
5496 [(set (match_operand:SI 0 "register_operand" "")
5498 (ashift:SI (match_operand:SI 1 "register_operand" "")
5499 (match_operand:SI 2 "const_int_operand" ""))
5500 (match_operand:SI 3 "const_int_operand" "")
5502 (clobber (reg:SI T_REG))]
5504 [(use (reg:SI R0_REG))]
5506 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5511 (define_insn "shl_sext_ext"
5512 [(set (match_operand:SI 0 "register_operand" "=r")
5514 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5515 (match_operand:SI 2 "const_int_operand" "n"))
5516 (match_operand:SI 3 "const_int_operand" "n")
5518 (clobber (reg:SI T_REG))]
5519 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5521 [(set (attr "length")
5522 (cond [(match_test "shl_sext_length (insn)")
5524 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5526 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5528 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5530 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5532 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5534 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5536 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5537 (const_string "16")]
5538 (const_string "18")))
5539 (set_attr "type" "arith")])
5541 (define_insn "shl_sext_sub"
5542 [(set (match_operand:SI 0 "register_operand" "=z")
5544 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5545 (match_operand:SI 2 "const_int_operand" "n"))
5546 (match_operand:SI 3 "const_int_operand" "n")
5548 (clobber (reg:SI T_REG))]
5549 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5551 [(set (attr "length")
5552 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5554 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5556 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5558 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5559 (const_string "12")]
5560 (const_string "14")))
5561 (set_attr "type" "arith")])
5563 ;; The xtrct_left and xtrct_right patterns are used in expansions of DImode
5564 ;; shifts by 16, and allow the xtrct instruction to be generated from C
5566 (define_insn "xtrct_left"
5567 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5568 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5570 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5574 [(set_attr "type" "arith")])
5576 (define_insn "xtrct_right"
5577 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5578 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5580 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5584 [(set_attr "type" "arith")])
5586 ;; -------------------------------------------------------------------------
5588 ;; -------------------------------------------------------------------------
5591 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5592 (neg:SI (plus:SI (reg:SI T_REG)
5593 (match_operand:SI 1 "arith_reg_operand" "r"))))
5595 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5599 [(set_attr "type" "arith")])
5601 ;; A simplified version of the negc insn, where the exact value of the
5602 ;; T bit doesn't matter. This is easier for combine to pick up.
5603 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5604 ;; extra patterns for this case.
5605 (define_insn "*negc"
5606 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5607 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5608 (match_operand:SI 2 "t_reg_operand" "")))
5609 (clobber (reg:SI T_REG))]
5612 [(set_attr "type" "arith")])
5614 (define_insn "*negdi_media"
5615 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5616 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5619 [(set_attr "type" "arith_media")])
5621 ;; Don't split into individual negc insns immediately so that neg:DI (abs:DI)
5623 (define_expand "negdi2"
5624 [(parallel [(set (match_operand:DI 0 "arith_reg_dest")
5625 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5626 (clobber (reg:SI T_REG))])]
5629 (define_insn_and_split "*negdi2"
5630 [(set (match_operand:DI 0 "arith_reg_dest")
5631 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5632 (clobber (reg:SI T_REG))]
5635 "&& can_create_pseudo_p ()"
5638 emit_insn (gen_clrt ());
5639 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5640 gen_lowpart (SImode, operands[1])));
5641 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5642 gen_highpart (SImode, operands[1])));
5646 (define_insn "negsi2"
5647 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5648 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5651 [(set_attr "type" "arith")])
5653 (define_insn_and_split "one_cmplsi2"
5654 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5655 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5658 "&& can_create_pseudo_p ()"
5659 [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
5660 (set (match_dup 0) (reg:SI T_REG))]
5663 If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
5666 (set (reg0) (not:SI (reg0) (reg1)))
5667 (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
5668 (clobber (reg:SI T_REG))])
5670 ... match and combine the sequence manually in the split pass after the
5671 combine pass. Notice that combine does try the target pattern of this
5672 split, but if the pattern is added it interferes with other patterns, in
5673 particular with the div0s comparisons.
5674 This could also be done with a peephole but doing it here before register
5675 allocation can save one temporary.
5676 When we're here, the not:SI pattern obviously has been matched already
5677 and we only have to see whether the following insn is the left shift. */
5679 rtx i = next_nonnote_insn_bb (curr_insn);
5680 if (i == NULL_RTX || !NONJUMP_INSN_P (i))
5683 rtx p = PATTERN (i);
5684 if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
5687 rtx p0 = XVECEXP (p, 0, 0);
5688 rtx p1 = XVECEXP (p, 0, 1);
5690 if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
5691 GET_CODE (p0) == SET
5692 && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
5693 && REG_P (XEXP (XEXP (p0, 1), 0))
5694 && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
5695 && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
5696 && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
5698 /* (clobber (reg:SI T_REG)) */
5699 && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
5700 && REGNO (XEXP (p1, 0)) == T_REG)
5702 operands[0] = XEXP (p0, 0);
5703 set_insn_deleted (i);
5708 [(set_attr "type" "arith")])
5710 (define_expand "one_cmpldi2"
5711 [(set (match_operand:DI 0 "arith_reg_dest" "")
5712 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
5714 "TARGET_SHMEDIA" "")
5716 (define_expand "abs<mode>2"
5717 [(parallel [(set (match_operand:SIDI 0 "arith_reg_dest")
5718 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5719 (clobber (reg:SI T_REG))])]
5722 (define_insn_and_split "*abs<mode>2"
5723 [(set (match_operand:SIDI 0 "arith_reg_dest")
5724 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5725 (clobber (reg:SI T_REG))]
5728 "&& can_create_pseudo_p ()"
5731 if (<MODE>mode == SImode)
5732 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5735 rtx high_src = gen_highpart (SImode, operands[1]);
5736 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5739 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5744 (define_insn_and_split "*negabs<mode>2"
5745 [(set (match_operand:SIDI 0 "arith_reg_dest")
5746 (neg:SIDI (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand"))))
5747 (clobber (reg:SI T_REG))]
5750 "&& can_create_pseudo_p ()"
5753 if (<MODE>mode == SImode)
5754 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5757 rtx high_src = gen_highpart (SImode, operands[1]);
5758 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5761 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5766 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
5767 ;; This can be used as some kind of conditional execution, which is useful
5769 ;; Actually the instruction scheduling should decide whether to use a
5770 ;; zero-offset branch or not for any generic case involving a single
5771 ;; instruction on SH4 202.
5772 (define_insn_and_split "negsi_cond"
5773 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5775 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand" "M,N"))
5776 (match_operand:SI 1 "arith_reg_operand" "0,0")
5777 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
5778 "TARGET_SH1 && TARGET_ZDCBRANCH"
5780 static const char* alt[] =
5790 return alt[which_alternative];
5792 "TARGET_SH1 && ! TARGET_ZDCBRANCH"
5795 rtx skip_neg_label = gen_label_rtx ();
5797 emit_move_insn (operands[0], operands[1]);
5799 emit_jump_insn (INTVAL (operands[3])
5800 ? gen_branch_true (skip_neg_label)
5801 : gen_branch_false (skip_neg_label));
5803 emit_label_after (skip_neg_label,
5804 emit_insn (gen_negsi2 (operands[0], operands[1])));
5807 [(set_attr "type" "arith") ;; poor approximation
5808 (set_attr "length" "4")])
5810 (define_insn_and_split "negdi_cond"
5811 [(set (match_operand:DI 0 "arith_reg_dest")
5813 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand"))
5814 (match_operand:DI 1 "arith_reg_operand")
5815 (neg:DI (match_operand:DI 2 "arith_reg_operand"))))
5816 (clobber (reg:SI T_REG))]
5819 "&& can_create_pseudo_p ()"
5822 rtx skip_neg_label = gen_label_rtx ();
5824 emit_move_insn (operands[0], operands[1]);
5826 emit_jump_insn (INTVAL (operands[3])
5827 ? gen_branch_true (skip_neg_label)
5828 : gen_branch_false (skip_neg_label));
5830 if (!INTVAL (operands[3]))
5831 emit_insn (gen_clrt ());
5833 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5834 gen_lowpart (SImode, operands[1])));
5835 emit_label_after (skip_neg_label,
5836 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5837 gen_highpart (SImode, operands[1]))));
5841 (define_expand "bswapsi2"
5842 [(set (match_operand:SI 0 "arith_reg_dest" "")
5843 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
5846 if (! can_create_pseudo_p ())
5850 rtx tmp0 = gen_reg_rtx (SImode);
5851 rtx tmp1 = gen_reg_rtx (SImode);
5853 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
5854 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
5855 emit_insn (gen_swapbsi2 (operands[0], tmp1));
5860 (define_insn "swapbsi2"
5861 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5862 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
5863 (const_int 4294901760))
5864 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5866 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5867 (const_int 255)))))]
5870 [(set_attr "type" "arith")])
5872 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
5873 ;; partial byte swap expressions such as...
5874 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
5875 ;; ...which are currently not handled by the tree optimizers.
5876 ;; The combine pass will not initially try to combine the full expression,
5877 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
5878 ;; pattern acts as an intermediate pattern that will eventually lead combine
5879 ;; to the swapbsi2 pattern above.
5880 ;; As a side effect this also improves code that does (x & 0xFF) << 8
5881 ;; or (x << 8) & 0xFF00.
5882 (define_insn_and_split "*swapbisi2_and_shl8"
5883 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5884 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5887 (match_operand:SI 2 "arith_reg_operand" "r")))]
5888 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5890 "&& can_create_pseudo_p ()"
5893 rtx tmp0 = gen_reg_rtx (SImode);
5894 rtx tmp1 = gen_reg_rtx (SImode);
5896 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
5897 emit_insn (gen_swapbsi2 (tmp1, tmp0));
5898 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
5902 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
5903 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
5904 (define_insn_and_split "*swapbhisi2"
5905 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5906 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5909 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
5910 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5912 "&& can_create_pseudo_p ()"
5915 rtx tmp = gen_reg_rtx (SImode);
5917 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
5918 emit_insn (gen_swapbsi2 (operands[0], tmp));
5922 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
5926 ;; which can be simplified to...
5929 [(set (match_operand:SI 0 "arith_reg_dest" "")
5930 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5931 (const_int 4294901760))
5932 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5934 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5936 (set (match_operand:SI 2 "arith_reg_dest" "")
5938 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
5940 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5941 (const_int 4294901760))
5942 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5944 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5945 (const_int 255)))))])
5947 ;; -------------------------------------------------------------------------
5948 ;; Zero extension instructions
5949 ;; -------------------------------------------------------------------------
5951 (define_insn "zero_extendsidi2"
5952 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5953 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
5955 "addz.l %1, r63, %0"
5956 [(set_attr "type" "arith_media")
5957 (set_attr "highpart" "extend")])
5959 (define_insn "zero_extendhidi2"
5960 [(set (match_operand:DI 0 "register_operand" "=r,r")
5961 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5966 [(set_attr "type" "*,load_media")
5967 (set (attr "highpart")
5968 (cond [(match_test "sh_contains_memref_p (insn)")
5969 (const_string "user")]
5970 (const_string "ignore")))])
5973 [(set (match_operand:DI 0 "register_operand" "")
5974 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5975 "TARGET_SHMEDIA && reload_completed"
5976 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5977 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
5979 if (GET_CODE (operands[1]) == TRUNCATE)
5980 operands[1] = XEXP (operands[1], 0);
5983 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
5984 ;; reload the entire truncate expression.
5985 (define_insn_and_split "*loaddi_trunc"
5986 [(set (match_operand 0 "any_register_operand" "=r")
5987 (truncate (match_operand:DI 1 "memory_operand" "m")))]
5988 "TARGET_SHMEDIA && reload_completed"
5990 "TARGET_SHMEDIA && reload_completed"
5991 [(set (match_dup 0) (match_dup 1))]
5993 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5996 (define_insn "zero_extendqidi2"
5997 [(set (match_operand:DI 0 "register_operand" "=r,r")
5998 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6003 [(set_attr "type" "arith_media,load_media")
6004 (set (attr "highpart")
6005 (cond [(match_test "sh_contains_memref_p (insn)")
6006 (const_string "user")]
6007 (const_string "ignore")))])
6009 (define_expand "zero_extend<mode>si2"
6010 [(set (match_operand:SI 0 "arith_reg_dest")
6011 (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
6013 (define_insn_and_split "*zero_extend<mode>si2_compact"
6014 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6015 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6018 "&& can_create_pseudo_p ()"
6019 [(set (match_dup 0) (match_dup 2))]
6021 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6022 reg with a following zero extension. In the split pass after combine,
6023 try to figure out how the extended reg was set. If it originated from
6024 the T bit we can replace the zero extension with a reg move, which will
6025 be eliminated. Notice that this also helps the *cbranch_t splitter when
6026 it tries to post-combine tests and conditional branches, as it does not
6027 check for zero extensions. */
6028 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6029 if (operands[2] == NULL_RTX)
6032 [(set_attr "type" "arith")])
6034 (define_insn "*zero_extendhisi2_media"
6035 [(set (match_operand:SI 0 "register_operand" "=r,r")
6036 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6041 [(set_attr "type" "arith_media,load_media")
6042 (set (attr "highpart")
6043 (cond [(match_test "sh_contains_memref_p (insn)")
6044 (const_string "user")]
6045 (const_string "ignore")))])
6048 [(set (match_operand:SI 0 "register_operand" "")
6049 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6050 "TARGET_SHMEDIA && reload_completed"
6051 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6052 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
6054 rtx op1 = operands[1];
6056 if (GET_CODE (op1) == TRUNCATE)
6057 op1 = XEXP (op1, 0);
6059 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6060 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6063 (define_insn "*zero_extendqisi2_media"
6064 [(set (match_operand:SI 0 "register_operand" "=r,r")
6065 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6070 [(set_attr "type" "arith_media,load_media")
6071 (set (attr "highpart")
6072 (cond [(match_test "sh_contains_memref_p (insn)")
6073 (const_string "user")]
6074 (const_string "ignore")))])
6076 (define_insn "zero_extendqihi2"
6077 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6078 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6081 [(set_attr "type" "arith")])
6083 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
6084 ;; They could also be used for simple memory addresses like @Rn by setting
6085 ;; the displacement value to zero. However, doing so too early results in
6086 ;; missed opportunities for other optimizations such as post-inc or index
6087 ;; addressing loads.
6088 ;; Although the 'zero_extend_movu_operand' predicate does not allow simple
6089 ;; register addresses (an address without a displacement, index, post-inc),
6090 ;; zero-displacement addresses might be generated during reload, wich are
6091 ;; simplified to simple register addresses in turn. Thus, we have to
6092 ;; provide the Sdd and Sra alternatives in the patterns.
6093 (define_insn "*zero_extend<mode>si2_disp_mem"
6094 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
6096 (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
6100 movu.<bw> @(0,%t1),%0"
6101 [(set_attr "type" "load")
6102 (set_attr "length" "4")])
6104 ;; Convert the zero extending loads in sequences such as:
6105 ;; movu.b @(1,r5),r0 movu.w @(2,r5),r0
6106 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6108 ;; back to sign extending loads like:
6109 ;; mov.b @(1,r5),r0 mov.w @(2,r5),r0
6110 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6112 ;; if the extension type is irrelevant. The sign extending mov.{b|w} insn
6113 ;; is only 2 bytes in size if the displacement is {K04|K05}.
6114 ;; If the displacement is greater it doesn't matter, so we convert anyways.
6116 [(set (match_operand:SI 0 "arith_reg_dest" "")
6117 (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
6118 (set (match_operand 2 "nonimmediate_operand" "")
6119 (match_operand 3 "arith_reg_operand" ""))]
6121 && REGNO (operands[0]) == REGNO (operands[3])
6122 && peep2_reg_dead_p (2, operands[0])
6123 && GET_MODE_SIZE (GET_MODE (operands[2]))
6124 <= GET_MODE_SIZE (GET_MODE (operands[1]))"
6125 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
6126 (set (match_dup 2) (match_dup 3))])
6128 ;; Fold sequences such as
6132 ;; movu.b @(0,r3),r7
6133 ;; This does not reduce the code size but the number of instructions is
6134 ;; halved, which results in faster code.
6136 [(set (match_operand:SI 0 "arith_reg_dest" "")
6137 (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
6138 (set (match_operand:SI 2 "arith_reg_dest" "")
6139 (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
6141 && GET_MODE (operands[1]) == GET_MODE (operands[3])
6142 && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
6143 && REGNO (operands[0]) == REGNO (operands[3])
6144 && (REGNO (operands[2]) == REGNO (operands[0])
6145 || peep2_reg_dead_p (2, operands[0]))"
6146 [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
6149 = replace_equiv_address (operands[1],
6150 gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
6154 ;; -------------------------------------------------------------------------
6155 ;; Sign extension instructions
6156 ;; -------------------------------------------------------------------------
6158 ;; ??? This should be a define expand.
6159 ;; ??? Or perhaps it should be dropped?
6161 ;; convert_move generates good code for SH[1-4].
6162 (define_insn "extendsidi2"
6163 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6164 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
6170 [(set_attr "type" "arith_media,load_media,fpconv_media")
6171 (set (attr "highpart")
6172 (cond [(match_test "sh_contains_memref_p (insn)")
6173 (const_string "user")]
6174 (const_string "extend")))])
6176 (define_insn "extendhidi2"
6177 [(set (match_operand:DI 0 "register_operand" "=r,r")
6178 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6183 [(set_attr "type" "*,load_media")
6184 (set (attr "highpart")
6185 (cond [(match_test "sh_contains_memref_p (insn)")
6186 (const_string "user")]
6187 (const_string "ignore")))])
6190 [(set (match_operand:DI 0 "register_operand" "")
6191 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
6192 "TARGET_SHMEDIA && reload_completed"
6193 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
6194 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6196 if (GET_CODE (operands[1]) == TRUNCATE)
6197 operands[1] = XEXP (operands[1], 0);
6200 (define_insn "extendqidi2"
6201 [(set (match_operand:DI 0 "register_operand" "=r,r")
6202 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6207 [(set_attr "type" "*,load_media")
6208 (set (attr "highpart")
6209 (cond [(match_test "sh_contains_memref_p (insn)")
6210 (const_string "user")]
6211 (const_string "ignore")))])
6214 [(set (match_operand:DI 0 "register_operand" "")
6215 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
6216 "TARGET_SHMEDIA && reload_completed"
6217 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
6218 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6220 if (GET_CODE (operands[1]) == TRUNCATE)
6221 operands[1] = XEXP (operands[1], 0);
6224 (define_expand "extend<mode>si2"
6225 [(set (match_operand:SI 0 "arith_reg_dest")
6226 (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
6228 (define_insn "*extendhisi2_media"
6229 [(set (match_operand:SI 0 "register_operand" "=r,r")
6230 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6235 [(set_attr "type" "arith_media,load_media")
6236 (set (attr "highpart")
6237 (cond [(match_test "sh_contains_memref_p (insn)")
6238 (const_string "user")]
6239 (const_string "ignore")))])
6242 [(set (match_operand:SI 0 "register_operand" "")
6243 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6244 "TARGET_SHMEDIA && reload_completed"
6245 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6246 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
6248 rtx op1 = operands[1];
6249 if (GET_CODE (op1) == TRUNCATE)
6250 op1 = XEXP (op1, 0);
6252 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6253 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6256 (define_insn_and_split "*extend<mode>si2_compact_reg"
6257 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6258 (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6261 "&& can_create_pseudo_p ()"
6262 [(set (match_dup 0) (match_dup 2))]
6264 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6265 reg with a following sign extension. In the split pass after combine,
6266 try to figure the extended reg was set. If it originated from the T
6267 bit we can replace the sign extension with a reg move, which will be
6269 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6270 if (operands[2] == NULL_RTX)
6273 [(set_attr "type" "arith")])
6275 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
6277 (define_insn "*extend<mode>si2_compact_mem_disp"
6278 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
6282 (match_operand:SI 1 "arith_reg_operand" "%r,r")
6283 (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
6284 "TARGET_SH1 && ! TARGET_SH2A
6285 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6287 mov.<bw> @(%O2,%1),%0
6289 [(set_attr "type" "load")])
6291 (define_insn "*extend<mode>si2_compact_mem_disp"
6292 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
6296 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6297 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
6298 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6300 mov.<bw> @(%O2,%1),%0
6302 mov.<bw> @(%O2,%1),%0"
6303 [(set_attr "type" "load")
6304 (set_attr "length" "2,2,4")])
6306 ;; The *_snd patterns will take care of other QImode/HImode addressing
6307 ;; modes than displacement addressing. They must be defined _after_ the
6308 ;; displacement addressing patterns. Otherwise the displacement addressing
6309 ;; patterns will not be picked.
6310 (define_insn "*extend<mode>si2_compact_snd"
6311 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6313 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
6316 [(set_attr "type" "load")])
6318 (define_insn "*extendqisi2_media"
6319 [(set (match_operand:SI 0 "register_operand" "=r,r")
6320 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6325 [(set_attr "type" "arith_media,load_media")
6326 (set (attr "highpart")
6327 (cond [(match_test "sh_contains_memref_p (insn)")
6328 (const_string "user")]
6329 (const_string "ignore")))])
6332 [(set (match_operand:SI 0 "register_operand" "")
6333 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
6334 "TARGET_SHMEDIA && reload_completed"
6335 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
6336 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
6338 rtx op1 = operands[1];
6339 if (GET_CODE (op1) == TRUNCATE)
6340 op1 = XEXP (op1, 0);
6342 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6343 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6346 (define_expand "extendqihi2"
6347 [(set (match_operand:HI 0 "arith_reg_dest")
6348 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand")))]
6351 (define_insn "*extendqihi2_compact_reg"
6352 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6353 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6356 [(set_attr "type" "arith")])
6358 ;; It would seem useful to combine the truncXi patterns into the movXi
6359 ;; patterns, but unary operators are ignored when matching constraints,
6360 ;; so we need separate patterns.
6361 (define_insn "truncdisi2"
6362 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
6363 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
6372 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,
6373 fpconv_media,fmove_media")
6374 (set (attr "highpart")
6375 (cond [(match_test "sh_contains_memref_p (insn)")
6376 (const_string "user")]
6377 (const_string "extend")))])
6379 (define_insn "truncdihi2"
6380 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
6381 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
6384 static const char* alt[] =
6386 "shlli %1,48,%0" "\n"
6391 return alt[which_alternative];
6393 [(set_attr "type" "arith_media,store_media")
6394 (set_attr "length" "8,4")
6395 (set (attr "highpart")
6396 (cond [(match_test "sh_contains_memref_p (insn)")
6397 (const_string "user")]
6398 (const_string "extend")))])
6400 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
6401 ; Because we use zero extension, we can't provide signed QImode compares
6402 ; using a simple compare or conditional branch insn.
6403 (define_insn "truncdiqi2"
6404 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
6405 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
6410 [(set_attr "type" "arith_media,store")
6411 (set (attr "highpart")
6412 (cond [(match_test "sh_contains_memref_p (insn)")
6413 (const_string "user")]
6414 (const_string "extend")))])
6416 ;; -------------------------------------------------------------------------
6417 ;; Move instructions
6418 ;; -------------------------------------------------------------------------
6420 ;; define push and pop so it is easy for sh.c
6421 ;; We can't use push and pop on SHcompact because the stack must always
6422 ;; be 8-byte aligned.
6423 (define_expand "push"
6424 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6425 (match_operand:SI 0 "register_operand" "r,l,x"))]
6426 "TARGET_SH1 && ! TARGET_SH5"
6429 (define_expand "pop"
6430 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6431 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6432 "TARGET_SH1 && ! TARGET_SH5"
6435 (define_expand "push_e"
6436 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6437 (match_operand:SF 0 "" ""))
6438 (use (reg:SI FPSCR_MODES_REG))
6439 (clobber (scratch:SI))])]
6440 "TARGET_SH1 && ! TARGET_SH5"
6443 (define_insn "push_fpul"
6444 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6445 "TARGET_SH2E && ! TARGET_SH5"
6447 [(set_attr "type" "fstore")
6448 (set_attr "late_fp_use" "yes")
6449 (set_attr "hit_stack" "yes")])
6451 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6453 (define_expand "push_4"
6454 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6455 (match_operand:DF 0 "" ""))
6456 (use (reg:SI FPSCR_MODES_REG))
6457 (clobber (scratch:SI))])]
6458 "TARGET_SH1 && ! TARGET_SH5"
6461 (define_expand "pop_e"
6462 [(parallel [(set (match_operand:SF 0 "" "")
6463 (mem:SF (post_inc:SI (reg:SI SP_REG))))
6464 (use (reg:SI FPSCR_MODES_REG))
6465 (clobber (scratch:SI))])]
6466 "TARGET_SH1 && ! TARGET_SH5"
6469 (define_insn "pop_fpul"
6470 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6471 "TARGET_SH2E && ! TARGET_SH5"
6473 [(set_attr "type" "load")
6474 (set_attr "hit_stack" "yes")])
6476 (define_expand "pop_4"
6477 [(parallel [(set (match_operand:DF 0 "" "")
6478 (mem:DF (post_inc:SI (reg:SI SP_REG))))
6479 (use (reg:SI FPSCR_MODES_REG))
6480 (clobber (scratch:SI))])]
6481 "TARGET_SH1 && ! TARGET_SH5"
6484 (define_expand "push_fpscr"
6491 gen_frame_mem (SImode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)))),
6492 REG_INC, stack_pointer_rtx);
6496 (define_expand "pop_fpscr"
6503 gen_frame_mem (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx)))),
6504 REG_INC, stack_pointer_rtx);
6508 ;; The clrt and sett patterns can happen as the result of optimization and
6510 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6511 ;; In this case they might not disappear completely, because the T reg is
6512 ;; a fixed hard reg.
6513 ;; When DImode operations that use the T reg as carry/borrow are split into
6514 ;; individual SImode operations, the T reg is usually cleared before the
6515 ;; first SImode insn.
6517 [(set (reg:SI T_REG) (const_int 0))]
6520 [(set_attr "type" "mt_group")])
6523 [(set (reg:SI T_REG) (const_int 1))]
6526 [(set_attr "type" "mt_group")])
6528 ;; Use the combine pass to transform sequences such as
6532 ;; mov.l @(r0,r4),r0
6538 ;; See also PR 39423.
6539 ;; Notice that these patterns have a T_REG clobber, because the shift
6540 ;; sequence that will be split out might clobber the T_REG. Ideally, the
6541 ;; clobber would be added conditionally, depending on the result of
6542 ;; sh_ashlsi_clobbers_t_reg_p. When splitting out the shifts we must go
6543 ;; through the ashlsi3 expander in order to get the right shift insn --
6544 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6545 ;; FIXME: Combine never tries this kind of patterns for DImode.
6546 (define_insn_and_split "*movsi_index_disp_load"
6547 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6548 (match_operand:SI 1 "mem_index_disp_operand" "m"))
6549 (clobber (reg:SI T_REG))]
6552 "&& can_create_pseudo_p ()"
6553 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6554 (set (match_dup 0) (match_dup 7))]
6556 rtx mem = operands[1];
6557 rtx plus0_rtx = XEXP (mem, 0);
6558 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6559 rtx mult_rtx = XEXP (plus1_rtx, 0);
6561 operands[1] = XEXP (mult_rtx, 0);
6562 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6563 operands[3] = XEXP (plus1_rtx, 1);
6564 operands[4] = XEXP (plus0_rtx, 1);
6565 operands[5] = gen_reg_rtx (SImode);
6566 operands[6] = gen_reg_rtx (SImode);
6568 replace_equiv_address (mem,
6569 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6571 emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6574 (define_insn_and_split "*movhi_index_disp_load"
6575 [(set (match_operand:SI 0 "arith_reg_dest")
6576 (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6577 (clobber (reg:SI T_REG))]
6580 "&& can_create_pseudo_p ()"
6583 rtx mem = operands[1];
6584 rtx plus0_rtx = XEXP (mem, 0);
6585 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6586 rtx mult_rtx = XEXP (plus1_rtx, 0);
6588 rtx op_1 = XEXP (mult_rtx, 0);
6589 rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6590 rtx op_3 = XEXP (plus1_rtx, 1);
6591 rtx op_4 = XEXP (plus0_rtx, 1);
6592 rtx op_5 = gen_reg_rtx (SImode);
6593 rtx op_6 = gen_reg_rtx (SImode);
6594 rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6596 emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6597 emit_insn (gen_addsi3 (op_6, op_5, op_3));
6599 if (<CODE> == SIGN_EXTEND)
6601 emit_insn (gen_extendhisi2 (operands[0], op_7));
6604 else if (<CODE> == ZERO_EXTEND)
6606 /* On SH2A the movu.w insn can be used for zero extending loads. */
6608 emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
6611 emit_insn (gen_extendhisi2 (operands[0], op_7));
6612 emit_insn (gen_zero_extendhisi2 (operands[0],
6613 gen_lowpart (HImode, operands[0])));
6621 (define_insn_and_split "*mov<mode>_index_disp_store"
6622 [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
6623 (match_operand:HISI 1 "arith_reg_operand" "r"))
6624 (clobber (reg:SI T_REG))]
6627 "&& can_create_pseudo_p ()"
6628 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6629 (set (match_dup 7) (match_dup 1))]
6631 rtx mem = operands[0];
6632 rtx plus0_rtx = XEXP (mem, 0);
6633 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6634 rtx mult_rtx = XEXP (plus1_rtx, 0);
6636 operands[0] = XEXP (mult_rtx, 0);
6637 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6638 operands[3] = XEXP (plus1_rtx, 1);
6639 operands[4] = XEXP (plus0_rtx, 1);
6640 operands[5] = gen_reg_rtx (SImode);
6641 operands[6] = gen_reg_rtx (SImode);
6643 replace_equiv_address (mem,
6644 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6646 emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
6649 ;; t/r must come after r/r, lest reload will try to reload stuff like
6650 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
6651 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
6652 (define_insn "movsi_i"
6653 [(set (match_operand:SI 0 "general_movdst_operand"
6654 "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
6655 (match_operand:SI 1 "general_movsrc_operand"
6656 "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
6660 && (register_operand (operands[0], SImode)
6661 || register_operand (operands[1], SImode))"
6677 [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,
6678 pstore,gp_mac,prset,mem_mac,pload,pcload_si")
6679 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
6681 ;; t/r must come after r/r, lest reload will try to reload stuff like
6682 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
6683 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
6684 ;; will require a reload.
6685 ;; ??? We can't include f/f because we need the proper FPSCR setting when
6686 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
6687 (define_insn "movsi_ie"
6688 [(set (match_operand:SI 0 "general_movdst_operand"
6689 "=r,r,r,r,r,r,r,r,mr,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
6690 (match_operand:SI 1 "general_movsrc_operand"
6691 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
6692 "(TARGET_SH2E || TARGET_SH2A)
6693 && ((register_operand (operands[0], SImode)
6694 && !fpscr_operand (operands[0], SImode))
6695 || (register_operand (operands[1], SImode)
6696 && !fpscr_operand (operands[1], SImode)))"
6721 ! move optimized away"
6722 [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,
6723 mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,
6724 pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
6725 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
6726 (set_attr_alternative "length"
6733 (match_test "TARGET_SH2A")
6734 (const_int 4) (const_int 2))
6738 (match_test "TARGET_SH2A")
6739 (const_int 4) (const_int 2))
6756 (define_insn "movsi_i_lowpart"
6757 [(set (strict_low_part
6758 (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
6759 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
6761 && (register_operand (operands[0], SImode)
6762 || register_operand (operands[1], SImode))"
6772 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
6774 (define_insn_and_split "load_ra"
6775 [(set (match_operand:SI 0 "general_movdst_operand" "")
6776 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
6779 "&& ! currently_expanding_to_rtl"
6780 [(set (match_dup 0) (match_dup 1))]
6782 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
6783 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
6786 ;; The '?'s in the following constraints may not reflect the time taken
6787 ;; to perform the move. They are there to discourage the use of floating-
6788 ;; point registers for storing integer values.
6789 (define_insn "*movsi_media"
6790 [(set (match_operand:SI 0 "general_movdst_operand"
6791 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
6792 (match_operand:SI 1 "general_movsrc_operand"
6793 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6795 && (register_operand (operands[0], SImode)
6796 || sh_register_operand (operands[1], SImode)
6797 || GET_CODE (operands[1]) == TRUNCATE)"
6812 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6813 fload_media,fstore_media,fload_media,fpconv_media,
6814 fmove_media,ptabs_media,gettr_media,pt_media")
6815 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
6816 (set (attr "highpart")
6817 (cond [(match_test "sh_contains_memref_p (insn)")
6818 (const_string "user")]
6819 (const_string "ignore")))])
6821 (define_insn "*movsi_media_nofpu"
6822 [(set (match_operand:SI 0 "general_movdst_operand"
6823 "=r,r,r,r,m,*b,r,*b")
6824 (match_operand:SI 1 "general_movsrc_operand"
6825 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
6827 && (register_operand (operands[0], SImode)
6828 || sh_register_operand (operands[1], SImode)
6829 || GET_CODE (operands[1]) == TRUNCATE)"
6839 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6840 ptabs_media,gettr_media,pt_media")
6841 (set_attr "length" "4,4,8,4,4,4,4,12")
6842 (set (attr "highpart")
6843 (cond [(match_test "sh_contains_memref_p (insn)")
6844 (const_string "user")]
6845 (const_string "ignore")))])
6847 (define_expand "movsi_const"
6848 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6849 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6850 (const_int 16)] UNSPEC_EXTRACT_S16)))
6852 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
6853 (const:SI (unspec:SI [(match_dup 1)
6854 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6855 "TARGET_SHMEDIA && reload_completed
6856 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6858 if (GET_CODE (operands[1]) == LABEL_REF
6859 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
6860 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
6861 else if (GOTOFF_P (operands[1]))
6863 rtx unspec = XEXP (operands[1], 0);
6865 if (! UNSPEC_GOTOFF_P (unspec))
6867 unspec = XEXP (unspec, 0);
6868 if (! UNSPEC_GOTOFF_P (unspec))
6871 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
6872 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
6873 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
6877 (define_expand "movsi_const_16bit"
6878 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6879 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6880 (const_int 0)] UNSPEC_EXTRACT_S16)))]
6881 "TARGET_SHMEDIA && flag_pic && reload_completed
6882 && GET_CODE (operands[1]) == SYMBOL_REF"
6886 [(set (match_operand:SI 0 "arith_reg_dest" "")
6887 (match_operand:SI 1 "immediate_operand" ""))]
6888 "TARGET_SHMEDIA && reload_completed
6889 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6892 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
6894 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6900 [(set (match_operand:SI 0 "register_operand" "")
6901 (match_operand:SI 1 "immediate_operand" ""))]
6902 "TARGET_SHMEDIA && reload_completed
6903 && ((CONST_INT_P (operands[1])
6904 && ! satisfies_constraint_I16 (operands[1]))
6905 || GET_CODE (operands[1]) == CONST_DOUBLE)"
6906 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6908 (define_expand "movsi"
6909 [(set (match_operand:SI 0 "general_movdst_operand" "")
6910 (match_operand:SI 1 "general_movsrc_operand" ""))]
6913 prepare_move_operands (operands, SImode);
6916 (define_expand "ic_invalidate_line"
6917 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
6918 (match_dup 1)] UNSPEC_ICACHE)
6919 (clobber (scratch:SI))])]
6920 "TARGET_HARD_SH4 || TARGET_SH5"
6924 emit_insn (gen_ic_invalidate_line_media (operands[0]));
6927 else if (TARGET_SHCOMPACT)
6929 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
6930 operands[1] = force_reg (Pmode, operands[1]);
6931 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
6934 else if (TARGET_SH4A || TARGET_SH4_300)
6936 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
6939 operands[0] = force_reg (Pmode, operands[0]);
6940 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
6944 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
6945 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
6946 ;; the requirement *1*00 for associative address writes. The alignment of
6947 ;; %0 implies that its least significant bit is cleared,
6948 ;; thus we clear the V bit of a matching entry if there is one.
6949 (define_insn "ic_invalidate_line_i"
6950 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
6951 (match_operand:SI 1 "register_operand" "r")]
6953 (clobber (match_scratch:SI 2 "=&r"))]
6956 return "ocbwb @%0" "\n"
6957 " extu.w %0,%2" "\n"
6961 [(set_attr "length" "8")
6962 (set_attr "type" "cwb")])
6964 (define_insn "ic_invalidate_line_sh4a"
6965 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6967 "TARGET_SH4A || TARGET_SH4_300"
6969 return "ocbwb @%0" "\n"
6973 [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
6974 (set_attr "type" "cwb")])
6976 ;; ??? could make arg 0 an offsettable memory operand to allow to save
6977 ;; an add in the code that calculates the address.
6978 (define_insn "ic_invalidate_line_media"
6979 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
6983 return "ocbwb %0,0" "\n"
6988 [(set_attr "length" "16")
6989 (set_attr "type" "invalidate_line_media")])
6991 (define_insn "ic_invalidate_line_compact"
6992 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6993 (match_operand:SI 1 "register_operand" "r")]
6995 (clobber (reg:SI PR_REG))]
6998 [(set_attr "type" "sfunc")
6999 (set_attr "needs_delay_slot" "yes")])
7001 (define_expand "initialize_trampoline"
7002 [(match_operand:SI 0 "" "")
7003 (match_operand:SI 1 "" "")
7004 (match_operand:SI 2 "" "")]
7009 tramp = force_reg (Pmode, operands[0]);
7010 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
7012 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
7013 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
7015 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
7019 (define_insn "initialize_trampoline_compact"
7020 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
7021 (match_operand:SI 1 "register_operand" "r")
7022 (reg:SI R2_REG) (reg:SI R3_REG)]
7025 (clobber (reg:SI PR_REG))]
7028 [(set_attr "type" "sfunc")
7029 (set_attr "needs_delay_slot" "yes")])
7031 (define_expand "mov<mode>"
7032 [(set (match_operand:QIHI 0 "general_movdst_operand")
7033 (match_operand:QIHI 1 "general_movsrc_operand"))]
7036 if (can_create_pseudo_p () && CONST_INT_P (operands[1])
7037 && REG_P (operands[0]) && REGNO (operands[0]) != R0_REG)
7039 rtx reg = gen_reg_rtx(SImode);
7040 emit_move_insn (reg, operands[1]);
7041 operands[1] = gen_lowpart (<MODE>mode, reg);
7044 prepare_move_operands (operands, <MODE>mode);
7047 ;; Specifying the displacement addressing load / store patterns separately
7048 ;; before the generic movqi / movhi pattern allows controlling the order
7049 ;; in which load / store insns are selected in a more fine grained way.
7050 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
7051 ;; "enabled" attribute as it is done in other targets.
7052 (define_insn "*mov<mode>_store_mem_disp04"
7054 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
7055 (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
7056 (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
7057 "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
7059 mov.<bw> %2,@(%O1,%0)
7061 [(set_attr "type" "store")])
7063 (define_insn "*mov<mode>_store_mem_disp12"
7065 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
7066 (match_operand:SI 1 "const_int_operand" "<disp12>")))
7067 (match_operand:QIHI 2 "arith_reg_operand" "r"))]
7068 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
7069 "mov.<bw> %2,@(%O1,%0)"
7070 [(set_attr "type" "store")
7071 (set_attr "length" "4")])
7073 (define_insn "*mov<mode>_load_mem_disp04"
7074 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
7076 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
7077 (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
7078 "TARGET_SH1 && ! TARGET_SH2A
7079 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
7081 mov.<bw> @(%O2,%1),%0
7083 [(set_attr "type" "load")])
7085 (define_insn "*mov<mode>_load_mem_disp12"
7086 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
7089 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
7090 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
7091 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
7093 mov.<bw> @(%O2,%1),%0
7095 mov.<bw> @(%O2,%1),%0"
7096 [(set_attr "type" "load")
7097 (set_attr "length" "2,2,4")])
7099 ;; The order of the constraint alternatives is important here.
7100 ;; Q/r has to come first, otherwise PC relative loads might wrongly get
7101 ;; placed into delay slots. Since there is no QImode PC relative load, the
7102 ;; Q constraint and general_movsrc_operand will reject it for QImode.
7103 ;; The Snd alternatives should come before Sdd in order to avoid a preference
7104 ;; of using r0 als the register operand for addressing modes other than
7105 ;; displacement addressing.
7106 ;; The Sdd alternatives allow only r0 as register operand, even though on
7107 ;; SH2A any register could be allowed by switching to a 32 bit insn.
7108 ;; Generally sticking to the r0 is preferrable, since it generates smaller
7109 ;; code. Obvious r0 reloads can then be eliminated with a peephole on SH2A.
7110 (define_insn "*mov<mode>"
7111 [(set (match_operand:QIHI 0 "general_movdst_operand"
7112 "=r,r,r,Snd,r, Sdd,z, r,l")
7113 (match_operand:QIHI 1 "general_movsrc_operand"
7114 "Q,r,i,r, Snd,z, Sdd,l,r"))]
7116 && (arith_reg_operand (operands[0], <MODE>mode)
7117 || arith_reg_operand (operands[1], <MODE>mode))"
7128 [(set_attr "type" "pcload,move,movi8,store,load,store,load,prget,prset")
7129 (set (attr "length")
7130 (cond [(and (match_operand 0 "displacement_mem_operand")
7131 (not (match_operand 0 "short_displacement_mem_operand")))
7133 (and (match_operand 1 "displacement_mem_operand")
7134 (not (match_operand 1 "short_displacement_mem_operand")))
7138 (define_insn "*movqi_media"
7139 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
7140 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
7142 && (arith_reg_operand (operands[0], QImode)
7143 || extend_reg_or_0_operand (operands[1], QImode))"
7149 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
7150 (set (attr "highpart")
7151 (cond [(match_test "sh_contains_memref_p (insn)")
7152 (const_string "user")]
7153 (const_string "ignore")))])
7155 (define_expand "reload_inqi"
7156 [(set (match_operand:SI 2 "" "=&r")
7157 (match_operand:QI 1 "inqhi_operand" ""))
7158 (set (match_operand:QI 0 "arith_reg_operand" "=r")
7159 (truncate:QI (match_dup 3)))]
7162 rtx inner = XEXP (operands[1], 0);
7163 int regno = REGNO (inner);
7165 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7166 operands[1] = gen_rtx_REG (SImode, regno);
7167 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7170 (define_insn "*movhi_media"
7171 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
7172 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
7174 && (arith_reg_operand (operands[0], HImode)
7175 || arith_reg_or_0_operand (operands[1], HImode))"
7182 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
7183 (set (attr "highpart")
7184 (cond [(match_test "sh_contains_memref_p (insn)")
7185 (const_string "user")]
7186 (const_string "ignore")))])
7189 [(set (match_operand:HI 0 "register_operand" "")
7190 (match_operand:HI 1 "immediate_operand" ""))]
7191 "TARGET_SHMEDIA && reload_completed
7192 && ! satisfies_constraint_I16 (operands[1])"
7193 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
7195 (define_expand "reload_inhi"
7196 [(set (match_operand:SI 2 "" "=&r")
7197 (match_operand:HI 1 "inqhi_operand" ""))
7198 (set (match_operand:HI 0 "arith_reg_operand" "=r")
7199 (truncate:HI (match_dup 3)))]
7202 rtx inner = XEXP (operands[1], 0);
7203 int regno = REGNO (inner);
7205 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7206 operands[1] = gen_rtx_REG (SImode, regno);
7207 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7210 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7211 ;; compiled with -m2 -ml -O3 -funroll-loops
7212 (define_insn "*movdi_i"
7213 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7214 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7216 && (arith_reg_operand (operands[0], DImode)
7217 || arith_reg_operand (operands[1], DImode))"
7219 return output_movedouble (insn, operands, DImode);
7221 [(set_attr "length" "4")
7222 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7224 ;; If the output is a register and the input is memory or a register, we have
7225 ;; to be careful and see which word needs to be loaded first.
7227 [(set (match_operand:DI 0 "general_movdst_operand" "")
7228 (match_operand:DI 1 "general_movsrc_operand" ""))]
7229 "TARGET_SH1 && reload_completed"
7230 [(set (match_dup 2) (match_dup 3))
7231 (set (match_dup 4) (match_dup 5))]
7235 if ((MEM_P (operands[0])
7236 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7237 || (MEM_P (operands[1])
7238 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7241 switch (GET_CODE (operands[0]))
7244 regno = REGNO (operands[0]);
7247 regno = subreg_regno (operands[0]);
7257 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7259 operands[2] = operand_subword (operands[0], 0, 0, DImode);
7260 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7261 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7262 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7266 operands[2] = operand_subword (operands[0], 1, 0, DImode);
7267 operands[3] = operand_subword (operands[1], 1, 0, DImode);
7268 operands[4] = operand_subword (operands[0], 0, 0, DImode);
7269 operands[5] = operand_subword (operands[1], 0, 0, DImode);
7272 if (operands[2] == 0 || operands[3] == 0
7273 || operands[4] == 0 || operands[5] == 0)
7277 ;; The '?'s in the following constraints may not reflect the time taken
7278 ;; to perform the move. They are there to discourage the use of floating-
7279 ;; point registers for storing integer values.
7280 (define_insn "*movdi_media"
7281 [(set (match_operand:DI 0 "general_movdst_operand"
7282 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7283 (match_operand:DI 1 "general_movsrc_operand"
7284 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7286 && (register_operand (operands[0], DImode)
7287 || sh_register_operand (operands[1], DImode))"
7302 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7303 fload_media,fstore_media,fload_media,dfpconv_media,
7304 fmove_media,ptabs_media,gettr_media,pt_media")
7305 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7307 (define_insn "*movdi_media_nofpu"
7308 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7309 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7311 && (register_operand (operands[0], DImode)
7312 || sh_register_operand (operands[1], DImode))"
7322 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7323 ptabs_media,gettr_media,pt_media")
7324 (set_attr "length" "4,4,16,4,4,4,4,*")])
7326 (define_insn "*movdi_media_I16"
7327 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7328 (match_operand:DI 1 "const_int_operand" "I16"))]
7329 "TARGET_SHMEDIA && reload_completed"
7331 [(set_attr "type" "arith_media")
7332 (set_attr "length" "4")])
7335 [(set (match_operand:DI 0 "arith_reg_dest" "")
7336 (match_operand:DI 1 "immediate_operand" ""))]
7337 "TARGET_SHMEDIA && reload_completed
7338 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7339 [(set (match_dup 0) (match_dup 1))]
7343 if (TARGET_SHMEDIA64)
7344 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7346 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7348 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7353 (define_expand "movdi_const"
7354 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7355 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7356 (const_int 48)] UNSPEC_EXTRACT_S16)))
7358 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7359 (const:DI (unspec:DI [(match_dup 1)
7360 (const_int 32)] UNSPEC_EXTRACT_U16))))
7362 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7363 (const:DI (unspec:DI [(match_dup 1)
7364 (const_int 16)] UNSPEC_EXTRACT_U16))))
7366 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7367 (const:DI (unspec:DI [(match_dup 1)
7368 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7369 "TARGET_SHMEDIA64 && reload_completed
7370 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7372 sh_mark_label (operands[1], 4);
7375 (define_expand "movdi_const_32bit"
7376 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7377 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7378 (const_int 16)] UNSPEC_EXTRACT_S16)))
7380 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7381 (const:DI (unspec:DI [(match_dup 1)
7382 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7383 "TARGET_SHMEDIA32 && reload_completed
7384 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7386 sh_mark_label (operands[1], 2);
7389 (define_expand "movdi_const_16bit"
7390 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7391 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7392 (const_int 0)] UNSPEC_EXTRACT_S16)))]
7393 "TARGET_SHMEDIA && flag_pic && reload_completed
7394 && GET_CODE (operands[1]) == SYMBOL_REF"
7398 [(set (match_operand:DI 0 "ext_dest_operand" "")
7399 (match_operand:DI 1 "immediate_operand" ""))]
7400 "TARGET_SHMEDIA && reload_completed
7401 && CONST_INT_P (operands[1])
7402 && ! satisfies_constraint_I16 (operands[1])"
7403 [(set (match_dup 0) (match_dup 2))
7406 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7407 unsigned HOST_WIDE_INT low = val;
7408 unsigned HOST_WIDE_INT high = val;
7409 unsigned HOST_WIDE_INT sign;
7410 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7412 /* Zero-extend the 16 least-significant bits. */
7415 /* Arithmetic shift right the word by 16 bits. */
7417 if (GET_CODE (operands[0]) == SUBREG
7418 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7427 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7433 /* If we can't generate the constant with a two-insn movi / shori
7434 sequence, try some other strategies. */
7435 if (! CONST_OK_FOR_I16 (high))
7437 /* Try constant load / left shift. We know VAL != 0. */
7438 val2 = val ^ (val-1);
7441 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7443 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7444 || (! CONST_OK_FOR_I16 (high >> 16)
7445 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7447 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7448 operands[1] = gen_ashldi3_media (operands[0], operands[0],
7449 GEN_INT (trailing_zeroes));
7453 /* Try constant load / right shift. */
7454 val2 = (val >> 15) + 1;
7455 if (val2 == (val2 & -val2))
7457 int shift = 49 - exact_log2 (val2);
7459 val2 = trunc_int_for_mode (val << shift, DImode);
7460 if (CONST_OK_FOR_I16 (val2))
7462 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7468 val2 = val & 0xffff;
7469 if ((val >> 16 & 0xffff) == val2
7470 && (val >> 32 & 0xffff) == val2
7471 && (val >> 48 & 0xffff) == val2)
7473 val2 = (HOST_WIDE_INT) val >> 48;
7474 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7475 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7478 /* Try movi / mshflo.l */
7479 val2 = (HOST_WIDE_INT) val >> 32;
7480 if (val2 == ((unsigned HOST_WIDE_INT)
7481 trunc_int_for_mode (val, SImode)))
7483 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7487 /* Try movi / mshflo.l w/ r63. */
7488 val2 = val + ((HOST_WIDE_INT) -1 << 32);
7489 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7491 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7497 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7500 operands[2] = GEN_INT (val2);
7504 [(set (match_operand:DI 0 "ext_dest_operand" "")
7505 (match_operand:DI 1 "immediate_operand" ""))]
7506 "TARGET_SHMEDIA && reload_completed
7507 && GET_CODE (operands[1]) == CONST_DOUBLE"
7508 [(set (match_dup 0) (match_dup 2))
7510 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7512 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7513 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7514 unsigned HOST_WIDE_INT val = low;
7515 unsigned HOST_WIDE_INT sign;
7517 /* Zero-extend the 16 least-significant bits. */
7519 operands[1] = GEN_INT (val);
7521 /* Arithmetic shift right the double-word by 16 bits. */
7523 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7526 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7530 /* This will only be true if high is a sign-extension of low, i.e.,
7531 it must be either 0 or (unsigned)-1, and be zero iff the
7532 most-significant bit of low is set. */
7533 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7534 operands[2] = GEN_INT (low);
7536 operands[2] = immed_double_const (low, high, DImode);
7539 (define_insn "shori_media"
7540 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7541 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7543 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7544 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7548 [(set_attr "type" "arith_media,*")])
7550 (define_insn "*shori_media_si"
7551 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7552 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7554 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7558 (define_expand "movdi"
7559 [(set (match_operand:DI 0 "general_movdst_operand" "")
7560 (match_operand:DI 1 "general_movsrc_operand" ""))]
7563 prepare_move_operands (operands, DImode);
7566 (define_insn "movdf_media"
7567 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7568 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7570 && (register_operand (operands[0], DFmode)
7571 || sh_register_operand (operands[1], DFmode))"
7582 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,
7583 fload_media,fstore_media,load_media,store_media")])
7585 (define_insn "movdf_media_nofpu"
7586 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7587 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7589 && (register_operand (operands[0], DFmode)
7590 || sh_register_operand (operands[1], DFmode))"
7596 [(set_attr "type" "arith_media,*,load_media,store_media")])
7599 [(set (match_operand:DF 0 "arith_reg_dest" "")
7600 (match_operand:DF 1 "immediate_operand" ""))]
7601 "TARGET_SHMEDIA && reload_completed"
7602 [(set (match_dup 3) (match_dup 2))]
7604 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7606 REAL_VALUE_TYPE value;
7608 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7609 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7611 if (HOST_BITS_PER_WIDE_INT >= 64)
7612 operands[2] = immed_double_const ((unsigned long) values[endian]
7613 | ((HOST_WIDE_INT) values[1 - endian]
7617 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7618 operands[2] = immed_double_const (values[endian], values[1 - endian],
7622 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7625 ;; FIXME: This should be a define_insn_and_split.
7626 (define_insn "movdf_k"
7627 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7628 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7630 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7631 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7632 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7633 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7634 && (arith_reg_operand (operands[0], DFmode)
7635 || arith_reg_operand (operands[1], DFmode))"
7637 return output_movedouble (insn, operands, DFmode);
7639 [(set_attr "length" "4")
7640 (set_attr "type" "move,pcload,load,store")])
7642 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7643 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7644 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7645 ;; the d/m/c/X alternative, which is split later into single-precision
7646 ;; instructions. And when not optimizing, no splits are done before fixing
7647 ;; up pcloads, so we need usable length information for that.
7648 (define_insn "movdf_i4"
7649 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7650 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
7651 (use (reg:SI FPSCR_MODES_REG))
7652 (clobber (match_scratch:SI 2 "=X,X,&z,X,X,X,X,X,X,X"))]
7653 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7654 && (arith_reg_operand (operands[0], DFmode)
7655 || arith_reg_operand (operands[1], DFmode))"
7657 switch (which_alternative)
7661 return "fmov %1,%0";
7662 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7663 return "fmov %R1,%R0" "\n"
7666 return "fmov %S1,%S0" "\n"
7670 return "fmov.d %1,%0";
7675 [(set_attr_alternative "length"
7676 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7678 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7679 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7680 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7682 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7683 ;; We can't use 4-byte push/pop on SHcompact, so we have to
7684 ;; increment or decrement r15 explicitly.
7686 (match_test "TARGET_SHCOMPACT")
7687 (const_int 10) (const_int 8))
7689 (match_test "TARGET_SHCOMPACT")
7690 (const_int 10) (const_int 8))])
7691 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7692 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7693 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7694 (const_string "double")
7695 (const_string "none")))])
7697 ;; Moving DFmode between fp/general registers through memory
7698 ;; (the top of the stack) is faster than moving through fpul even for
7699 ;; little endian. Because the type of an instruction is important for its
7700 ;; scheduling, it is beneficial to split these operations, rather than
7701 ;; emitting them in one single chunk, even if this will expose a stack
7702 ;; use that will prevent scheduling of other stack accesses beyond this
7705 [(set (match_operand:DF 0 "register_operand")
7706 (match_operand:DF 1 "register_operand"))
7707 (use (reg:SI FPSCR_MODES_REG))
7708 (clobber (match_scratch:SI 2))]
7709 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7710 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7715 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7717 emit_move_insn (stack_pointer_rtx,
7718 plus_constant (Pmode, stack_pointer_rtx, -8));
7719 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7722 tos = gen_tmp_stack_mem (DFmode,
7723 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7724 insn = emit_insn (gen_movdf_i4 (tos, operands[1]));
7725 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7726 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7727 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7728 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7730 tos = gen_tmp_stack_mem (DFmode,
7731 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7732 insn = emit_insn (gen_movdf_i4 (operands[0], tos));
7733 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7734 emit_move_insn (stack_pointer_rtx,
7735 plus_constant (Pmode, stack_pointer_rtx, 8));
7737 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7741 ;; local-alloc sometimes allocates scratch registers even when not required,
7742 ;; so we must be prepared to handle these.
7744 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7746 [(set (match_operand:DF 0 "general_movdst_operand" "")
7747 (match_operand:DF 1 "general_movsrc_operand" ""))
7748 (use (reg:SI FPSCR_MODES_REG))
7749 (clobber (match_scratch:SI 2))]
7750 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7752 && true_regnum (operands[0]) < 16
7753 && true_regnum (operands[1]) < 16"
7754 [(set (match_dup 0) (match_dup 1))]
7756 /* If this was a reg <-> mem operation with base + index reg addressing,
7757 we have to handle this in a special way. */
7758 rtx mem = operands[0];
7760 if (! memory_operand (mem, DFmode))
7765 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7766 mem = SUBREG_REG (mem);
7769 rtx addr = XEXP (mem, 0);
7770 if (GET_CODE (addr) == PLUS
7771 && REG_P (XEXP (addr, 0))
7772 && REG_P (XEXP (addr, 1)))
7775 rtx reg0 = gen_rtx_REG (Pmode, 0);
7776 rtx regop = operands[store_p], word0 ,word1;
7778 if (GET_CODE (regop) == SUBREG)
7779 alter_subreg (®op, true);
7780 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7784 mem = copy_rtx (mem);
7785 PUT_MODE (mem, SImode);
7786 word0 = gen_rtx_SUBREG (SImode, regop, 0);
7787 alter_subreg (&word0, true);
7788 word1 = gen_rtx_SUBREG (SImode, regop, 4);
7789 alter_subreg (&word1, true);
7790 if (store_p || ! refers_to_regno_p (REGNO (word0),
7791 REGNO (word0) + 1, addr, 0))
7794 ? gen_movsi_ie (mem, word0)
7795 : gen_movsi_ie (word0, mem));
7796 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7797 mem = copy_rtx (mem);
7799 ? gen_movsi_ie (mem, word1)
7800 : gen_movsi_ie (word1, mem));
7801 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7805 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7806 emit_insn (gen_movsi_ie (word1, mem));
7807 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7808 mem = copy_rtx (mem);
7809 emit_insn (gen_movsi_ie (word0, mem));
7816 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7818 [(set (match_operand:DF 0 "register_operand" "")
7819 (match_operand:DF 1 "memory_operand" ""))
7820 (use (reg:SI FPSCR_MODES_REG))
7821 (clobber (reg:SI R0_REG))]
7822 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7823 [(parallel [(set (match_dup 0) (match_dup 1))
7824 (use (reg:SI FPSCR_MODES_REG))
7825 (clobber (scratch:SI))])]
7828 (define_expand "reload_indf__frn"
7829 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7830 (match_operand:DF 1 "immediate_operand" "FQ"))
7831 (use (reg:SI FPSCR_MODES_REG))
7832 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7836 (define_expand "reload_outdf__RnFRm"
7837 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7838 (match_operand:DF 1 "register_operand" "af,r"))
7839 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7843 ;; Simplify no-op moves.
7845 [(set (match_operand:SF 0 "register_operand" "")
7846 (match_operand:SF 1 "register_operand" ""))
7847 (use (reg:SI FPSCR_MODES_REG))
7848 (clobber (match_scratch:SI 2))]
7849 "TARGET_SH2E && reload_completed
7850 && true_regnum (operands[0]) == true_regnum (operands[1])"
7851 [(set (match_dup 0) (match_dup 0))]
7854 ;; fmovd substitute post-reload splits
7856 [(set (match_operand:DF 0 "register_operand" "")
7857 (match_operand:DF 1 "register_operand" ""))
7858 (use (reg:SI FPSCR_MODES_REG))
7859 (clobber (match_scratch:SI 2))]
7860 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7861 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7862 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7865 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7866 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7867 gen_rtx_REG (SFmode, src)));
7868 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7869 gen_rtx_REG (SFmode, src + 1)));
7874 [(set (match_operand:DF 0 "register_operand" "")
7875 (mem:DF (match_operand:SI 1 "register_operand" "")))
7876 (use (reg:SI FPSCR_MODES_REG))
7877 (clobber (match_scratch:SI 2))]
7878 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7879 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7880 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7883 int regno = true_regnum (operands[0]);
7885 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7887 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7888 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7889 regno + SH_REG_MSW_OFFSET),
7891 add_reg_note (insn, REG_INC, operands[1]);
7892 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7893 regno + SH_REG_LSW_OFFSET),
7894 change_address (mem, SFmode, NULL_RTX)));
7899 [(set (match_operand:DF 0 "register_operand" "")
7900 (match_operand:DF 1 "memory_operand" ""))
7901 (use (reg:SI FPSCR_MODES_REG))
7902 (clobber (match_scratch:SI 2))]
7903 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7904 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7907 int regno = true_regnum (operands[0]);
7909 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7910 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
7911 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
7913 operands[1] = copy_rtx (mem2);
7914 addr = XEXP (mem2, 0);
7916 switch (GET_CODE (addr))
7919 /* This is complicated. If the register is an arithmetic register
7920 we can just fall through to the REG+DISP case below. Otherwise
7921 we have to use a combination of POST_INC and REG addressing... */
7922 if (! arith_reg_operand (operands[1], SFmode))
7924 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7925 insn = emit_insn (gen_movsf_ie (reg0, mem2));
7926 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7928 emit_insn (gen_movsf_ie (reg1, operands[1]));
7930 /* If we have modified the stack pointer, the value that we have
7931 read with post-increment might be modified by an interrupt,
7932 so write it back. */
7933 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7934 emit_insn (gen_push_e (reg0));
7936 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0),
7943 emit_insn (gen_movsf_ie (reg0, operands[1]));
7944 operands[1] = copy_rtx (operands[1]);
7945 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7946 emit_insn (gen_movsf_ie (reg1, operands[1]));
7950 insn = emit_insn (gen_movsf_ie (reg0, operands[1]));
7951 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7953 insn = emit_insn (gen_movsf_ie (reg1, operands[1]));
7954 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7966 [(set (match_operand:DF 0 "memory_operand" "")
7967 (match_operand:DF 1 "register_operand" ""))
7968 (use (reg:SI FPSCR_MODES_REG))
7969 (clobber (match_scratch:SI 2))]
7970 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7971 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7974 int regno = true_regnum (operands[1]);
7976 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
7977 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
7979 operands[0] = copy_rtx (operands[0]);
7980 PUT_MODE (operands[0], SFmode);
7981 addr = XEXP (operands[0], 0);
7983 switch (GET_CODE (addr))
7986 /* This is complicated. If the register is an arithmetic register
7987 we can just fall through to the REG+DISP case below. Otherwise
7988 we have to use a combination of REG and PRE_DEC addressing... */
7989 if (! arith_reg_operand (operands[0], SFmode))
7991 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
7992 emit_insn (gen_movsf_ie (operands[0], reg1));
7994 operands[0] = copy_rtx (operands[0]);
7995 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
7997 insn = emit_insn (gen_movsf_ie (operands[0], reg0));
7998 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8004 /* Since REG+DISP addressing has already been decided upon by gcc
8005 we can rely upon it having chosen an arithmetic register as the
8006 register component of the address. Just emit the lower numbered
8007 register first, to the lower address, then the higher numbered
8008 register to the higher address. */
8009 emit_insn (gen_movsf_ie (operands[0], reg0));
8011 operands[0] = copy_rtx (operands[0]);
8012 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
8014 emit_insn (gen_movsf_ie (operands[0], reg1));
8018 /* This is easy. Output the word to go to the higher address
8019 first (ie the word in the higher numbered register) then the
8020 word to go to the lower address. */
8022 insn = emit_insn (gen_movsf_ie (operands[0], reg1));
8023 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8025 insn = emit_insn (gen_movsf_ie (operands[0], reg0));
8026 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8038 ;; If the output is a register and the input is memory or a register, we have
8039 ;; to be careful and see which word needs to be loaded first.
8041 [(set (match_operand:DF 0 "general_movdst_operand" "")
8042 (match_operand:DF 1 "general_movsrc_operand" ""))]
8043 "TARGET_SH1 && reload_completed"
8044 [(set (match_dup 2) (match_dup 3))
8045 (set (match_dup 4) (match_dup 5))]
8049 if ((MEM_P (operands[0])
8050 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
8051 || (MEM_P (operands[1])
8052 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
8055 switch (GET_CODE (operands[0]))
8058 regno = REGNO (operands[0]);
8061 regno = subreg_regno (operands[0]);
8071 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8073 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
8074 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
8075 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
8076 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
8080 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
8081 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
8082 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
8083 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
8086 if (operands[2] == 0 || operands[3] == 0
8087 || operands[4] == 0 || operands[5] == 0)
8091 (define_expand "movdf"
8092 [(set (match_operand:DF 0 "general_movdst_operand" "")
8093 (match_operand:DF 1 "general_movsrc_operand" ""))]
8096 prepare_move_operands (operands, DFmode);
8099 if (TARGET_SHMEDIA_FPU)
8100 emit_insn (gen_movdf_media (operands[0], operands[1]));
8102 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
8105 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8107 emit_insn (gen_movdf_i4 (operands[0], operands[1]));
8112 ;;This is incompatible with the way gcc uses subregs.
8113 ;;(define_insn "movv2sf_i"
8114 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
8115 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
8116 ;; "TARGET_SHMEDIA_FPU
8117 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
8118 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
8122 ;; fst%M0.p %m0, %1"
8123 ;; [(set_attr "type" "*,fload_media,fstore_media")])
8124 (define_insn_and_split "movv2sf_i"
8125 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8126 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8127 "TARGET_SHMEDIA_FPU"
8129 "TARGET_SHMEDIA_FPU && reload_completed"
8130 [(set (match_dup 0) (match_dup 1))]
8132 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
8133 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
8136 (define_expand "movv2sf"
8137 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
8138 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
8139 "TARGET_SHMEDIA_FPU"
8141 prepare_move_operands (operands, V2SFmode);
8144 (define_expand "addv2sf3"
8145 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8146 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8147 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8148 "TARGET_SHMEDIA_FPU"
8150 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
8154 (define_expand "subv2sf3"
8155 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8156 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8157 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8158 "TARGET_SHMEDIA_FPU"
8160 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
8164 (define_expand "mulv2sf3"
8165 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8166 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8167 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8168 "TARGET_SHMEDIA_FPU"
8170 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
8174 (define_expand "divv2sf3"
8175 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8176 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8177 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8178 "TARGET_SHMEDIA_FPU"
8180 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
8184 (define_insn_and_split "*movv4sf_i"
8185 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8186 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8187 "TARGET_SHMEDIA_FPU"
8189 "&& reload_completed"
8192 for (int i = 0; i < 4/2; i++)
8196 if (MEM_P (operands[0]))
8197 x = adjust_address (operands[0], V2SFmode,
8198 i * GET_MODE_SIZE (V2SFmode));
8200 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
8202 if (MEM_P (operands[1]))
8203 y = adjust_address (operands[1], V2SFmode,
8204 i * GET_MODE_SIZE (V2SFmode));
8206 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8208 emit_insn (gen_movv2sf_i (x, y));
8213 [(set_attr "length" "8")])
8215 (define_expand "movv4sf"
8216 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8217 (match_operand:V4SF 1 "general_operand" ""))]
8218 "TARGET_SHMEDIA_FPU"
8220 prepare_move_operands (operands, V4SFmode);
8223 (define_insn_and_split "*movv16sf_i"
8224 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8225 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8226 "TARGET_SHMEDIA_FPU"
8228 "&& reload_completed"
8231 for (int i = 0; i < 16/2; i++)
8235 if (MEM_P (operands[0]))
8236 x = adjust_address (operands[0], V2SFmode,
8237 i * GET_MODE_SIZE (V2SFmode));
8240 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8241 alter_subreg (&x, true);
8244 if (MEM_P (operands[1]))
8245 y = adjust_address (operands[1], V2SFmode,
8246 i * GET_MODE_SIZE (V2SFmode));
8249 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8250 alter_subreg (&y, true);
8253 emit_insn (gen_movv2sf_i (x, y));
8258 [(set_attr "length" "32")])
8260 (define_expand "movv16sf"
8261 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8262 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8263 "TARGET_SHMEDIA_FPU"
8265 prepare_move_operands (operands, V16SFmode);
8268 (define_insn "movsf_media"
8269 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8270 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8272 && (register_operand (operands[0], SFmode)
8273 || sh_register_operand (operands[1], SFmode))"
8284 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8285 (set (attr "highpart")
8286 (cond [(match_test "sh_contains_memref_p (insn)")
8287 (const_string "user")]
8288 (const_string "ignore")))])
8290 (define_insn "movsf_media_nofpu"
8291 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8292 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8294 && (register_operand (operands[0], SFmode)
8295 || sh_register_operand (operands[1], SFmode))"
8301 [(set_attr "type" "arith_media,*,load_media,store_media")
8302 (set (attr "highpart")
8303 (cond [(match_test "sh_contains_memref_p (insn)")
8304 (const_string "user")]
8305 (const_string "ignore")))])
8308 [(set (match_operand:SF 0 "arith_reg_dest" "")
8309 (match_operand:SF 1 "immediate_operand" ""))]
8310 "TARGET_SHMEDIA && reload_completed
8311 && ! FP_REGISTER_P (true_regnum (operands[0]))"
8312 [(set (match_dup 3) (match_dup 2))]
8315 REAL_VALUE_TYPE value;
8317 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
8318 REAL_VALUE_TO_TARGET_SINGLE (value, values);
8319 operands[2] = GEN_INT (values);
8321 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8324 (define_insn "movsf_i"
8325 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8326 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
8329 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8330 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8331 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8332 && (arith_reg_operand (operands[0], SFmode)
8333 || arith_reg_operand (operands[1], SFmode))"
8342 [(set_attr "type" "move,move,pcload,load,store,move,move")])
8344 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8345 ;; update_flow_info would not know where to put REG_EQUAL notes
8346 ;; when the destination changes mode.
8347 (define_insn "movsf_ie"
8348 [(set (match_operand:SF 0 "general_movdst_operand"
8349 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8350 (match_operand:SF 1 "general_movsrc_operand"
8351 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8352 (use (reg:SI FPSCR_MODES_REG))
8353 (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8355 && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode)
8356 || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode)
8357 || arith_reg_operand (operands[2], SImode))"
8377 ! move optimized away"
8378 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8379 store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8380 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8381 (set_attr_alternative "length"
8388 (match_test "TARGET_SH2A")
8389 (const_int 4) (const_int 2))
8391 (match_test "TARGET_SH2A")
8392 (const_int 4) (const_int 2))
8395 (match_test "TARGET_SH2A")
8396 (const_int 4) (const_int 2))
8398 (match_test "TARGET_SH2A")
8399 (const_int 4) (const_int 2))
8409 (set_attr_alternative "fp_mode"
8410 [(if_then_else (eq_attr "fmovd" "yes")
8411 (const_string "single") (const_string "none"))
8412 (const_string "none")
8413 (const_string "single")
8414 (const_string "single")
8415 (const_string "none")
8416 (if_then_else (eq_attr "fmovd" "yes")
8417 (const_string "single") (const_string "none"))
8418 (if_then_else (eq_attr "fmovd" "yes")
8419 (const_string "single") (const_string "none"))
8420 (const_string "none")
8421 (const_string "none")
8422 (const_string "none")
8423 (const_string "none")
8424 (const_string "none")
8425 (const_string "none")
8426 (const_string "none")
8427 (const_string "none")
8428 (const_string "none")
8429 (const_string "none")
8430 (const_string "none")
8431 (const_string "none")])])
8433 (define_insn_and_split "movsf_ie_ra"
8434 [(set (match_operand:SF 0 "general_movdst_operand"
8435 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8436 (match_operand:SF 1 "general_movsrc_operand"
8437 "f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y,>,y"))
8438 (use (reg:SI FPSCR_MODES_REG))
8439 (clobber (match_scratch:SF 2 "=r,r,X,X,&z,r,r,X,r,r,r,r,r,y,r,r,r,r,r"))
8442 && (arith_reg_operand (operands[0], SFmode)
8443 || fpul_operand (operands[0], SFmode)
8444 || arith_reg_operand (operands[1], SFmode)
8445 || fpul_operand (operands[1], SFmode))"
8465 ! move optimized away"
8467 && sh_movsf_ie_ra_split_p (operands[0], operands[1], operands[2])"
8470 if (! rtx_equal_p (operands[0], operands[1]))
8472 emit_insn (gen_movsf_ie (operands[2], operands[1]));
8473 emit_insn (gen_movsf_ie (operands[0], operands[2]));
8476 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8477 store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8478 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8479 (set_attr_alternative "length"
8486 (match_test "TARGET_SH2A")
8487 (const_int 4) (const_int 2))
8489 (match_test "TARGET_SH2A")
8490 (const_int 4) (const_int 2))
8493 (match_test "TARGET_SH2A")
8494 (const_int 4) (const_int 2))
8496 (match_test "TARGET_SH2A")
8497 (const_int 4) (const_int 2))
8507 (set_attr_alternative "fp_mode"
8508 [(if_then_else (eq_attr "fmovd" "yes")
8509 (const_string "single") (const_string "none"))
8510 (const_string "none")
8511 (const_string "single")
8512 (const_string "single")
8513 (const_string "none")
8514 (if_then_else (eq_attr "fmovd" "yes")
8515 (const_string "single") (const_string "none"))
8516 (if_then_else (eq_attr "fmovd" "yes")
8517 (const_string "single") (const_string "none"))
8518 (const_string "none")
8519 (const_string "none")
8520 (const_string "none")
8521 (const_string "none")
8522 (const_string "none")
8523 (const_string "none")
8524 (const_string "none")
8525 (const_string "none")
8526 (const_string "none")
8527 (const_string "none")
8528 (const_string "none")
8529 (const_string "none")])])
8532 [(set (match_operand:SF 0 "register_operand" "")
8533 (match_operand:SF 1 "register_operand" ""))
8534 (use (reg:SI FPSCR_MODES_REG))
8535 (clobber (reg:SI FPUL_REG))]
8537 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8538 (use (reg:SI FPSCR_MODES_REG))
8539 (clobber (scratch:SI))])
8540 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8541 (use (reg:SI FPSCR_MODES_REG))
8542 (clobber (scratch:SI))])]
8545 (define_expand "movsf"
8546 [(set (match_operand:SF 0 "general_movdst_operand" "")
8547 (match_operand:SF 1 "general_movsrc_operand" ""))]
8550 prepare_move_operands (operands, SFmode);
8553 if (TARGET_SHMEDIA_FPU)
8554 emit_insn (gen_movsf_media (operands[0], operands[1]));
8556 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8561 if (lra_in_progress)
8563 if (GET_CODE (operands[0]) == SCRATCH)
8565 emit_insn (gen_movsf_ie_ra (operands[0], operands[1]));
8569 emit_insn (gen_movsf_ie (operands[0], operands[1]));
8574 (define_insn "mov_nop"
8575 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8578 [(set_attr "length" "0")
8579 (set_attr "type" "nil")])
8581 (define_expand "reload_insf__frn"
8582 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8583 (match_operand:SF 1 "immediate_operand" "FQ"))
8584 (use (reg:SI FPSCR_MODES_REG))
8585 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8589 (define_expand "reload_insi__i_fpul"
8590 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8591 (match_operand:SI 1 "immediate_operand" "i"))
8592 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8596 (define_expand "ptabs"
8597 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8600 if (!TARGET_PT_FIXED)
8602 rtx eq = operands[1];
8604 /* ??? For canonical RTL we really should remove any CONST from EQ
8605 before wrapping it in the AND, and finally wrap the EQ into a
8606 const if is constant. However, for reload we must expose the
8607 input register or symbolic constant, and we can't have
8608 different insn structures outside of the operands for different
8609 alternatives of the same pattern. */
8610 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8613 = (gen_rtx_IF_THEN_ELSE
8616 gen_rtx_MEM (PDImode, operands[1]),
8617 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8618 PDImode, operands[1])));
8622 ;; expanded by ptabs expander.
8623 (define_insn "*extendsipdi_media"
8624 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8625 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8629 (mem:PDI (match_dup 1))
8630 (sign_extend:PDI (match_dup 1))))]
8631 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8635 [(set_attr "type" "ptabs_media,pt_media")
8636 (set_attr "length" "4,*")])
8638 (define_insn "*truncdipdi_media"
8639 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8640 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8644 (mem:PDI (match_dup 1))
8645 (truncate:PDI (match_dup 1))))]
8646 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8650 [(set_attr "type" "ptabs_media,pt_media")
8651 (set_attr "length" "4,*")])
8653 (define_insn "*movsi_y"
8654 [(set (match_operand:SI 0 "register_operand" "=y,y")
8655 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8656 (clobber (match_scratch:SI 2 "=&z,r"))]
8658 && (reload_in_progress || reload_completed)"
8660 [(set_attr "length" "4")
8661 (set_attr "type" "pcload,move")])
8664 [(set (match_operand:SI 0 "register_operand" "")
8665 (match_operand:SI 1 "immediate_operand" ""))
8666 (clobber (match_operand:SI 2 "register_operand" ""))]
8668 [(set (match_dup 2) (match_dup 1))
8669 (set (match_dup 0) (match_dup 2))]
8672 ;; ------------------------------------------------------------------------
8673 ;; Define the real conditional branch instructions.
8674 ;; ------------------------------------------------------------------------
8676 (define_expand "branch_true"
8677 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8678 (label_ref (match_operand 0))
8682 (define_expand "branch_false"
8683 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8684 (label_ref (match_operand 0))
8688 (define_insn_and_split "*cbranch_t"
8689 [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8690 (label_ref (match_operand 0))
8694 return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8699 /* Try to canonicalize the branch condition if it is not one of:
8700 (ne (reg:SI T_REG) (const_int 0))
8701 (eq (reg:SI T_REG) (const_int 0))
8703 Instead of splitting out a new insn, we modify the current insn's
8704 operands as needed. This preserves things such as REG_DEAD notes. */
8706 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
8707 && REG_P (XEXP (operands[1], 0)) && REGNO (XEXP (operands[1], 0)) == T_REG
8708 && XEXP (operands[1], 1) == const0_rtx)
8711 int branch_cond = sh_eval_treg_value (operands[1]);
8712 rtx new_cond_rtx = NULL_RTX;
8714 if (branch_cond == 0)
8715 new_cond_rtx = gen_rtx_EQ (VOIDmode, get_t_reg_rtx (), const0_rtx);
8716 else if (branch_cond == 1)
8717 new_cond_rtx = gen_rtx_NE (VOIDmode, get_t_reg_rtx (), const0_rtx);
8719 if (new_cond_rtx != NULL_RTX)
8720 validate_change (curr_insn, &XEXP (XEXP (PATTERN (curr_insn), 1), 0),
8721 new_cond_rtx, false);
8724 [(set_attr "type" "cbranch")])
8726 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8727 ;; which destination is too far away.
8728 ;; The const_int_operand is distinct for each branch target; it avoids
8729 ;; unwanted matches with redundant_insn.
8730 (define_insn "block_branch_redirect"
8731 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8734 [(set_attr "length" "0")])
8736 ;; This one has the additional purpose to record a possible scratch register
8737 ;; for the following branch.
8738 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8739 ;; because the insn then might be deemed dead and deleted. And we can't
8740 ;; make the use in the jump insn explicit because that would disable
8741 ;; delay slot scheduling from the target.
8742 (define_insn "indirect_jump_scratch"
8743 [(set (match_operand:SI 0 "register_operand" "=r")
8744 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8745 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8748 [(set_attr "length" "0")])
8750 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8751 ;; being pulled into the delay slot of a condbranch that has been made to
8752 ;; jump around the unconditional jump because it was out of range.
8753 (define_insn "stuff_delay_slot"
8755 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8756 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8759 [(set_attr "length" "0")
8760 (set_attr "cond_delay_slot" "yes")])
8762 ;; Conditional branch insns
8764 (define_expand "cbranchint4_media"
8766 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8767 [(match_operand 1 "" "")
8768 (match_operand 2 "" "")])
8769 (match_operand 3 "" "")
8773 machine_mode mode = GET_MODE (operands[1]);
8774 if (mode == VOIDmode)
8775 mode = GET_MODE (operands[2]);
8776 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8778 operands[1] = force_reg (mode, operands[1]);
8779 if (CONSTANT_P (operands[2])
8780 && (! satisfies_constraint_I06 (operands[2])))
8781 operands[2] = force_reg (mode, operands[2]);
8785 if (operands[1] != const0_rtx)
8786 operands[1] = force_reg (mode, operands[1]);
8787 if (operands[2] != const0_rtx)
8788 operands[2] = force_reg (mode, operands[2]);
8790 switch (GET_CODE (operands[0]))
8796 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8797 VOIDmode, operands[2], operands[1]);
8798 operands[1] = XEXP (operands[0], 0);
8799 operands[2] = XEXP (operands[0], 1);
8802 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8803 VOIDmode, operands[1], operands[2]);
8806 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8809 (define_expand "cbranchfp4_media"
8811 (if_then_else (match_operator 0 "sh_float_comparison_operator"
8812 [(match_operand 1 "" "")
8813 (match_operand 2 "" "")])
8814 (match_operand 3 "" "")
8818 rtx tmp = gen_reg_rtx (SImode);
8820 if (GET_CODE (operands[0]) == NE)
8821 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8823 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8824 operands[1], operands[2]);
8826 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8828 if (GET_CODE (cmp) == GET_CODE (operands[0]))
8829 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8831 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8833 operands[2] = const0_rtx;
8834 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8837 (define_insn "*beq_media_i"
8839 (if_then_else (match_operator 3 "equality_comparison_operator"
8840 [(match_operand:DI 1 "arith_reg_operand" "r,r")
8841 (match_operand:DI 2 "arith_operand" "r,I06")])
8842 (match_operand 0 "target_operand" "b,b")
8847 b%o3i%' %1, %2, %0%>"
8848 [(set_attr "type" "cbranch_media")])
8850 (define_insn "*beq_media_i32"
8852 (if_then_else (match_operator 3 "equality_comparison_operator"
8853 [(match_operand:SI 1 "arith_reg_operand" "r,r")
8854 (match_operand:SI 2 "arith_operand" "r,I06")])
8855 (match_operand 0 "target_operand" "b,b")
8860 b%o3i%' %1, %2, %0%>"
8861 [(set_attr "type" "cbranch_media")])
8863 (define_insn "*bgt_media_i"
8865 (if_then_else (match_operator 3 "greater_comparison_operator"
8866 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8867 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8868 (match_operand 0 "target_operand" "b")
8871 "b%o3%' %N1, %N2, %0%>"
8872 [(set_attr "type" "cbranch_media")])
8874 (define_insn "*bgt_media_i32"
8876 (if_then_else (match_operator 3 "greater_comparison_operator"
8877 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8878 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8879 (match_operand 0 "target_operand" "b")
8882 "b%o3%' %N1, %N2, %0%>"
8883 [(set_attr "type" "cbranch_media")])
8885 ;; These are only needed to make invert_jump() happy - otherwise, jump
8886 ;; optimization will be silently disabled.
8887 (define_insn "*blt_media_i"
8889 (if_then_else (match_operator 3 "less_comparison_operator"
8890 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8891 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8892 (match_operand 0 "target_operand" "b")
8895 "b%o3%' %N2, %N1, %0%>"
8896 [(set_attr "type" "cbranch_media")])
8898 (define_insn "*blt_media_i32"
8900 (if_then_else (match_operator 3 "less_comparison_operator"
8901 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8902 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8903 (match_operand 0 "target_operand" "b")
8906 "b%o3%' %N2, %N1, %0%>"
8907 [(set_attr "type" "cbranch_media")])
8909 ;; combiner splitter for test-and-branch on single bit in register. This
8910 ;; is endian dependent because the non-paradoxical subreg looks different
8915 (match_operator 3 "equality_comparison_operator"
8918 (subreg:DI (match_operand:SI 1 "extend_reg_operand" "") 0)
8920 (match_operand 2 "const_int_operand" "")) 0)
8922 (match_operand 0 "target_operand" "")
8924 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8925 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8926 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8927 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8929 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8930 operands[6] = (GET_CODE (operands[3]) == EQ
8931 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8932 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8935 ; operand 0 is the loop count pseudo register
8936 ; operand 1 is the label to jump to at the top of the loop
8937 (define_expand "doloop_end"
8938 [(parallel [(set (pc)
8939 (if_then_else (ne:SI (match_operand:SI 0 "" "")
8941 (label_ref (match_operand 1 "" ""))
8944 (plus:SI (match_dup 0) (const_int -1)))
8945 (clobber (reg:SI T_REG))])]
8948 if (GET_MODE (operands[0]) != SImode)
8950 emit_jump_insn (gen_doloop_end_split (operands[0], operands[1], operands[0]));
8954 (define_insn_and_split "doloop_end_split"
8956 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8958 (label_ref (match_operand 1 "" ""))
8960 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8961 (plus:SI (match_dup 2) (const_int -1)))
8962 (clobber (reg:SI T_REG))]
8966 [(parallel [(set (reg:SI T_REG)
8967 (eq:SI (match_dup 2) (const_int 1)))
8968 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8969 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8970 (label_ref (match_dup 1))
8973 [(set_attr "type" "cbranch")])
8975 ;; ------------------------------------------------------------------------
8976 ;; Jump and linkage insns
8977 ;; ------------------------------------------------------------------------
8979 (define_insn "jump_compact"
8981 (label_ref (match_operand 0 "" "")))]
8982 "TARGET_SH1 && !CROSSING_JUMP_P (insn)"
8984 /* The length is 16 if the delay slot is unfilled. */
8985 if (get_attr_length(insn) > 4)
8986 return output_far_jump(insn, operands[0]);
8990 [(set_attr "type" "jump")
8991 (set_attr "needs_delay_slot" "yes")])
8993 ;; ??? It would be much saner to explicitly use the scratch register
8994 ;; in the jump insn, and have indirect_jump_scratch only set it,
8995 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8996 ;; from the target then, as it uses simplejump_p.
8997 ;;(define_insn "jump_compact_far"
8999 ;; (label_ref (match_operand 0 "" "")))
9000 ;; (use (match_operand 1 "register_operand" "r")]
9002 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
9003 ;; [(set_attr "type" "jump")
9004 ;; (set_attr "needs_delay_slot" "yes")])
9006 (define_insn "jump_media"
9008 (match_operand 0 "target_operand" "b"))]
9011 [(set_attr "type" "jump_media")])
9013 (define_expand "jump"
9015 (label_ref (match_operand 0 "" "")))]
9019 emit_jump_insn (gen_jump_compact (operands[0]));
9020 else if (TARGET_SHMEDIA)
9022 if (reload_in_progress || reload_completed)
9024 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, operands[0])));
9029 (define_insn "force_mode_for_call"
9030 [(use (reg:SI FPSCR_MODES_REG))]
9033 [(set_attr "length" "0")
9034 (set (attr "fp_mode")
9035 (if_then_else (eq_attr "fpu_single" "yes")
9036 (const_string "single") (const_string "double")))])
9038 (define_insn "calli"
9039 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9040 (match_operand 1 "" ""))
9041 (use (reg:SI FPSCR_MODES_REG))
9042 (clobber (reg:SI PR_REG))]
9045 if (TARGET_SH2A && (dbr_sequence_length () == 0))
9050 [(set_attr "type" "call")
9051 (set (attr "fp_mode")
9052 (if_then_else (eq_attr "fpu_single" "yes")
9053 (const_string "single") (const_string "double")))
9054 (set_attr "needs_delay_slot" "yes")
9055 (set_attr "fp_set" "unknown")])
9057 ;; This is TBR relative jump instruction for SH2A architecture.
9058 ;; Its use is enabled by assigning an attribute "function_vector"
9059 ;; and the vector number to a function during its declaration.
9060 (define_insn "calli_tbr_rel"
9061 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
9062 (match_operand 1 "" ""))
9063 (use (reg:SI FPSCR_MODES_REG))
9064 (clobber (reg:SI PR_REG))]
9065 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
9067 unsigned HOST_WIDE_INT vect_num;
9068 vect_num = sh2a_get_function_vector_number (operands[0]);
9069 operands[2] = GEN_INT (vect_num * 4);
9071 return "jsr/n @@(%O2,tbr)";
9073 [(set_attr "type" "call")
9074 (set (attr "fp_mode")
9075 (if_then_else (eq_attr "fpu_single" "yes")
9076 (const_string "single") (const_string "double")))
9077 (set_attr "needs_delay_slot" "no")
9078 (set_attr "fp_set" "unknown")])
9080 ;; This is a pc-rel call, using bsrf, for use with PIC.
9081 (define_insn "calli_pcrel"
9082 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9083 (match_operand 1 "" ""))
9084 (use (reg:SI FPSCR_MODES_REG))
9085 (use (reg:SI PIC_REG))
9086 (use (match_operand 2 "" ""))
9087 (clobber (reg:SI PR_REG))]
9090 return "bsrf %0" "\n"
9093 [(set_attr "type" "call")
9094 (set (attr "fp_mode")
9095 (if_then_else (eq_attr "fpu_single" "yes")
9096 (const_string "single") (const_string "double")))
9097 (set_attr "needs_delay_slot" "yes")
9098 (set_attr "fp_set" "unknown")])
9100 (define_insn_and_split "call_pcrel"
9101 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9102 (match_operand 1 "" ""))
9103 (use (reg:SI FPSCR_MODES_REG))
9104 (use (reg:SI PIC_REG))
9105 (clobber (reg:SI PR_REG))
9106 (clobber (match_scratch:SI 2 "=r"))]
9112 rtx lab = PATTERN (gen_call_site ());
9114 if (SYMBOL_REF_LOCAL_P (operands[0]))
9115 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9117 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
9118 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
9121 [(set_attr "type" "call")
9122 (set (attr "fp_mode")
9123 (if_then_else (eq_attr "fpu_single" "yes")
9124 (const_string "single") (const_string "double")))
9125 (set_attr "needs_delay_slot" "yes")
9126 (set_attr "fp_set" "unknown")])
9128 (define_insn "call_compact"
9129 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9130 (match_operand 1 "" ""))
9131 (match_operand 2 "immediate_operand" "n")
9132 (use (reg:SI R0_REG))
9133 (use (reg:SI R1_REG))
9134 (use (reg:SI FPSCR_MODES_REG))
9135 (clobber (reg:SI PR_REG))]
9136 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9138 [(set_attr "type" "call")
9139 (set (attr "fp_mode")
9140 (if_then_else (eq_attr "fpu_single" "yes")
9141 (const_string "single") (const_string "double")))
9142 (set_attr "needs_delay_slot" "yes")])
9144 (define_insn "call_compact_rettramp"
9145 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9146 (match_operand 1 "" ""))
9147 (match_operand 2 "immediate_operand" "n")
9148 (use (reg:SI R0_REG))
9149 (use (reg:SI R1_REG))
9150 (use (reg:SI FPSCR_MODES_REG))
9151 (clobber (reg:SI R10_REG))
9152 (clobber (reg:SI PR_REG))]
9153 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9155 [(set_attr "type" "call")
9156 (set (attr "fp_mode")
9157 (if_then_else (eq_attr "fpu_single" "yes")
9158 (const_string "single") (const_string "double")))
9159 (set_attr "needs_delay_slot" "yes")])
9161 (define_insn "call_media"
9162 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
9163 (match_operand 1 "" ""))
9164 (clobber (reg:DI PR_MEDIA_REG))]
9167 [(set_attr "type" "jump_media")])
9169 (define_insn "call_valuei"
9170 [(set (match_operand 0 "" "=rf")
9171 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9172 (match_operand 2 "" "")))
9173 (use (reg:SI FPSCR_MODES_REG))
9174 (clobber (reg:SI PR_REG))]
9177 if (TARGET_SH2A && (dbr_sequence_length () == 0))
9182 [(set_attr "type" "call")
9183 (set (attr "fp_mode")
9184 (if_then_else (eq_attr "fpu_single" "yes")
9185 (const_string "single") (const_string "double")))
9186 (set_attr "needs_delay_slot" "yes")
9187 (set_attr "fp_set" "unknown")])
9189 ;; This is TBR relative jump instruction for SH2A architecture.
9190 ;; Its use is enabled by assigning an attribute "function_vector"
9191 ;; and the vector number to a function during its declaration.
9192 (define_insn "call_valuei_tbr_rel"
9193 [(set (match_operand 0 "" "=rf")
9194 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9195 (match_operand 2 "" "")))
9196 (use (reg:SI FPSCR_MODES_REG))
9197 (clobber (reg:SI PR_REG))]
9198 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
9200 unsigned HOST_WIDE_INT vect_num;
9201 vect_num = sh2a_get_function_vector_number (operands[1]);
9202 operands[3] = GEN_INT (vect_num * 4);
9204 return "jsr/n @@(%O3,tbr)";
9206 [(set_attr "type" "call")
9207 (set (attr "fp_mode")
9208 (if_then_else (eq_attr "fpu_single" "yes")
9209 (const_string "single") (const_string "double")))
9210 (set_attr "needs_delay_slot" "no")
9211 (set_attr "fp_set" "unknown")])
9213 (define_insn "call_valuei_pcrel"
9214 [(set (match_operand 0 "" "=rf")
9215 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9216 (match_operand 2 "" "")))
9217 (use (reg:SI FPSCR_MODES_REG))
9218 (use (reg:SI PIC_REG))
9219 (use (match_operand 3 "" ""))
9220 (clobber (reg:SI PR_REG))]
9223 return "bsrf %1" "\n"
9226 [(set_attr "type" "call")
9227 (set (attr "fp_mode")
9228 (if_then_else (eq_attr "fpu_single" "yes")
9229 (const_string "single") (const_string "double")))
9230 (set_attr "needs_delay_slot" "yes")
9231 (set_attr "fp_set" "unknown")])
9233 (define_insn_and_split "call_value_pcrel"
9234 [(set (match_operand 0 "" "=rf")
9235 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9236 (match_operand 2 "" "")))
9237 (use (reg:SI FPSCR_MODES_REG))
9238 (use (reg:SI PIC_REG))
9239 (clobber (reg:SI PR_REG))
9240 (clobber (match_scratch:SI 3 "=r"))]
9246 rtx lab = PATTERN (gen_call_site ());
9248 if (SYMBOL_REF_LOCAL_P (operands[1]))
9249 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9251 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
9252 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
9253 operands[2], copy_rtx (lab)));
9256 [(set_attr "type" "call")
9257 (set (attr "fp_mode")
9258 (if_then_else (eq_attr "fpu_single" "yes")
9259 (const_string "single") (const_string "double")))
9260 (set_attr "needs_delay_slot" "yes")
9261 (set_attr "fp_set" "unknown")])
9263 (define_insn "call_value_compact"
9264 [(set (match_operand 0 "" "=rf")
9265 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9266 (match_operand 2 "" "")))
9267 (match_operand 3 "immediate_operand" "n")
9268 (use (reg:SI R0_REG))
9269 (use (reg:SI R1_REG))
9270 (use (reg:SI FPSCR_MODES_REG))
9271 (clobber (reg:SI PR_REG))]
9272 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9274 [(set_attr "type" "call")
9275 (set (attr "fp_mode")
9276 (if_then_else (eq_attr "fpu_single" "yes")
9277 (const_string "single") (const_string "double")))
9278 (set_attr "needs_delay_slot" "yes")])
9280 (define_insn "call_value_compact_rettramp"
9281 [(set (match_operand 0 "" "=rf")
9282 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9283 (match_operand 2 "" "")))
9284 (match_operand 3 "immediate_operand" "n")
9285 (use (reg:SI R0_REG))
9286 (use (reg:SI R1_REG))
9287 (use (reg:SI FPSCR_MODES_REG))
9288 (clobber (reg:SI R10_REG))
9289 (clobber (reg:SI PR_REG))]
9290 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9292 [(set_attr "type" "call")
9293 (set (attr "fp_mode")
9294 (if_then_else (eq_attr "fpu_single" "yes")
9295 (const_string "single") (const_string "double")))
9296 (set_attr "needs_delay_slot" "yes")])
9298 (define_insn "call_value_media"
9299 [(set (match_operand 0 "" "=rf")
9300 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9301 (match_operand 2 "" "")))
9302 (clobber (reg:DI PR_MEDIA_REG))]
9305 [(set_attr "type" "jump_media")])
9307 (define_expand "call"
9308 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9309 (match_operand 1 "" ""))
9310 (match_operand 2 "" "")
9311 (use (reg:SI FPSCR_MODES_REG))
9312 (clobber (reg:SI PR_REG))])]
9317 operands[0] = shmedia_prepare_call_address (operands[0], 0);
9318 emit_call_insn (gen_call_media (operands[0], operands[1]));
9321 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9323 rtx cookie_rtx = operands[2];
9324 long cookie = INTVAL (cookie_rtx);
9325 rtx func = XEXP (operands[0], 0);
9330 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9332 rtx reg = gen_reg_rtx (Pmode);
9334 emit_insn (gen_symGOTPLT2reg (reg, func));
9338 func = legitimize_pic_address (func, Pmode, 0);
9341 r0 = gen_rtx_REG (SImode, R0_REG);
9342 r1 = gen_rtx_REG (SImode, R1_REG);
9344 /* Since such a call function may use all call-clobbered
9345 registers, we force a mode switch earlier, so that we don't
9346 run out of registers when adjusting fpscr for the call. */
9347 emit_insn (gen_force_mode_for_call ());
9350 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9351 operands[0] = force_reg (SImode, operands[0]);
9353 emit_move_insn (r0, func);
9354 emit_move_insn (r1, cookie_rtx);
9356 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9357 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9360 emit_call_insn (gen_call_compact (operands[0], operands[1],
9365 else if (TARGET_SHCOMPACT && flag_pic
9366 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9367 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9369 rtx reg = gen_reg_rtx (Pmode);
9371 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9372 XEXP (operands[0], 0) = reg;
9374 if (!flag_pic && TARGET_SH2A
9375 && MEM_P (operands[0])
9376 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9378 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9380 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9385 if (flag_pic && TARGET_SH2
9386 && MEM_P (operands[0])
9387 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9389 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9394 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9395 operands[1] = operands[2];
9398 emit_call_insn (gen_calli (operands[0], operands[1]));
9402 (define_insn "call_pop_compact"
9403 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9404 (match_operand 1 "" ""))
9405 (match_operand 2 "immediate_operand" "n")
9406 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9407 (match_operand 3 "immediate_operand" "n")))
9408 (use (reg:SI R0_REG))
9409 (use (reg:SI R1_REG))
9410 (use (reg:SI FPSCR_MODES_REG))
9411 (clobber (reg:SI PR_REG))]
9412 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9414 [(set_attr "type" "call")
9415 (set (attr "fp_mode")
9416 (if_then_else (eq_attr "fpu_single" "yes")
9417 (const_string "single") (const_string "double")))
9418 (set_attr "needs_delay_slot" "yes")])
9420 (define_insn "call_pop_compact_rettramp"
9421 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9422 (match_operand 1 "" ""))
9423 (match_operand 2 "immediate_operand" "n")
9424 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9425 (match_operand 3 "immediate_operand" "n")))
9426 (use (reg:SI R0_REG))
9427 (use (reg:SI R1_REG))
9428 (use (reg:SI FPSCR_MODES_REG))
9429 (clobber (reg:SI R10_REG))
9430 (clobber (reg:SI PR_REG))]
9431 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9433 [(set_attr "type" "call")
9434 (set (attr "fp_mode")
9435 (if_then_else (eq_attr "fpu_single" "yes")
9436 (const_string "single") (const_string "double")))
9437 (set_attr "needs_delay_slot" "yes")])
9439 (define_expand "call_pop"
9440 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9441 (match_operand 1 "" ""))
9442 (match_operand 2 "" "")
9443 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9444 (match_operand 3 "" "")))])]
9452 gcc_assert (operands[2] && INTVAL (operands[2]));
9453 cookie_rtx = operands[2];
9454 cookie = INTVAL (cookie_rtx);
9455 func = XEXP (operands[0], 0);
9459 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9461 rtx reg = gen_reg_rtx (Pmode);
9462 emit_insn (gen_symGOTPLT2reg (reg, func));
9466 func = legitimize_pic_address (func, Pmode, 0);
9469 r0 = gen_rtx_REG (SImode, R0_REG);
9470 r1 = gen_rtx_REG (SImode, R1_REG);
9472 /* Since such a call function may use all call-clobbered
9473 registers, we force a mode switch earlier, so that we don't
9474 run out of registers when adjusting fpscr for the call. */
9475 emit_insn (gen_force_mode_for_call ());
9477 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9479 operands[0] = force_reg (SImode, operands[0]);
9481 emit_move_insn (r0, func);
9482 emit_move_insn (r1, cookie_rtx);
9484 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9485 emit_call_insn (gen_call_pop_compact_rettramp
9486 (operands[0], operands[1], operands[2], operands[3]));
9488 emit_call_insn (gen_call_pop_compact
9489 (operands[0], operands[1], operands[2], operands[3]));
9494 (define_expand "call_value"
9495 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9496 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9497 (match_operand 2 "" "")))
9498 (match_operand 3 "" "")
9499 (use (reg:SI FPSCR_MODES_REG))
9500 (clobber (reg:SI PR_REG))])]
9505 operands[1] = shmedia_prepare_call_address (operands[1], 0);
9506 emit_call_insn (gen_call_value_media (operands[0], operands[1],
9510 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9512 rtx cookie_rtx = operands[3];
9513 long cookie = INTVAL (cookie_rtx);
9514 rtx func = XEXP (operands[1], 0);
9519 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9521 rtx reg = gen_reg_rtx (Pmode);
9523 emit_insn (gen_symGOTPLT2reg (reg, func));
9527 func = legitimize_pic_address (func, Pmode, 0);
9530 r0 = gen_rtx_REG (SImode, R0_REG);
9531 r1 = gen_rtx_REG (SImode, R1_REG);
9533 /* Since such a call function may use all call-clobbered
9534 registers, we force a mode switch earlier, so that we don't
9535 run out of registers when adjusting fpscr for the call. */
9536 emit_insn (gen_force_mode_for_call ());
9539 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9540 operands[1] = force_reg (SImode, operands[1]);
9542 emit_move_insn (r0, func);
9543 emit_move_insn (r1, cookie_rtx);
9545 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9546 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9551 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9552 operands[2], operands[3]));
9556 else if (TARGET_SHCOMPACT && flag_pic
9557 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9558 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9560 rtx reg = gen_reg_rtx (Pmode);
9562 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9563 XEXP (operands[1], 0) = reg;
9565 if (!flag_pic && TARGET_SH2A
9566 && MEM_P (operands[1])
9567 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9569 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9571 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9572 XEXP (operands[1], 0), operands[2]));
9576 if (flag_pic && TARGET_SH2
9577 && MEM_P (operands[1])
9578 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9580 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9585 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9587 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9591 (define_insn "sibcalli"
9592 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9593 (match_operand 1 "" ""))
9594 (use (reg:SI FPSCR_MODES_REG))
9598 [(set_attr "needs_delay_slot" "yes")
9599 (set (attr "fp_mode")
9600 (if_then_else (eq_attr "fpu_single" "yes")
9601 (const_string "single") (const_string "double")))
9602 (set_attr "type" "jump_ind")])
9604 (define_insn "sibcalli_pcrel"
9605 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9606 (match_operand 1 "" ""))
9607 (use (match_operand 2 "" ""))
9608 (use (reg:SI FPSCR_MODES_REG))
9612 return "braf %0" "\n"
9615 [(set_attr "needs_delay_slot" "yes")
9616 (set (attr "fp_mode")
9617 (if_then_else (eq_attr "fpu_single" "yes")
9618 (const_string "single") (const_string "double")))
9619 (set_attr "type" "jump_ind")])
9621 ;; This uses an unspec to describe that the symbol_ref is very close.
9622 (define_insn "sibcalli_thunk"
9623 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9625 (match_operand 1 "" ""))
9626 (use (reg:SI FPSCR_MODES_REG))
9630 [(set_attr "needs_delay_slot" "yes")
9631 (set (attr "fp_mode")
9632 (if_then_else (eq_attr "fpu_single" "yes")
9633 (const_string "single") (const_string "double")))
9634 (set_attr "type" "jump")
9635 (set_attr "length" "2")])
9637 (define_insn_and_split "sibcall_pcrel"
9638 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9639 (match_operand 1 "" ""))
9640 (use (reg:SI FPSCR_MODES_REG))
9641 (clobber (match_scratch:SI 2 "=k"))
9648 rtx lab = PATTERN (gen_call_site ());
9651 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9652 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9654 SIBLING_CALL_P (call_insn) = 1;
9657 [(set_attr "needs_delay_slot" "yes")
9658 (set (attr "fp_mode")
9659 (if_then_else (eq_attr "fpu_single" "yes")
9660 (const_string "single") (const_string "double")))
9661 (set_attr "type" "jump_ind")])
9663 (define_insn "sibcall_compact"
9664 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9665 (match_operand 1 "" ""))
9667 (use (match_operand:SI 2 "register_operand" "z,x"))
9668 (use (reg:SI R1_REG))
9669 (use (reg:SI FPSCR_MODES_REG))
9670 ;; We want to make sure the `x' above will only match MACH_REG
9671 ;; because sibcall_epilogue may clobber MACL_REG.
9672 (clobber (reg:SI MACL_REG))]
9675 static const char* alt[] =
9682 return alt[which_alternative];
9684 [(set_attr "needs_delay_slot" "yes,no")
9685 (set_attr "length" "2,4")
9686 (set (attr "fp_mode") (const_string "single"))
9687 (set_attr "type" "jump_ind")])
9689 (define_insn "sibcall_media"
9690 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9691 (match_operand 1 "" ""))
9692 (use (reg:SI PR_MEDIA_REG))
9696 [(set_attr "type" "jump_media")])
9698 (define_expand "sibcall"
9700 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9701 (match_operand 1 "" ""))
9702 (match_operand 2 "" "")
9703 (use (reg:SI FPSCR_MODES_REG))
9709 operands[0] = shmedia_prepare_call_address (operands[0], 1);
9710 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9713 else if (TARGET_SHCOMPACT && operands[2]
9714 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9716 rtx cookie_rtx = operands[2];
9717 long cookie = INTVAL (cookie_rtx);
9718 rtx func = XEXP (operands[0], 0);
9723 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9725 rtx reg = gen_reg_rtx (Pmode);
9727 emit_insn (gen_symGOT2reg (reg, func));
9731 func = legitimize_pic_address (func, Pmode, 0);
9734 /* FIXME: if we could tell whether all argument registers are
9735 already taken, we could decide whether to force the use of
9736 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9737 simple way to tell. We could use the CALL_COOKIE, but we
9738 can't currently tell a register used for regular argument
9739 passing from one that is unused. If we leave it up to reload
9740 to decide which register to use, it seems to always choose
9741 R0_REG, which leaves no available registers in SIBCALL_REGS
9742 to hold the address of the trampoline. */
9743 mach = gen_rtx_REG (SImode, MACH_REG);
9744 r1 = gen_rtx_REG (SImode, R1_REG);
9746 /* Since such a call function may use all call-clobbered
9747 registers, we force a mode switch earlier, so that we don't
9748 run out of registers when adjusting fpscr for the call. */
9749 emit_insn (gen_force_mode_for_call ());
9752 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9753 operands[0] = force_reg (SImode, operands[0]);
9755 /* We don't need a return trampoline, since the callee will
9756 return directly to the upper caller. */
9757 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9759 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9760 cookie_rtx = GEN_INT (cookie);
9763 emit_move_insn (mach, func);
9764 emit_move_insn (r1, cookie_rtx);
9766 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9769 else if (TARGET_SHCOMPACT && flag_pic
9770 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9771 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9773 rtx reg = gen_reg_rtx (Pmode);
9775 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9776 XEXP (operands[0], 0) = reg;
9778 if (flag_pic && TARGET_SH2
9779 && MEM_P (operands[0])
9780 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9781 /* The PLT needs the PIC register, but the epilogue would have
9782 to restore it, so we can only use PC-relative PIC calls for
9783 static functions. */
9784 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9786 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9790 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9792 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9796 (define_insn "sibcall_valuei"
9797 [(set (match_operand 0 "" "=rf")
9798 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9799 (match_operand 2 "" "")))
9800 (use (reg:SI FPSCR_MODES_REG))
9804 [(set_attr "needs_delay_slot" "yes")
9805 (set (attr "fp_mode")
9806 (if_then_else (eq_attr "fpu_single" "yes")
9807 (const_string "single") (const_string "double")))
9808 (set_attr "type" "jump_ind")])
9810 (define_insn "sibcall_valuei_pcrel"
9811 [(set (match_operand 0 "" "=rf")
9812 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9813 (match_operand 2 "" "")))
9814 (use (match_operand 3 "" ""))
9815 (use (reg:SI FPSCR_MODES_REG))
9819 return "braf %1" "\n"
9822 [(set_attr "needs_delay_slot" "yes")
9823 (set (attr "fp_mode")
9824 (if_then_else (eq_attr "fpu_single" "yes")
9825 (const_string "single") (const_string "double")))
9826 (set_attr "type" "jump_ind")])
9828 (define_insn_and_split "sibcall_value_pcrel"
9829 [(set (match_operand 0 "" "=rf")
9830 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9831 (match_operand 2 "" "")))
9832 (use (reg:SI FPSCR_MODES_REG))
9833 (clobber (match_scratch:SI 3 "=k"))
9840 rtx lab = PATTERN (gen_call_site ());
9843 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9844 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9848 SIBLING_CALL_P (call_insn) = 1;
9851 [(set_attr "needs_delay_slot" "yes")
9852 (set (attr "fp_mode")
9853 (if_then_else (eq_attr "fpu_single" "yes")
9854 (const_string "single") (const_string "double")))
9855 (set_attr "type" "jump_ind")])
9857 (define_insn "sibcall_value_compact"
9858 [(set (match_operand 0 "" "=rf,rf")
9859 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9860 (match_operand 2 "" "")))
9862 (use (match_operand:SI 3 "register_operand" "z,x"))
9863 (use (reg:SI R1_REG))
9864 (use (reg:SI FPSCR_MODES_REG))
9865 ;; We want to make sure the `x' above will only match MACH_REG
9866 ;; because sibcall_epilogue may clobber MACL_REG.
9867 (clobber (reg:SI MACL_REG))]
9870 static const char* alt[] =
9877 return alt[which_alternative];
9879 [(set_attr "needs_delay_slot" "yes,no")
9880 (set_attr "length" "2,4")
9881 (set (attr "fp_mode") (const_string "single"))
9882 (set_attr "type" "jump_ind")])
9884 (define_insn "sibcall_value_media"
9885 [(set (match_operand 0 "" "=rf")
9886 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9887 (match_operand 2 "" "")))
9888 (use (reg:SI PR_MEDIA_REG))
9892 [(set_attr "type" "jump_media")])
9894 (define_expand "sibcall_value"
9896 [(set (match_operand 0 "arith_reg_operand" "")
9897 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9898 (match_operand 2 "" "")))
9899 (match_operand 3 "" "")
9900 (use (reg:SI FPSCR_MODES_REG))
9906 operands[1] = shmedia_prepare_call_address (operands[1], 1);
9907 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9911 else if (TARGET_SHCOMPACT && operands[3]
9912 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9914 rtx cookie_rtx = operands[3];
9915 long cookie = INTVAL (cookie_rtx);
9916 rtx func = XEXP (operands[1], 0);
9921 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9923 rtx reg = gen_reg_rtx (Pmode);
9925 emit_insn (gen_symGOT2reg (reg, func));
9929 func = legitimize_pic_address (func, Pmode, 0);
9932 /* FIXME: if we could tell whether all argument registers are
9933 already taken, we could decide whether to force the use of
9934 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9935 simple way to tell. We could use the CALL_COOKIE, but we
9936 can't currently tell a register used for regular argument
9937 passing from one that is unused. If we leave it up to reload
9938 to decide which register to use, it seems to always choose
9939 R0_REG, which leaves no available registers in SIBCALL_REGS
9940 to hold the address of the trampoline. */
9941 mach = gen_rtx_REG (SImode, MACH_REG);
9942 r1 = gen_rtx_REG (SImode, R1_REG);
9944 /* Since such a call function may use all call-clobbered
9945 registers, we force a mode switch earlier, so that we don't
9946 run out of registers when adjusting fpscr for the call. */
9947 emit_insn (gen_force_mode_for_call ());
9950 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9951 operands[1] = force_reg (SImode, operands[1]);
9953 /* We don't need a return trampoline, since the callee will
9954 return directly to the upper caller. */
9955 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9957 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9958 cookie_rtx = GEN_INT (cookie);
9961 emit_move_insn (mach, func);
9962 emit_move_insn (r1, cookie_rtx);
9964 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9965 operands[2], mach));
9968 else if (TARGET_SHCOMPACT && flag_pic
9969 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9970 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9972 rtx reg = gen_reg_rtx (Pmode);
9974 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9975 XEXP (operands[1], 0) = reg;
9977 if (flag_pic && TARGET_SH2
9978 && MEM_P (operands[1])
9979 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9980 /* The PLT needs the PIC register, but the epilogue would have
9981 to restore it, so we can only use PC-relative PIC calls for
9982 static functions. */
9983 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9985 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9986 XEXP (operands[1], 0),
9991 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9993 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9997 (define_insn "call_value_pop_compact"
9998 [(set (match_operand 0 "" "=rf")
9999 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
10000 (match_operand 2 "" "")))
10001 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
10002 (match_operand 4 "immediate_operand" "n")))
10003 (match_operand 3 "immediate_operand" "n")
10004 (use (reg:SI R0_REG))
10005 (use (reg:SI R1_REG))
10006 (use (reg:SI FPSCR_MODES_REG))
10007 (clobber (reg:SI PR_REG))]
10008 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
10010 [(set_attr "type" "call")
10011 (set (attr "fp_mode")
10012 (if_then_else (eq_attr "fpu_single" "yes")
10013 (const_string "single") (const_string "double")))
10014 (set_attr "needs_delay_slot" "yes")])
10016 (define_insn "call_value_pop_compact_rettramp"
10017 [(set (match_operand 0 "" "=rf")
10018 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
10019 (match_operand 2 "" "")))
10020 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
10021 (match_operand 4 "immediate_operand" "n")))
10022 (match_operand 3 "immediate_operand" "n")
10023 (use (reg:SI R0_REG))
10024 (use (reg:SI R1_REG))
10025 (use (reg:SI FPSCR_MODES_REG))
10026 (clobber (reg:SI R10_REG))
10027 (clobber (reg:SI PR_REG))]
10028 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
10030 [(set_attr "type" "call")
10031 (set (attr "fp_mode")
10032 (if_then_else (eq_attr "fpu_single" "yes")
10033 (const_string "single") (const_string "double")))
10034 (set_attr "needs_delay_slot" "yes")])
10036 (define_expand "call_value_pop"
10037 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
10038 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
10039 (match_operand 2 "" "")))
10040 (match_operand 3 "" "")
10041 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
10042 (match_operand 4 "" "")))])]
10050 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
10051 cookie_rtx = operands[3];
10052 cookie = INTVAL (cookie_rtx);
10053 func = XEXP (operands[1], 0);
10057 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
10059 rtx reg = gen_reg_rtx (Pmode);
10061 emit_insn (gen_symGOTPLT2reg (reg, func));
10065 func = legitimize_pic_address (func, Pmode, 0);
10068 r0 = gen_rtx_REG (SImode, R0_REG);
10069 r1 = gen_rtx_REG (SImode, R1_REG);
10071 /* Since such a call function may use all call-clobbered
10072 registers, we force a mode switch earlier, so that we don't
10073 run out of registers when adjusting fpscr for the call. */
10074 emit_insn (gen_force_mode_for_call ());
10076 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
10078 operands[1] = force_reg (SImode, operands[1]);
10080 emit_move_insn (r0, func);
10081 emit_move_insn (r1, cookie_rtx);
10083 if (cookie & CALL_COOKIE_RET_TRAMP (1))
10084 emit_call_insn (gen_call_value_pop_compact_rettramp
10085 (operands[0], operands[1], operands[2],
10086 operands[3], operands[4]));
10088 emit_call_insn (gen_call_value_pop_compact
10089 (operands[0], operands[1], operands[2],
10090 operands[3], operands[4]));
10095 (define_expand "sibcall_epilogue"
10099 sh_expand_epilogue (true);
10100 if (TARGET_SHCOMPACT)
10105 /* If epilogue clobbers r0, preserve it in macl. */
10106 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10107 if ((set = single_set (insn))
10108 && REG_P (SET_DEST (set))
10109 && REGNO (SET_DEST (set)) == R0_REG)
10111 rtx r0 = gen_rtx_REG (SImode, R0_REG);
10112 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
10114 /* We can't tell at this point whether the sibcall is a
10115 sibcall_compact and, if it is, whether it uses r0 or
10116 mach as operand 2, so let the instructions that
10117 preserve r0 be optimized away if r0 turns out to be
10119 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
10120 emit_move_insn (r0, tmp);
10127 (define_insn "indirect_jump_compact"
10129 (match_operand:SI 0 "arith_reg_operand" "r"))]
10132 [(set_attr "needs_delay_slot" "yes")
10133 (set_attr "type" "jump_ind")])
10135 (define_expand "indirect_jump"
10137 (match_operand 0 "register_operand" ""))]
10140 if (GET_MODE (operands[0]) != Pmode)
10141 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
10144 ;; The use of operand 1 / 2 helps us distinguish case table jumps
10145 ;; which can be present in structured code from indirect jumps which can not
10146 ;; be present in structured code. This allows -fprofile-arcs to work.
10148 ;; For SH1 processors.
10149 (define_insn "casesi_jump_1"
10151 (match_operand:SI 0 "register_operand" "r"))
10152 (use (label_ref (match_operand 1 "" "")))]
10155 [(set_attr "needs_delay_slot" "yes")
10156 (set_attr "type" "jump_ind")])
10158 ;; For all later processors.
10159 (define_insn "casesi_jump_2"
10160 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
10161 (label_ref (match_operand 1 "" ""))))
10162 (use (label_ref (match_operand 2 "" "")))]
10164 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
10166 [(set_attr "needs_delay_slot" "yes")
10167 (set_attr "type" "jump_ind")])
10169 (define_insn "casesi_jump_media"
10170 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
10171 (use (label_ref (match_operand 1 "" "")))]
10174 [(set_attr "type" "jump_media")])
10176 ;; Call subroutine returning any type.
10177 ;; ??? This probably doesn't work.
10178 (define_expand "untyped_call"
10179 [(parallel [(call (match_operand 0 "" "")
10181 (match_operand 1 "" "")
10182 (match_operand 2 "" "")])]
10183 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
10185 if (! TARGET_SHMEDIA)
10187 /* RA does not know that the call sets the function value registers.
10188 We avoid problems by claiming that those registers are clobbered
10190 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10192 rtx set = XVECEXP (operands[2], 0, i);
10193 emit_clobber (SET_SRC (set));
10197 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10199 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10201 rtx set = XVECEXP (operands[2], 0, i);
10202 emit_move_insn (SET_DEST (set), SET_SRC (set));
10205 /* The optimizer does not know that the call sets the function value
10206 registers we stored in the result block. We avoid problems by
10207 claiming that all hard registers are used and clobbered at this
10209 emit_insn (gen_blockage ());
10214 ;; ------------------------------------------------------------------------
10216 ;; ------------------------------------------------------------------------
10218 (define_insn "dect"
10219 [(set (reg:SI T_REG)
10220 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
10221 (set (match_operand:SI 0 "arith_reg_dest" "=r")
10222 (plus:SI (match_dup 1) (const_int -1)))]
10225 [(set_attr "type" "arith")])
10232 ;; Load address of a label. This is only generated by the casesi expand,
10233 ;; and by machine_dependent_reorg (fixing up fp moves).
10234 ;; This must use unspec, because this only works for labels that are
10236 (define_insn "mova"
10237 [(set (reg:SI R0_REG)
10238 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
10241 [(set_attr "in_delay_slot" "no")
10242 (set_attr "type" "arith")])
10244 ;; machine_dependent_reorg will make this a `mova'.
10245 (define_insn "mova_const"
10246 [(set (reg:SI R0_REG)
10247 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
10250 [(set_attr "in_delay_slot" "no")
10251 (set_attr "type" "arith")])
10253 (define_expand "GOTaddr2picreg"
10254 [(set (reg:SI R0_REG)
10255 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
10257 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
10258 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10261 if (TARGET_VXWORKS_RTP)
10263 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
10264 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
10265 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
10269 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
10270 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10272 if (TARGET_SHMEDIA)
10274 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10275 rtx pic = operands[0];
10276 rtx lab = PATTERN (gen_call_site ());
10279 equiv = operands[1];
10280 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
10281 UNSPEC_PCREL_SYMOFF);
10282 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
10284 if (Pmode == SImode)
10286 emit_insn (gen_movsi_const (pic, operands[1]));
10287 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10291 emit_insn (gen_movdi_const (pic, operands[1]));
10292 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10295 insn = emit_move_insn (operands[0], tr);
10297 set_unique_reg_note (insn, REG_EQUAL, equiv);
10303 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10305 (define_expand "vxworks_picreg"
10306 [(set (reg:SI PIC_REG)
10307 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10308 (set (reg:SI R0_REG)
10309 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10310 (set (reg:SI PIC_REG)
10311 (mem:SI (reg:SI PIC_REG)))
10312 (set (reg:SI PIC_REG)
10313 (mem:SI (plus:SI (reg:SI PIC_REG)
10314 (reg:SI R0_REG))))]
10315 "TARGET_VXWORKS_RTP")
10317 (define_insn "*ptb"
10318 [(set (match_operand 0 "target_reg_operand" "=b")
10319 (const (unspec [(match_operand 1 "" "Csy")]
10320 UNSPEC_DATALABEL)))]
10321 "TARGET_SHMEDIA && flag_pic
10322 && satisfies_constraint_Csy (operands[1])"
10323 "ptb/u datalabel %1, %0"
10324 [(set_attr "type" "ptabs_media")
10325 (set_attr "length" "*")])
10327 (define_insn "ptrel_si"
10328 [(set (match_operand:SI 0 "target_reg_operand" "=b")
10329 (plus:SI (match_operand:SI 1 "register_operand" "r")
10331 (match_operand:SI 2 "" "")]
10333 "%O2: ptrel/u %1, %0"
10334 [(set_attr "type" "ptabs_media")])
10336 (define_insn "ptrel_di"
10337 [(set (match_operand:DI 0 "target_reg_operand" "=b")
10338 (plus:DI (match_operand:DI 1 "register_operand" "r")
10340 (match_operand:DI 2 "" "")]
10342 "%O2: ptrel/u %1, %0"
10343 [(set_attr "type" "ptabs_media")])
10345 (define_expand "builtin_setjmp_receiver"
10346 [(match_operand 0 "" "")]
10349 emit_insn (gen_GOTaddr2picreg ());
10353 (define_expand "call_site"
10354 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10357 static HOST_WIDE_INT i = 0;
10358 operands[0] = GEN_INT (i);
10362 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
10363 ;; in symGOT_load expand.
10364 (define_insn_and_split "chk_guard_add"
10365 [(set (match_operand:SI 0 "register_operand" "=&r")
10366 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10371 "TARGET_SH1 && reload_completed"
10372 [(set (match_dup 0) (reg:SI PIC_REG))
10373 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10375 [(set_attr "type" "arith")])
10377 (define_expand "sym_label2reg"
10378 [(set (match_operand:SI 0 "" "")
10379 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10380 (const (plus:SI (match_operand:SI 2 "" "")
10385 (define_expand "symGOT_load"
10386 [(set (match_dup 2) (match_operand 1 "" ""))
10387 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10388 (set (match_operand 0 "" "") (mem (match_dup 3)))]
10393 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10394 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10396 if (TARGET_SHMEDIA)
10398 rtx reg = operands[2];
10400 if (Pmode == DImode)
10403 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10405 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10410 emit_insn (gen_movsi_const (reg, operands[1]));
10412 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10416 emit_move_insn (operands[2], operands[1]);
10418 /* When stack protector inserts codes after the result is set to
10419 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
10420 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10421 when rX is a GOT address for the guard symbol. Ugly but doesn't
10422 matter because this is a rare situation. */
10423 if (!TARGET_SHMEDIA
10424 && flag_stack_protect
10425 && GET_CODE (operands[1]) == CONST
10426 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10427 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10428 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10429 "__stack_chk_guard") == 0)
10430 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10432 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10433 gen_rtx_REG (Pmode, PIC_REG)));
10435 /* N.B. This is not constant for a GOTPLT relocation. */
10436 mem = gen_rtx_MEM (Pmode, operands[3]);
10437 MEM_NOTRAP_P (mem) = 1;
10438 /* ??? Should we have a special alias set for the GOT? */
10439 emit_move_insn (operands[0], mem);
10444 (define_expand "sym2GOT"
10445 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10449 (define_expand "symGOT2reg"
10450 [(match_operand 0 "" "") (match_operand 1 "" "")]
10455 gotsym = gen_sym2GOT (operands[1]);
10456 PUT_MODE (gotsym, Pmode);
10457 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10459 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10464 (define_expand "symGOTPLT2reg"
10465 [(match_operand 0 "" "") (match_operand 1 "" "")]
10468 rtx pltsym = gen_rtx_CONST (Pmode,
10469 gen_rtx_UNSPEC (Pmode,
10470 gen_rtvec (1, operands[1]),
10472 emit_insn (gen_symGOT_load (operands[0], pltsym));
10476 (define_expand "sym2GOTOFF"
10477 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10481 (define_expand "symGOTOFF2reg"
10482 [(match_operand 0 "" "") (match_operand 1 "" "")]
10485 rtx gotoffsym, insn;
10486 rtx t = (!can_create_pseudo_p ()
10488 : gen_reg_rtx (GET_MODE (operands[0])));
10490 gotoffsym = gen_sym2GOTOFF (operands[1]);
10491 PUT_MODE (gotoffsym, Pmode);
10492 emit_move_insn (t, gotoffsym);
10493 insn = emit_move_insn (operands[0],
10494 gen_rtx_PLUS (Pmode, t,
10495 gen_rtx_REG (Pmode, PIC_REG)));
10497 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10502 (define_expand "symPLT_label2reg"
10503 [(set (match_operand:SI 0 "" "")
10506 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10507 (const:SI (plus:SI (match_operand:SI 2 "" "")
10508 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10509 ;; Even though the PIC register is not really used by the call
10510 ;; sequence in which this is expanded, the PLT code assumes the PIC
10511 ;; register is set, so we must not skip its initialization. Since
10512 ;; we only use this expand as part of calling sequences, and never
10513 ;; to take the address of a function, this is the best point to
10514 ;; insert the (use). Using the PLT to take the address of a
10515 ;; function would be wrong, not only because the PLT entry could
10516 ;; then be called from a function that doesn't initialize the PIC
10517 ;; register to the proper GOT, but also because pointers to the
10518 ;; same function might not compare equal, should they be set by
10519 ;; different shared libraries.
10520 (use (reg:SI PIC_REG))]
10524 (define_expand "sym2PIC"
10525 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10529 ;; -------------------------------------------------------------------------
10530 ;; TLS code generation.
10532 ;; FIXME: The multi-insn asm blocks should be converted to use
10533 ;; define_insn_and_split.
10534 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10535 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10538 (define_insn "tls_global_dynamic"
10539 [(set (match_operand:SI 0 "register_operand" "=&z")
10540 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10543 (use (reg:SI FPSCR_MODES_REG))
10544 (use (reg:SI PIC_REG))
10545 (clobber (reg:SI PR_REG))
10546 (clobber (scratch:SI))]
10549 return "mov.l 1f,r4" "\n"
10551 " mov.l 2f,r1" "\n"
10558 "1: .long %a1@TLSGD" "\n"
10559 "2: .long __tls_get_addr@PLT" "\n"
10562 [(set_attr "type" "tls_load")
10563 (set_attr "length" "26")])
10565 (define_insn "tls_local_dynamic"
10566 [(set (match_operand:SI 0 "register_operand" "=&z")
10567 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10570 (use (reg:SI FPSCR_MODES_REG))
10571 (use (reg:SI PIC_REG))
10572 (clobber (reg:SI PR_REG))
10573 (clobber (scratch:SI))]
10576 return "mov.l 1f,r4" "\n"
10578 " mov.l 2f,r1" "\n"
10585 "1: .long %a1@TLSLDM" "\n"
10586 "2: .long __tls_get_addr@PLT" "\n"
10589 [(set_attr "type" "tls_load")
10590 (set_attr "length" "26")])
10592 (define_expand "sym2DTPOFF"
10593 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10597 (define_expand "symDTPOFF2reg"
10598 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10602 rtx t = (!can_create_pseudo_p ()
10604 : gen_reg_rtx (GET_MODE (operands[0])));
10606 dtpoffsym = gen_sym2DTPOFF (operands[1]);
10607 PUT_MODE (dtpoffsym, Pmode);
10608 emit_move_insn (t, dtpoffsym);
10609 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10613 (define_expand "sym2GOTTPOFF"
10614 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10618 (define_insn "tls_initial_exec"
10619 [(set (match_operand:SI 0 "register_operand" "=&r")
10620 (unspec:SI [(match_operand:SI 1 "" "")]
10622 (use (reg:SI GBR_REG))
10623 (use (reg:SI PIC_REG))
10624 (clobber (reg:SI R0_REG))]
10627 return "mov.l 1f,r0" "\n"
10629 " mov.l @(r0,r12),r0" "\n"
10633 "1: .long %a1" "\n"
10636 [(set_attr "type" "tls_load")
10637 (set_attr "length" "16")])
10639 (define_expand "sym2TPOFF"
10640 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10644 (define_expand "symTPOFF2reg"
10645 [(match_operand 0 "" "") (match_operand 1 "" "")]
10650 tpoffsym = gen_sym2TPOFF (operands[1]);
10651 PUT_MODE (tpoffsym, Pmode);
10652 emit_move_insn (operands[0], tpoffsym);
10656 ;;------------------------------------------------------------------------------
10657 ;; Thread pointer getter and setter.
10659 ;; On SH the thread pointer is kept in the GBR.
10660 ;; These patterns are usually expanded from the respective built-in functions.
10661 (define_expand "get_thread_pointersi"
10662 [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10665 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10666 (define_insn "store_gbr"
10667 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10670 [(set_attr "type" "tls_load")])
10672 (define_expand "set_thread_pointersi"
10673 [(set (reg:SI GBR_REG)
10674 (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10678 (define_insn "load_gbr"
10679 [(set (reg:SI GBR_REG)
10680 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10684 [(set_attr "type" "move")])
10686 ;;------------------------------------------------------------------------------
10687 ;; Thread pointer relative memory loads and stores.
10689 ;; On SH there are GBR displacement address modes which can be utilized to
10690 ;; access memory behind the thread pointer.
10691 ;; Since we do not allow using GBR for general purpose memory accesses, these
10692 ;; GBR addressing modes are formed by the combine pass.
10693 ;; This could be done with fewer patterns than below by using a mem predicate
10694 ;; for the GBR mem, but then reload would try to reload addresses with a
10695 ;; zero displacement for some strange reason.
10697 (define_insn "*mov<mode>_gbr_load"
10698 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10699 (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10700 (match_operand:QIHISI 1 "gbr_displacement"))))]
10702 "mov.<bwl> @(%O1,gbr),%0"
10703 [(set_attr "type" "load")])
10705 (define_insn "*mov<mode>_gbr_load"
10706 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10707 (mem:QIHISI (reg:SI GBR_REG)))]
10709 "mov.<bwl> @(0,gbr),%0"
10710 [(set_attr "type" "load")])
10712 (define_insn "*mov<mode>_gbr_load"
10713 [(set (match_operand:SI 0 "register_operand" "=z")
10715 (mem:QIHI (plus:SI (reg:SI GBR_REG)
10716 (match_operand:QIHI 1 "gbr_displacement")))))]
10718 "mov.<bw> @(%O1,gbr),%0"
10719 [(set_attr "type" "load")])
10721 (define_insn "*mov<mode>_gbr_load"
10722 [(set (match_operand:SI 0 "register_operand" "=z")
10723 (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10725 "mov.<bw> @(0,gbr),%0"
10726 [(set_attr "type" "load")])
10728 (define_insn "*mov<mode>_gbr_store"
10729 [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10730 (match_operand:QIHISI 0 "gbr_displacement")))
10731 (match_operand:QIHISI 1 "register_operand" "z"))]
10733 "mov.<bwl> %1,@(%O0,gbr)"
10734 [(set_attr "type" "store")])
10736 (define_insn "*mov<mode>_gbr_store"
10737 [(set (mem:QIHISI (reg:SI GBR_REG))
10738 (match_operand:QIHISI 0 "register_operand" "z"))]
10740 "mov.<bwl> %0,@(0,gbr)"
10741 [(set_attr "type" "store")])
10743 ;; DImode memory accesses have to be split in two SImode accesses.
10744 ;; Split them before reload, so that it gets a better chance to figure out
10745 ;; how to deal with the R0 restriction for the individual SImode accesses.
10746 ;; Do not match this insn during or after reload because it can't be split
10748 (define_insn_and_split "*movdi_gbr_load"
10749 [(set (match_operand:DI 0 "register_operand")
10750 (match_operand:DI 1 "gbr_address_mem"))]
10751 "TARGET_SH1 && can_create_pseudo_p ()"
10754 [(set (match_dup 3) (match_dup 5))
10755 (set (match_dup 4) (match_dup 6))]
10757 /* Swap low/high part load order on little endian, so that the result reg
10758 of the second load can be used better. */
10759 int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10760 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10761 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10762 operands[4 - off] = gen_highpart (SImode, operands[0]);
10763 operands[6 - off] = gen_highpart (SImode, operands[1]);
10766 (define_insn_and_split "*movdi_gbr_store"
10767 [(set (match_operand:DI 0 "gbr_address_mem")
10768 (match_operand:DI 1 "register_operand"))]
10769 "TARGET_SH1 && can_create_pseudo_p ()"
10772 [(set (match_dup 3) (match_dup 5))
10773 (set (match_dup 4) (match_dup 6))]
10775 /* Swap low/high part store order on big endian, so that stores of function
10776 call results can save a reg copy. */
10777 int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10778 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10779 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10780 operands[4 - off] = gen_highpart (SImode, operands[0]);
10781 operands[6 - off] = gen_highpart (SImode, operands[1]);
10784 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10785 ;; in particular when the displacements are in the range of the regular move
10786 ;; insns. Thus, in the first split pass after the combine pass we search
10787 ;; for missed opportunities and try to fix them up ourselves.
10788 ;; If an equivalent GBR address can be determined the load / store is split
10789 ;; into one of the GBR load / store patterns.
10790 ;; All of that must happen before reload (GBR address modes use R0 as the
10791 ;; other operand) and there's no point of doing it if the GBR is not
10792 ;; referenced in a function at all.
10794 [(set (match_operand:QIHISIDI 0 "register_operand")
10795 (match_operand:QIHISIDI 1 "memory_operand"))]
10796 "TARGET_SH1 && !reload_in_progress && !reload_completed
10797 && df_regs_ever_live_p (GBR_REG)"
10798 [(set (match_dup 0) (match_dup 1))]
10800 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10801 if (gbr_mem != NULL_RTX)
10802 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10808 [(set (match_operand:SI 0 "register_operand")
10809 (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10810 "TARGET_SH1 && !reload_in_progress && !reload_completed
10811 && df_regs_ever_live_p (GBR_REG)"
10812 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10814 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10815 if (gbr_mem != NULL_RTX)
10816 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10821 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10822 ;; Split those so that a GBR load can be used.
10824 [(set (match_operand:SI 0 "register_operand")
10825 (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10826 "TARGET_SH2A && !reload_in_progress && !reload_completed
10827 && df_regs_ever_live_p (GBR_REG)"
10828 [(set (match_dup 2) (match_dup 1))
10829 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10831 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10832 if (gbr_mem != NULL_RTX)
10834 operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10835 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10842 [(set (match_operand:QIHISIDI 0 "memory_operand")
10843 (match_operand:QIHISIDI 1 "register_operand"))]
10844 "TARGET_SH1 && !reload_in_progress && !reload_completed
10845 && df_regs_ever_live_p (GBR_REG)"
10846 [(set (match_dup 0) (match_dup 1))]
10848 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10849 if (gbr_mem != NULL_RTX)
10850 operands[0] = replace_equiv_address (operands[0], gbr_mem);
10855 ;;------------------------------------------------------------------------------
10856 ;; case instruction for switch statements.
10858 ;; operand 0 is index
10859 ;; operand 1 is the minimum bound
10860 ;; operand 2 is the maximum bound - minimum bound + 1
10861 ;; operand 3 is CODE_LABEL for the table;
10862 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10863 (define_expand "casesi"
10864 [(match_operand:SI 0 "arith_reg_operand" "")
10865 (match_operand:SI 1 "arith_reg_operand" "")
10866 (match_operand:SI 2 "arith_reg_operand" "")
10867 (match_operand 3 "" "") (match_operand 4 "" "")]
10870 rtx reg = gen_reg_rtx (SImode);
10871 rtx reg2 = gen_reg_rtx (SImode);
10872 if (TARGET_SHMEDIA)
10874 rtx reg = gen_reg_rtx (DImode);
10875 rtx reg2 = gen_reg_rtx (DImode);
10876 rtx reg3 = gen_reg_rtx (Pmode);
10877 rtx reg4 = gen_reg_rtx (Pmode);
10878 rtx reg5 = gen_reg_rtx (Pmode);
10881 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10882 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10883 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10885 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10886 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0],
10888 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10889 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10890 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10891 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10892 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10893 (Pmode, operands[3])));
10894 /* Messy: can we subreg to clean this up? */
10895 if (Pmode == DImode)
10896 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10898 load = gen_casesi_load_media (reg4,
10899 gen_rtx_SUBREG (DImode, reg3, 0),
10900 reg2, operands[3]);
10901 PUT_MODE (SET_SRC (load), Pmode);
10903 /* ??? The following add could be eliminated if we used ptrel. */
10904 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10905 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10909 operands[1] = copy_to_mode_reg (SImode, operands[1]);
10910 operands[2] = copy_to_mode_reg (SImode, operands[2]);
10911 /* If optimizing, casesi_worker depends on the mode of the instruction
10912 before label it 'uses' - operands[3]. */
10913 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10915 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10917 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10919 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10920 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10921 operands[3], but to lab. We will fix this up in
10922 machine_dependent_reorg. */
10927 (define_expand "casesi_0"
10928 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10929 (set (match_dup 4) (minus:SI (match_dup 4)
10930 (match_operand:SI 1 "arith_operand" "")))
10931 (set (reg:SI T_REG)
10932 (gtu:SI (match_dup 4)
10933 (match_operand:SI 2 "arith_reg_operand" "")))
10935 (if_then_else (ne (reg:SI T_REG)
10937 (label_ref (match_operand 3 "" ""))
10942 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10943 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10944 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10945 (define_insn "casesi_worker_0"
10946 [(set (match_operand:SI 0 "register_operand" "=r,r")
10947 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10948 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10949 (clobber (match_scratch:SI 3 "=X,1"))
10950 (clobber (match_scratch:SI 4 "=&z,z"))]
10955 [(set (match_operand:SI 0 "register_operand" "")
10956 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10957 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10958 (clobber (match_scratch:SI 3 ""))
10959 (clobber (match_scratch:SI 4 ""))]
10960 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10961 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10962 (parallel [(set (match_dup 0)
10963 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10964 (label_ref (match_dup 2))] UNSPEC_CASESI))
10965 (clobber (match_dup 3))])
10966 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10968 if (GET_CODE (operands[2]) == CODE_LABEL)
10969 LABEL_NUSES (operands[2])++;
10973 [(set (match_operand:SI 0 "register_operand" "")
10974 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10975 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10976 (clobber (match_scratch:SI 3 ""))
10977 (clobber (match_scratch:SI 4 ""))]
10978 "TARGET_SH2 && reload_completed"
10979 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10980 (parallel [(set (match_dup 0)
10981 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10982 (label_ref (match_dup 2))] UNSPEC_CASESI))
10983 (clobber (match_dup 3))])]
10985 if (GET_CODE (operands[2]) == CODE_LABEL)
10986 LABEL_NUSES (operands[2])++;
10989 (define_insn "casesi_worker_1"
10990 [(set (match_operand:SI 0 "register_operand" "=r,r")
10991 (unspec:SI [(reg:SI R0_REG)
10992 (match_operand:SI 1 "register_operand" "0,r")
10993 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10994 (clobber (match_scratch:SI 3 "=X,1"))]
10997 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
10999 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11001 switch (GET_MODE (diff_vec))
11004 return "shll2 %1" "\n"
11005 " mov.l @(r0,%1),%0";
11007 return "add %1,%1" "\n"
11008 " mov.w @(r0,%1),%0";
11010 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11011 return "mov.b @(r0,%1),%0" "\n"
11014 return "mov.b @(r0,%1),%0";
11017 gcc_unreachable ();
11020 [(set_attr "length" "4")])
11022 (define_insn "casesi_worker_2"
11023 [(set (match_operand:SI 0 "register_operand" "=r,r")
11024 (unspec:SI [(reg:SI R0_REG)
11025 (match_operand:SI 1 "register_operand" "0,r")
11026 (label_ref (match_operand 2 "" ""))
11027 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
11028 (clobber (match_operand:SI 4 "" "=X,1"))]
11029 "TARGET_SH2 && reload_completed && flag_pic"
11031 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
11032 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11034 switch (GET_MODE (diff_vec))
11037 return "shll2 %1" "\n"
11039 " mova %O3,r0" "\n"
11040 " mov.l @(r0,%1),%0";
11042 return "add %1,%1" "\n"
11044 " mova %O3,r0" "\n"
11045 " mov.w @(r0,%1),%0";
11047 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11048 return "add r0,%1" "\n"
11049 " mova %O3,r0" "\n"
11050 " mov.b @(r0,%1),%0" "\n"
11053 return "add r0,%1" "\n"
11054 " mova %O3,r0" "\n"
11055 " mov.b @(r0,%1),%0";
11057 gcc_unreachable ();
11060 [(set_attr "length" "8")])
11062 (define_insn "casesi_shift_media"
11063 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11064 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
11065 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
11069 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
11071 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11073 switch (GET_MODE (diff_vec))
11076 return "shlli %1, 2, %0";
11078 return "shlli %1, 1, %0";
11080 if (rtx_equal_p (operands[0], operands[1]))
11082 return "add %1, r63, %0";
11084 gcc_unreachable ();
11087 [(set_attr "type" "arith_media")])
11089 (define_insn "casesi_load_media"
11090 [(set (match_operand 0 "any_arith_reg_dest" "=r")
11091 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
11092 (match_operand:DI 2 "arith_reg_operand" "r")
11093 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
11096 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[3])));
11098 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11100 switch (GET_MODE (diff_vec))
11103 return "ldx.l %1, %2, %0";
11106 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11107 return "ldx.uw %1, %2, %0";
11109 return "ldx.w %1, %2, %0";
11111 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11112 return "ldx.ub %1, %2, %0";
11113 return "ldx.b %1, %2, %0";
11115 gcc_unreachable ();
11118 [(set_attr "type" "load_media")])
11120 (define_expand "simple_return"
11122 "sh_can_use_simple_return_p ()")
11124 (define_expand "return"
11126 "reload_completed && epilogue_completed"
11128 if (TARGET_SHMEDIA)
11130 emit_jump_insn (gen_return_media ());
11134 if (TARGET_SHCOMPACT
11135 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
11137 emit_jump_insn (gen_shcompact_return_tramp ());
11142 (define_insn "*<code>_i"
11144 "TARGET_SH1 && ! (TARGET_SHCOMPACT
11145 && (crtl->args.info.call_cookie
11146 & CALL_COOKIE_RET_TRAMP (1)))
11147 && reload_completed
11148 && ! sh_cfun_trap_exit_p ()"
11150 if (TARGET_SH2A && (dbr_sequence_length () == 0)
11151 && !current_function_interrupt)
11156 [(set_attr "type" "return")
11157 (set_attr "needs_delay_slot" "yes")])
11159 ;; trapa has no delay slot.
11160 (define_insn "*return_trapa"
11162 "TARGET_SH1 && !TARGET_SHCOMPACT
11163 && reload_completed"
11165 [(set_attr "type" "return")])
11167 (define_expand "shcompact_return_tramp"
11170 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
11172 rtx reg = gen_rtx_REG (Pmode, R0_REG);
11174 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
11175 emit_jump_insn (gen_shcompact_return_tramp_i ());
11179 (define_insn "shcompact_return_tramp_i"
11180 [(parallel [(return) (use (reg:SI R0_REG))])]
11182 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
11184 [(set_attr "type" "jump_ind")
11185 (set_attr "needs_delay_slot" "yes")])
11187 (define_insn "return_media_i"
11188 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
11189 "TARGET_SHMEDIA && reload_completed"
11191 [(set_attr "type" "jump_media")])
11193 (define_insn "return_media_rte"
11195 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
11197 [(set_attr "type" "jump_media")])
11199 (define_expand "return_media"
11201 "TARGET_SHMEDIA && reload_completed"
11203 int tr_regno = sh_media_register_for_return ();
11206 if (current_function_interrupt)
11208 emit_jump_insn (gen_return_media_rte ());
11213 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
11215 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
11216 tr_regno = TR0_REG;
11217 tr = gen_rtx_REG (Pmode, tr_regno);
11218 emit_move_insn (tr, r18);
11221 tr = gen_rtx_REG (Pmode, tr_regno);
11223 emit_jump_insn (gen_return_media_i (tr));
11227 (define_insn "shcompact_preserve_incoming_args"
11228 [(set (match_operand:SI 0 "register_operand" "+r")
11229 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
11232 [(set_attr "length" "0")])
11234 (define_insn "shcompact_incoming_args"
11235 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
11236 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
11237 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
11238 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
11239 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
11240 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
11241 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
11242 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
11243 (set (mem:BLK (reg:SI MACL_REG))
11244 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
11245 (use (reg:SI R0_REG))
11246 (clobber (reg:SI R0_REG))
11247 (clobber (reg:SI MACL_REG))
11248 (clobber (reg:SI MACH_REG))
11249 (clobber (reg:SI PR_REG))]
11252 [(set_attr "needs_delay_slot" "yes")])
11254 (define_insn "shmedia_save_restore_regs_compact"
11255 [(set (reg:SI SP_REG)
11256 (plus:SI (reg:SI SP_REG)
11257 (match_operand:SI 0 "immediate_operand" "i")))
11258 (use (reg:SI R0_REG))
11259 (clobber (reg:SI PR_REG))]
11261 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
11262 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
11264 [(set_attr "needs_delay_slot" "yes")])
11266 (define_expand "prologue"
11270 sh_expand_prologue ();
11274 (define_expand "epilogue"
11278 sh_expand_epilogue (false);
11280 || (TARGET_SHCOMPACT
11281 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11283 emit_jump_insn (gen_return ());
11288 (define_expand "eh_return"
11289 [(use (match_operand 0 "register_operand" ""))]
11292 rtx ra = operands[0];
11294 if (TARGET_SHMEDIA64)
11295 emit_insn (gen_eh_set_ra_di (ra));
11297 emit_insn (gen_eh_set_ra_si (ra));
11302 ;; Clobber the return address on the stack. We can't expand this
11303 ;; until we know where it will be put in the stack frame.
11305 (define_insn "eh_set_ra_si"
11306 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11308 (clobber (match_scratch:SI 1 "=&r"))]
11309 "! TARGET_SHMEDIA64"
11312 (define_insn "eh_set_ra_di"
11313 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11315 (clobber (match_scratch:DI 1 "=&r"))]
11320 [(unspec_volatile [(match_operand 0 "register_operand" "")]
11322 (clobber (match_scratch 1 ""))]
11326 sh_set_return_address (operands[0], operands[1]);
11330 (define_insn "blockage"
11331 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11334 [(set_attr "length" "0")])
11336 ;; Define movml instructions for SH2A target. Currently they are
11337 ;; used to push and pop all banked registers only.
11339 (define_insn "movml_push_banked"
11340 [(set (match_operand:SI 0 "register_operand" "=r")
11341 (plus (match_dup 0) (const_int -32)))
11342 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11343 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11344 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11345 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11346 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11347 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11348 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11349 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11350 "TARGET_SH2A && REGNO (operands[0]) == 15"
11352 [(set_attr "in_delay_slot" "no")])
11354 (define_insn "movml_pop_banked"
11355 [(set (match_operand:SI 0 "register_operand" "=r")
11356 (plus (match_dup 0) (const_int 32)))
11357 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11358 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11359 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11360 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11361 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11362 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11363 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11364 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11365 "TARGET_SH2A && REGNO (operands[0]) == 15"
11367 [(set_attr "in_delay_slot" "no")])
11369 ;; ------------------------------------------------------------------------
11370 ;; Scc instructions
11371 ;; ------------------------------------------------------------------------
11373 (define_insn "movt"
11374 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11375 (match_operand:SI 1 "t_reg_operand"))]
11378 [(set_attr "type" "arith")])
11380 (define_insn "movrt"
11381 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11382 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11385 [(set_attr "type" "arith")])
11387 (define_expand "cstore4_media"
11388 [(set (match_operand:SI 0 "register_operand" "=r")
11389 (match_operator:SI 1 "sh_float_comparison_operator"
11390 [(match_operand 2 "logical_operand" "")
11391 (match_operand 3 "cmp_operand" "")]))]
11394 machine_mode mode = GET_MODE (operands[2]);
11395 enum rtx_code code = GET_CODE (operands[1]);
11397 if (mode == VOIDmode)
11398 mode = GET_MODE (operands[3]);
11399 if (operands[2] == const0_rtx)
11401 if (code == EQ || code == NE)
11402 operands[2] = operands[3], operands[3] = const0_rtx;
11405 operands[2] = force_reg (mode, operands[2]);
11406 if (operands[3] != const0_rtx)
11407 operands[3] = force_reg (mode, operands[3]);
11413 swap = invert = !FLOAT_MODE_P (mode);
11418 swap = FLOAT_MODE_P (mode), invert = !swap;
11423 swap = true, invert = false;
11430 swap = invert = false;
11434 swap = invert = true;
11438 gcc_unreachable ();
11443 std::swap (operands[2], operands[3]);
11444 code = swap_condition (code);
11449 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11450 code = reverse_condition (code);
11451 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11452 emit_insn (gen_cstore4_media (tem, operands[1],
11453 operands[2], operands[3]));
11456 operands[3] = const0_rtx;
11459 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11462 (define_expand "cstoresi4"
11463 [(set (match_operand:SI 0 "register_operand" "=r")
11464 (match_operator:SI 1 "comparison_operator"
11465 [(match_operand:SI 2 "cmpsi_operand" "")
11466 (match_operand:SI 3 "arith_operand" "")]))]
11467 "TARGET_SH1 || TARGET_SHMEDIA"
11469 if (TARGET_SHMEDIA)
11471 emit_insn (gen_cstore4_media (operands[0], operands[1],
11472 operands[2], operands[3]));
11476 if (sh_expand_t_scc (operands))
11479 if (! currently_expanding_to_rtl)
11482 sh_emit_compare_and_set (operands, SImode);
11486 (define_expand "cstoredi4"
11487 [(set (match_operand:SI 0 "register_operand" "=r")
11488 (match_operator:SI 1 "comparison_operator"
11489 [(match_operand:DI 2 "arith_operand" "")
11490 (match_operand:DI 3 "arith_operand" "")]))]
11491 "TARGET_SH2 || TARGET_SHMEDIA"
11493 if (TARGET_SHMEDIA)
11495 emit_insn (gen_cstore4_media (operands[0], operands[1],
11496 operands[2], operands[3]));
11500 if (sh_expand_t_scc (operands))
11503 if (! currently_expanding_to_rtl)
11506 sh_emit_compare_and_set (operands, DImode);
11510 ;; Move the complement of the T reg to a reg.
11511 ;; On SH2A the movrt insn can be used.
11512 ;; On anything else than SH2A this has to be done with multiple instructions.
11513 ;; One obvious way would be:
11518 ;; However, this puts pressure on r0 in most cases and thus the following is
11524 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11525 ;; becomes a one instruction operation. Moreover, care must be taken that
11526 ;; the insn can still be combined with inverted compare and branch code
11527 ;; around it. On the other hand, if a function returns the complement of
11528 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11529 ;; lead to better code.
11530 (define_expand "movnegt"
11531 [(set (match_operand:SI 0 "arith_reg_dest" "")
11532 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11536 emit_insn (gen_movrt (operands[0], operands[1]));
11539 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11540 emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11545 (define_insn_and_split "movrt_negc"
11546 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11547 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11548 (set (reg:SI T_REG) (const_int 1))
11549 (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11555 if (sh_split_movrt_negc_to_movt_xor (curr_insn, operands))
11560 [(set_attr "type" "arith")])
11562 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11563 ;; pattern can be used by the combine pass. Using a scratch reg for the
11564 ;; -1 constant results in slightly better register allocations compared to
11565 ;; generating a pseudo reg before reload.
11566 (define_insn_and_split "*movrt_negc"
11567 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11568 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11569 (clobber (match_scratch:SI 2 "=r"))
11570 (clobber (reg:SI T_REG))]
11571 "TARGET_SH1 && ! TARGET_SH2A"
11576 if (sh_split_movrt_negc_to_movt_xor (curr_insn, operands))
11578 else if (reload_completed)
11580 emit_move_insn (operands[2], gen_int_mode (-1, SImode));
11581 emit_insn (gen_movrt_negc (operands[0], operands[1], operands[2]));
11588 ;; Store the negated T bit in a reg using r0 and xor. This one doesn't
11589 ;; clobber the T bit, which is useful when storing the T bit and the
11590 ;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
11591 ;; Usually we don't want this insn to be matched, except for cases where the
11592 ;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
11593 (define_insn_and_split "movrt_xor"
11594 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11595 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11596 (use (reg:SI T_REG))]
11599 "&& reload_completed"
11600 [(set (match_dup 0) (reg:SI T_REG))
11601 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11603 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11604 ;; T = 0: 0x80000000 -> reg
11605 ;; T = 1: 0x7FFFFFFF -> reg
11606 ;; This works because 0 - 0x80000000 = 0x80000000.
11608 ;; This insn must not match again after it has been split into the constant
11609 ;; load and negc. This is accomplished by the special negc insn that
11610 ;; has a use on the operand.
11611 (define_insn_and_split "*mov_t_msb_neg"
11612 [(set (match_operand:SI 0 "arith_reg_dest")
11613 (minus:SI (const_int -2147483648) ;; 0x80000000
11614 (match_operand 1 "t_reg_operand")))
11615 (clobber (reg:SI T_REG))]
11618 "&& can_create_pseudo_p ()"
11619 [(set (match_dup 2) (const_int -2147483648))
11620 (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11622 (clobber (reg:SI T_REG))
11623 (use (match_dup 2))])]
11625 operands[2] = gen_reg_rtx (SImode);
11628 (define_insn "*mov_t_msb_neg_negc"
11629 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11630 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
11631 (match_operand:SI 2 "t_reg_operand")))
11632 (clobber (reg:SI T_REG))
11633 (use (match_dup 1))]
11636 [(set_attr "type" "arith")])
11638 (define_insn_and_split "*mov_t_msb_neg"
11639 [(set (match_operand:SI 0 "arith_reg_dest")
11640 (plus:SI (match_operand 1 "negt_reg_operand")
11641 (const_int 2147483647))) ;; 0x7fffffff
11642 (clobber (reg:SI T_REG))]
11645 "&& can_create_pseudo_p ()"
11646 [(parallel [(set (match_dup 0)
11647 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11648 (clobber (reg:SI T_REG))])])
11650 (define_insn_and_split "*mov_t_msb_neg"
11651 [(set (match_operand:SI 0 "arith_reg_dest")
11652 (if_then_else:SI (match_operand 1 "t_reg_operand")
11653 (const_int 2147483647) ;; 0x7fffffff
11654 (const_int -2147483648))) ;; 0x80000000
11655 (clobber (reg:SI T_REG))]
11658 "&& can_create_pseudo_p ()"
11659 [(parallel [(set (match_dup 0)
11660 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11661 (clobber (reg:SI T_REG))])])
11663 ;; The *negnegt pattern helps the combine pass to figure out how to fold
11664 ;; an explicit double T bit negation.
11665 (define_insn_and_split "*negnegt"
11666 [(set (reg:SI T_REG)
11667 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11673 ;; Store T bit as all zeros or ones in a reg.
11674 (define_insn "mov_neg_si_t"
11675 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11676 (neg:SI (match_operand 1 "t_reg_operand" "")))]
11679 [(set_attr "type" "arith")])
11681 ;; Store negated T bit as all zeros or ones in a reg.
11682 ;; Use the following sequence:
11683 ;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
11684 ;; not Rn,Rn ! Rn = 0 - Rn
11686 [(set (match_operand:SI 0 "arith_reg_dest" "")
11687 (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11689 [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11690 (set (match_dup 0) (not:SI (match_dup 0)))])
11692 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11693 (define_insn_and_split "*movtt"
11694 [(set (reg:SI T_REG)
11695 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11701 ;; Invert the T bit.
11702 ;; On SH2A we can use the nott insn. On anything else this must be done with
11703 ;; multiple insns like:
11706 ;; This requires an additional pseudo. The SH specific sh_treg_combine RTL
11707 ;; pass will look for this insn. Disallow using it if pseudos can't be
11709 (define_insn_and_split "nott"
11710 [(set (reg:SI T_REG)
11711 (xor:SI (match_operand:SI 0 "t_reg_operand") (const_int 1)))]
11712 "TARGET_SH2A || (TARGET_SH1 && can_create_pseudo_p ())"
11714 gcc_assert (TARGET_SH2A);
11717 "! TARGET_SH2A && can_create_pseudo_p ()"
11718 [(set (match_dup 0) (reg:SI T_REG))
11719 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11721 operands[0] = gen_reg_rtx (SImode);
11724 ;; Store T bit as MSB in a reg.
11725 ;; T = 0: 0x00000000 -> reg
11726 ;; T = 1: 0x80000000 -> reg
11727 (define_insn_and_split "*movt_msb"
11728 [(set (match_operand:SI 0 "arith_reg_dest")
11729 (mult:SI (match_operand:SI 1 "t_reg_operand")
11730 (const_int -2147483648))) ;; 0xffffffff80000000
11731 (clobber (reg:SI T_REG))]
11735 [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11737 ;; Store inverted T bit as MSB in a reg.
11738 ;; T = 0: 0x80000000 -> reg
11739 ;; T = 1: 0x00000000 -> reg
11740 ;; On SH2A we can get away without clobbering the T_REG using the movrt insn.
11741 ;; On non SH2A we resort to the following sequence:
11745 ;; The T bit value will be modified during the sequence, but the rotcr insn
11746 ;; will restore its original value.
11747 (define_insn_and_split "*negt_msb"
11748 [(set (match_operand:SI 0 "arith_reg_dest")
11749 (match_operand:SI 1 "negt_reg_shl31_operand"))]
11752 "&& can_create_pseudo_p ()"
11755 rtx tmp = gen_reg_rtx (SImode);
11759 emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11760 emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11764 emit_move_insn (tmp, get_t_reg_rtx ());
11765 emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11766 emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11771 ;; The *cset_zero patterns convert optimizations such as
11772 ;; "if (test) x = 0;"
11774 ;; "x &= -(test == 0);"
11775 ;; back to conditional branch sequences if zero-displacement branches
11777 ;; FIXME: These patterns can be removed when conditional execution patterns
11778 ;; are implemented, since ifcvt will not perform these optimizations if
11779 ;; conditional execution is supported.
11780 (define_insn "*cset_zero"
11781 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11782 (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11784 (match_operand:SI 2 "arith_reg_operand" "0")))]
11785 "TARGET_SH1 && TARGET_ZDCBRANCH"
11787 return "bf 0f" "\n"
11791 [(set_attr "type" "arith") ;; poor approximation
11792 (set_attr "length" "4")])
11794 (define_insn "*cset_zero"
11795 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11796 (if_then_else:SI (match_operand:SI 1 "cbranch_treg_value")
11797 (match_operand:SI 2 "arith_reg_operand" "0")
11799 "TARGET_SH1 && TARGET_ZDCBRANCH"
11801 int tval = sh_eval_treg_value (operands[1]);
11803 return "bt 0f" "\n"
11806 else if (tval == false)
11807 return "bf 0f" "\n"
11811 gcc_unreachable ();
11813 [(set_attr "type" "arith") ;; poor approximation
11814 (set_attr "length" "4")])
11816 (define_expand "cstoresf4"
11817 [(set (match_operand:SI 0 "register_operand" "=r")
11818 (match_operator:SI 1 "sh_float_comparison_operator"
11819 [(match_operand:SF 2 "arith_operand" "")
11820 (match_operand:SF 3 "arith_operand" "")]))]
11821 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11823 if (TARGET_SHMEDIA)
11825 emit_insn (gen_cstore4_media (operands[0], operands[1],
11826 operands[2], operands[3]));
11830 if (! currently_expanding_to_rtl)
11833 sh_emit_compare_and_set (operands, SFmode);
11837 (define_expand "cstoredf4"
11838 [(set (match_operand:SI 0 "register_operand" "=r")
11839 (match_operator:SI 1 "sh_float_comparison_operator"
11840 [(match_operand:DF 2 "arith_operand" "")
11841 (match_operand:DF 3 "arith_operand" "")]))]
11842 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11844 if (TARGET_SHMEDIA)
11846 emit_insn (gen_cstore4_media (operands[0], operands[1],
11847 operands[2], operands[3]));
11851 if (! currently_expanding_to_rtl)
11854 sh_emit_compare_and_set (operands, DFmode);
11858 ;; -------------------------------------------------------------------------
11859 ;; Instructions to cope with inline literal tables
11860 ;; -------------------------------------------------------------------------
11862 ;; 2 byte integer in line
11863 (define_insn "consttable_2"
11864 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11865 (match_operand 1 "" "")]
11869 if (operands[1] != const0_rtx)
11870 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11873 [(set_attr "length" "2")
11874 (set_attr "in_delay_slot" "no")])
11876 ;; 4 byte integer in line
11877 (define_insn "consttable_4"
11878 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11879 (match_operand 1 "" "")]
11883 if (operands[1] != const0_rtx)
11885 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11886 mark_symbol_refs_as_used (operands[0]);
11890 [(set_attr "length" "4")
11891 (set_attr "in_delay_slot" "no")])
11893 ;; 8 byte integer in line
11894 (define_insn "consttable_8"
11895 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11896 (match_operand 1 "" "")]
11900 if (operands[1] != const0_rtx)
11901 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11904 [(set_attr "length" "8")
11905 (set_attr "in_delay_slot" "no")])
11907 ;; 4 byte floating point
11908 (define_insn "consttable_sf"
11909 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11910 (match_operand 1 "" "")]
11914 if (operands[1] != const0_rtx)
11917 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11918 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11922 [(set_attr "length" "4")
11923 (set_attr "in_delay_slot" "no")])
11925 ;; 8 byte floating point
11926 (define_insn "consttable_df"
11927 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11928 (match_operand 1 "" "")]
11932 if (operands[1] != const0_rtx)
11935 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11936 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11940 [(set_attr "length" "8")
11941 (set_attr "in_delay_slot" "no")])
11943 ;; Alignment is needed for some constant tables; it may also be added for
11944 ;; Instructions at the start of loops, or after unconditional branches.
11945 ;; ??? We would get more accurate lengths if we did instruction
11946 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11947 ;; here is too conservative.
11949 ;; align to a two byte boundary
11950 (define_expand "align_2"
11951 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11955 ;; Align to a four byte boundary.
11956 ;; align_4 and align_log are instructions for the starts of loops, or
11957 ;; after unconditional branches, which may take up extra room.
11958 (define_expand "align_4"
11959 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11963 ;; Align to a cache line boundary.
11964 (define_insn "align_log"
11965 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11968 [(set_attr "length" "0")
11969 (set_attr "in_delay_slot" "no")])
11971 ;; Emitted at the end of the literal table, used to emit the
11972 ;; 32bit branch labels if needed.
11973 (define_insn "consttable_end"
11974 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11977 return output_jump_label_table ();
11979 [(set_attr "in_delay_slot" "no")])
11981 ;; Emitted at the end of the window in the literal table.
11982 (define_insn "consttable_window_end"
11983 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11986 [(set_attr "length" "0")
11987 (set_attr "in_delay_slot" "no")])
11989 ;; -------------------------------------------------------------------------
11990 ;; Minimum / maximum operations.
11991 ;; -------------------------------------------------------------------------
11993 ;; The SH2A clips.b and clips.w insns do a signed min-max function. If smin
11994 ;; and smax standard name patterns are defined, they will be used during
11995 ;; initial expansion and combine will then be able to form the actual min-max
11997 ;; The clips.b and clips.w set the SR.CS bit if the value in the register is
11998 ;; clipped, but there is currently no way of making use of this information.
11999 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
12000 (define_expand "<code>si3"
12001 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
12002 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
12003 (match_operand 2 "const_int_operand")))
12004 (clobber (reg:SI T_REG))])]
12007 /* Force the comparison value into a register, because greater-than
12008 comparisons can work only on registers. Combine will be able to pick up
12009 the constant value from the REG_EQUAL note when trying to form a min-max
12011 operands[2] = force_reg (SImode, operands[2]);
12015 ;; smax (smin (...))
12017 ;; smin (smax (...))
12018 (define_insn_and_split "*clips"
12019 [(set (match_operand:SI 0 "arith_reg_dest")
12020 (smax:SI (smin:SI (match_operand:SI 1 "arith_reg_operand")
12021 (match_operand 2 "clips_max_const_int"))
12022 (match_operand 3 "clips_min_const_int")))]
12026 [(set (match_dup 0)
12027 (smin:SI (smax:SI (match_dup 1) (match_dup 3)) (match_dup 2)))])
12029 (define_insn "*clips"
12030 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12031 (smin:SI (smax:SI (match_operand:SI 1 "arith_reg_operand" "0")
12032 (match_operand 2 "clips_min_const_int"))
12033 (match_operand 3 "clips_max_const_int")))]
12036 if (INTVAL (operands[3]) == 127)
12037 return "clips.b %0";
12038 else if (INTVAL (operands[3]) == 32767)
12039 return "clips.w %0";
12041 gcc_unreachable ();
12043 [(set_attr "type" "arith")])
12045 ;; If the expanded smin or smax patterns were not combined, split them into
12046 ;; a compare and branch sequence, because there are no real smin or smax
12048 (define_insn_and_split "*<code>si3"
12049 [(set (match_operand:SI 0 "arith_reg_dest")
12050 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
12051 (match_operand:SI 2 "arith_reg_or_0_or_1_operand")))
12052 (clobber (reg:SI T_REG))]
12053 "TARGET_SH2A && can_create_pseudo_p ()"
12058 rtx skip_label = gen_label_rtx ();
12059 emit_move_insn (operands[0], operands[1]);
12061 rtx cmp_val = operands[2];
12062 if (satisfies_constraint_M (cmp_val))
12063 cmp_val = const0_rtx;
12065 emit_insn (gen_cmpgtsi_t (operands[0], cmp_val));
12066 emit_jump_insn (<CODE> == SMIN
12067 ? gen_branch_false (skip_label)
12068 : gen_branch_true (skip_label));
12070 emit_label_after (skip_label, emit_move_insn (operands[0], operands[2]));
12074 ;; The SH2A clipu.b and clipu.w insns can be used to implement a min function
12075 ;; with a register and a constant.
12076 ;; The clipu.b and clipu.w set the SR.CS bit if the value in the register is
12077 ;; clipped, but there is currently no way of making use of this information.
12078 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
12079 (define_expand "uminsi3"
12080 [(set (match_operand:SI 0 "arith_reg_dest")
12081 (umin:SI (match_operand:SI 1 "arith_reg_operand")
12082 (match_operand 2 "const_int_operand")))]
12085 if (INTVAL (operands[2]) == 1)
12087 emit_insn (gen_clipu_one (operands[0], operands[1]));
12090 else if (! clipu_max_const_int (operands[2], VOIDmode))
12094 (define_insn "*clipu"
12095 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12096 (umin:SI (match_operand:SI 1 "arith_reg_operand" "0")
12097 (match_operand 2 "clipu_max_const_int")))]
12100 if (INTVAL (operands[2]) == 255)
12101 return "clipu.b %0";
12102 else if (INTVAL (operands[2]) == 65535)
12103 return "clipu.w %0";
12105 gcc_unreachable ();
12107 [(set_attr "type" "arith")])
12109 (define_insn_and_split "clipu_one"
12110 [(set (match_operand:SI 0 "arith_reg_dest")
12111 (umin:SI (match_operand:SI 1 "arith_reg_operand") (const_int 1)))
12112 (clobber (reg:SI T_REG))]
12115 "&& can_create_pseudo_p ()"
12118 emit_insn (gen_cmpeqsi_t (operands[1], const0_rtx));
12119 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
12123 ;; -------------------------------------------------------------------------
12125 ;; -------------------------------------------------------------------------
12127 ;; String/block move insn.
12129 (define_expand "movmemsi"
12130 [(parallel [(set (mem:BLK (match_operand:BLK 0))
12131 (mem:BLK (match_operand:BLK 1)))
12132 (use (match_operand:SI 2 "nonmemory_operand"))
12133 (use (match_operand:SI 3 "immediate_operand"))
12134 (clobber (reg:SI PR_REG))
12135 (clobber (reg:SI R4_REG))
12136 (clobber (reg:SI R5_REG))
12137 (clobber (reg:SI R0_REG))])]
12138 "TARGET_SH1 && ! TARGET_SH5"
12140 if (expand_block_move (operands))
12146 (define_insn "block_move_real"
12147 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12148 (mem:BLK (reg:SI R5_REG)))
12149 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12150 (clobber (reg:SI PR_REG))
12151 (clobber (reg:SI R0_REG))])]
12152 "TARGET_SH1 && ! TARGET_HARD_SH4"
12154 [(set_attr "type" "sfunc")
12155 (set_attr "needs_delay_slot" "yes")])
12157 (define_insn "block_lump_real"
12158 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12159 (mem:BLK (reg:SI R5_REG)))
12160 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12161 (use (reg:SI R6_REG))
12162 (clobber (reg:SI PR_REG))
12163 (clobber (reg:SI T_REG))
12164 (clobber (reg:SI R4_REG))
12165 (clobber (reg:SI R5_REG))
12166 (clobber (reg:SI R6_REG))
12167 (clobber (reg:SI R0_REG))])]
12168 "TARGET_SH1 && ! TARGET_HARD_SH4"
12170 [(set_attr "type" "sfunc")
12171 (set_attr "needs_delay_slot" "yes")])
12173 (define_insn "block_move_real_i4"
12174 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12175 (mem:BLK (reg:SI R5_REG)))
12176 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12177 (clobber (reg:SI PR_REG))
12178 (clobber (reg:SI R0_REG))
12179 (clobber (reg:SI R1_REG))
12180 (clobber (reg:SI R2_REG))])]
12183 [(set_attr "type" "sfunc")
12184 (set_attr "needs_delay_slot" "yes")])
12186 (define_insn "block_lump_real_i4"
12187 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12188 (mem:BLK (reg:SI R5_REG)))
12189 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12190 (use (reg:SI R6_REG))
12191 (clobber (reg:SI PR_REG))
12192 (clobber (reg:SI T_REG))
12193 (clobber (reg:SI R4_REG))
12194 (clobber (reg:SI R5_REG))
12195 (clobber (reg:SI R6_REG))
12196 (clobber (reg:SI R0_REG))
12197 (clobber (reg:SI R1_REG))
12198 (clobber (reg:SI R2_REG))
12199 (clobber (reg:SI R3_REG))])]
12202 [(set_attr "type" "sfunc")
12203 (set_attr "needs_delay_slot" "yes")])
12205 ;; byte compare pattern
12207 ;; !((temp & 0xF000) && (temp & 0x0F00) && (temp & 0x00F0) && (temp & 0x000F))
12208 (define_insn "cmpstr_t"
12209 [(set (reg:SI T_REG)
12214 (xor:SI (match_operand:SI 0 "arith_reg_operand" "r")
12215 (match_operand:SI 1 "arith_reg_operand" "r"))
12216 (const_int 8) (const_int 0))
12217 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12218 (const_int 8) (const_int 8)))
12219 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12220 (const_int 8) (const_int 16)))
12221 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12222 (const_int 8) (const_int 24)))
12226 [(set_attr "type" "mt_group")])
12228 (define_expand "cmpstrsi"
12229 [(set (match_operand:SI 0 "register_operand")
12230 (compare:SI (match_operand:BLK 1 "memory_operand")
12231 (match_operand:BLK 2 "memory_operand")))
12232 (use (match_operand 3 "immediate_operand"))]
12233 "TARGET_SH1 && optimize"
12235 if (! optimize_insn_for_size_p () && sh_expand_cmpstr (operands))
12241 (define_expand "cmpstrnsi"
12242 [(set (match_operand:SI 0 "register_operand")
12243 (compare:SI (match_operand:BLK 1 "memory_operand")
12244 (match_operand:BLK 2 "memory_operand")))
12245 (use (match_operand:SI 3 "immediate_operand"))
12246 (use (match_operand:SI 4 "immediate_operand"))]
12247 "TARGET_SH1 && optimize"
12249 if (! optimize_insn_for_size_p () && sh_expand_cmpnstr (operands))
12255 (define_expand "strlensi"
12256 [(set (match_operand:SI 0 "register_operand")
12257 (unspec:SI [(match_operand:BLK 1 "memory_operand")
12258 (match_operand:SI 2 "immediate_operand")
12259 (match_operand:SI 3 "immediate_operand")]
12260 UNSPEC_BUILTIN_STRLEN))]
12261 "TARGET_SH1 && optimize"
12263 if (! optimize_insn_for_size_p () && sh_expand_strlen (operands))
12269 (define_expand "setmemqi"
12270 [(parallel [(set (match_operand:BLK 0 "memory_operand")
12271 (match_operand 2 "const_int_operand"))
12272 (use (match_operand:QI 1 "const_int_operand"))
12273 (use (match_operand:QI 3 "const_int_operand"))])]
12274 "TARGET_SH1 && optimize"
12276 if (optimize_insn_for_size_p ())
12279 sh_expand_setmem (operands);
12284 ;; -------------------------------------------------------------------------
12285 ;; Floating point instructions.
12286 ;; -------------------------------------------------------------------------
12288 ;; FIXME: For now we disallow any memory operands for fpscr loads/stores,
12289 ;; except for post-inc loads and pre-dec stores for push/pop purposes.
12290 ;; This avoids problems with reload. As a consequence, user initiated fpscr
12291 ;; stores to memory will always be ferried through a general register.
12292 ;; User initiated fpscr loads always have to undergo bit masking to preserve
12293 ;; the current fpu mode settings for the compiler generated code. Thus such
12294 ;; fpscr loads will always have to go through general registers anyways.
12295 (define_insn "lds_fpscr"
12296 [(set (reg:SI FPSCR_REG)
12297 (match_operand:SI 0 "fpscr_movsrc_operand" "r,>"))
12298 (set (reg:SI FPSCR_STAT_REG)
12299 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_STAT))
12300 (set (reg:SI FPSCR_MODES_REG)
12301 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12306 [(set_attr "type" "gp_fpscr,mem_fpscr")])
12308 ;; A move fpscr -> reg schedules like a move mac -> reg. Thus we use mac_gp
12310 (define_insn "sts_fpscr"
12311 [(set (match_operand:SI 0 "fpscr_movdst_operand" "=r,<")
12312 (reg:SI FPSCR_REG))
12313 (use (reg:SI FPSCR_STAT_REG))
12314 (use (reg:SI FPSCR_MODES_REG))]
12319 [(set_attr "type" "mac_gp,fstore")])
12321 (define_expand "set_fpscr"
12322 [(parallel [(set (reg:SI FPSCR_REG)
12323 (match_operand:SI 0 "general_operand"))
12324 (set (reg:SI FPSCR_STAT_REG)
12325 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))])]
12328 /* We have to mask out the FR, SZ and PR bits. To do that, we need to
12329 get the current FPSCR value first.
12330 (a & ~mask) | (b & mask) = a ^ ((a ^ b) & mask) */
12332 rtx mask = force_reg (SImode, GEN_INT (FPSCR_FR | FPSCR_SZ | FPSCR_PR));
12334 rtx a = force_reg (SImode, operands[0]);
12336 rtx b = gen_reg_rtx (SImode);
12337 emit_insn (gen_sts_fpscr (b));
12339 rtx a_xor_b = gen_reg_rtx (SImode);
12340 emit_insn (gen_xorsi3 (a_xor_b, a, b));
12342 rtx a_xor_b_and_mask = gen_reg_rtx (SImode);
12343 emit_insn (gen_andsi3 (a_xor_b_and_mask, a_xor_b, mask));
12345 rtx r = gen_reg_rtx (SImode);
12346 emit_insn (gen_xorsi3 (r, a_xor_b_and_mask, a));
12347 emit_insn (gen_lds_fpscr (r));
12352 ;; ??? This uses the fp unit, but has no type indicating that.
12353 ;; If we did that, this would either give a bogus latency or introduce
12354 ;; a bogus FIFO constraint.
12355 ;; Since this insn is currently only used for prologues/epilogues,
12356 ;; it is probably best to claim no function unit, which matches the
12357 ;; current setting.
12358 (define_insn "toggle_sz"
12359 [(set (reg:SI FPSCR_REG)
12360 (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_SZ)))
12361 (set (reg:SI FPSCR_MODES_REG)
12362 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12363 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12365 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
12367 ;; Toggle FPU precision PR mode.
12369 (define_insn "toggle_pr"
12370 [(set (reg:SI FPSCR_REG)
12371 (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_PR)))
12372 (set (reg:SI FPSCR_MODES_REG)
12373 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12376 [(set_attr "type" "fpscr_toggle")])
12378 (define_expand "addsf3"
12379 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12380 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand")
12381 (match_operand:SF 2 "fp_arith_reg_operand")))]
12382 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12386 emit_insn (gen_addsf3_i (operands[0], operands[1], operands[2]));
12391 (define_insn "*addsf3_media"
12392 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12393 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12394 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12395 "TARGET_SHMEDIA_FPU"
12396 "fadd.s %1, %2, %0"
12397 [(set_attr "type" "fparith_media")])
12399 (define_insn_and_split "unary_sf_op"
12400 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12405 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
12406 (match_operator:SF 2 "unary_float_operator"
12407 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12408 (parallel [(match_operand 4
12409 "const_int_operand" "n")]))]))
12410 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
12411 "TARGET_SHMEDIA_FPU"
12413 "TARGET_SHMEDIA_FPU && reload_completed"
12414 [(set (match_dup 5) (match_dup 6))]
12416 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12417 rtx op1 = gen_rtx_REG (SFmode,
12418 (true_regnum (operands[1])
12419 + (INTVAL (operands[4]) ^ endian)));
12421 operands[7] = gen_rtx_REG (SFmode,
12422 (true_regnum (operands[0])
12423 + (INTVAL (operands[3]) ^ endian)));
12424 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
12426 [(set_attr "type" "fparith_media")])
12428 (define_insn_and_split "binary_sf_op0"
12429 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12431 (match_operator:SF 3 "binary_float_operator"
12432 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12433 (parallel [(const_int 0)]))
12434 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12435 (parallel [(const_int 0)]))])
12438 (parallel [(const_int 1)]))))]
12439 "TARGET_SHMEDIA_FPU"
12441 "&& reload_completed"
12442 [(set (match_dup 4) (match_dup 5))]
12444 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12445 rtx op1 = gen_rtx_REG (SFmode,
12446 true_regnum (operands[1]) + endian);
12447 rtx op2 = gen_rtx_REG (SFmode,
12448 true_regnum (operands[2]) + endian);
12450 operands[4] = gen_rtx_REG (SFmode,
12451 true_regnum (operands[0]) + endian);
12452 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12454 [(set_attr "type" "fparith_media")])
12456 (define_insn_and_split "binary_sf_op1"
12457 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12461 (parallel [(const_int 0)]))
12462 (match_operator:SF 3 "binary_float_operator"
12463 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12464 (parallel [(const_int 1)]))
12465 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12466 (parallel [(const_int 1)]))])))]
12467 "TARGET_SHMEDIA_FPU"
12469 "&& reload_completed"
12470 [(set (match_dup 4) (match_dup 5))]
12472 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12473 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
12474 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
12476 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
12477 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12479 [(set_attr "type" "fparith_media")])
12481 (define_insn "addsf3_i"
12482 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12483 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12484 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12485 (clobber (reg:SI FPSCR_STAT_REG))
12486 (use (reg:SI FPSCR_MODES_REG))]
12489 [(set_attr "type" "fp")
12490 (set_attr "fp_mode" "single")])
12492 (define_expand "subsf3"
12493 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12494 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12495 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12496 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12500 emit_insn (gen_subsf3_i (operands[0], operands[1], operands[2]));
12505 (define_insn "*subsf3_media"
12506 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12507 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12508 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12509 "TARGET_SHMEDIA_FPU"
12510 "fsub.s %1, %2, %0"
12511 [(set_attr "type" "fparith_media")])
12513 (define_insn "subsf3_i"
12514 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12515 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12516 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12517 (clobber (reg:SI FPSCR_STAT_REG))
12518 (use (reg:SI FPSCR_MODES_REG))]
12521 [(set_attr "type" "fp")
12522 (set_attr "fp_mode" "single")])
12524 (define_expand "mulsf3"
12525 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12526 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12527 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12528 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12532 emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2]));
12537 (define_insn "*mulsf3_media"
12538 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12539 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12540 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12541 "TARGET_SHMEDIA_FPU"
12542 "fmul.s %1, %2, %0"
12543 [(set_attr "type" "fparith_media")])
12545 (define_insn "mulsf3_i"
12546 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12547 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12548 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12549 (clobber (reg:SI FPSCR_STAT_REG))
12550 (use (reg:SI FPSCR_MODES_REG))]
12553 [(set_attr "type" "fp")
12554 (set_attr "fp_mode" "single")])
12556 ;; FMA (fused multiply-add) patterns
12557 (define_expand "fmasf4"
12558 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12559 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand")
12560 (match_operand:SF 2 "fp_arith_reg_operand")
12561 (match_operand:SF 3 "fp_arith_reg_operand")))]
12562 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12566 emit_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
12572 (define_insn "fmasf4_i"
12573 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12574 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
12575 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12576 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
12577 (clobber (reg:SI FPSCR_STAT_REG))
12578 (use (reg:SI FPSCR_MODES_REG))]
12581 [(set_attr "type" "fp")
12582 (set_attr "fp_mode" "single")])
12584 (define_insn "fmasf4_media"
12585 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12586 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12587 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12588 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12589 "TARGET_SHMEDIA_FPU"
12590 "fmac.s %1, %2, %0"
12591 [(set_attr "type" "fparith_media")])
12593 ;; For some cases such as 'a * b + a' the FMA pattern is not generated by
12594 ;; previous transformations. If FMA is generally allowed, let the combine
12595 ;; pass utilize it.
12596 (define_insn_and_split "*fmasf4"
12597 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12598 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
12599 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12600 (match_operand:SF 3 "arith_reg_operand" "0")))
12601 (clobber (reg:SI FPSCR_STAT_REG))
12602 (use (reg:SI FPSCR_MODES_REG))]
12603 "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF"
12605 "&& can_create_pseudo_p ()"
12606 [(parallel [(set (match_dup 0)
12607 (fma:SF (match_dup 1) (match_dup 2) (match_dup 3)))
12608 (clobber (reg:SI FPSCR_STAT_REG))
12609 (use (reg:SI FPSCR_MODES_REG))])]
12611 /* Change 'b * a + a' into 'a * b + a'.
12612 This is better for register allocation. */
12613 if (REGNO (operands[2]) == REGNO (operands[3]))
12614 std::swap (operands[1], operands[2]);
12616 [(set_attr "type" "fp")
12617 (set_attr "fp_mode" "single")])
12619 (define_insn "*fmasf4_media"
12620 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12621 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12622 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12623 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12624 "TARGET_SHMEDIA_FPU && flag_fp_contract_mode != FP_CONTRACT_OFF"
12625 "fmac.s %1, %2, %0"
12626 [(set_attr "type" "fparith_media")])
12628 (define_expand "divsf3"
12629 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12630 (div:SF (match_operand:SF 1 "fp_arith_reg_operand")
12631 (match_operand:SF 2 "fp_arith_reg_operand")))]
12632 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12636 emit_insn (gen_divsf3_i (operands[0], operands[1], operands[2]));
12641 (define_insn "*divsf3_media"
12642 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12643 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12644 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12645 "TARGET_SHMEDIA_FPU"
12646 "fdiv.s %1, %2, %0"
12647 [(set_attr "type" "fdiv_media")])
12649 (define_insn "divsf3_i"
12650 [(set (match_operand:SF 0 "fp_arith_reg_dest" "=f")
12651 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12652 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12653 (clobber (reg:SI FPSCR_STAT_REG))
12654 (use (reg:SI FPSCR_MODES_REG))]
12657 [(set_attr "type" "fdiv")
12658 (set_attr "fp_mode" "single")])
12660 (define_insn "floatdisf2"
12661 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12662 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12663 "TARGET_SHMEDIA_FPU"
12665 [(set_attr "type" "fpconv_media")])
12667 (define_expand "floatsisf2"
12668 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12669 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
12670 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12672 if (!TARGET_SHMEDIA_FPU)
12674 emit_insn (gen_floatsisf2_i4 (operands[0], operands[1]));
12679 (define_insn "*floatsisf2_media"
12680 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12681 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12682 "TARGET_SHMEDIA_FPU"
12684 [(set_attr "type" "fpconv_media")])
12686 (define_insn "floatsisf2_i4"
12687 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12688 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
12689 (clobber (reg:SI FPSCR_STAT_REG))
12690 (use (reg:SI FPSCR_MODES_REG))]
12693 [(set_attr "type" "fp")
12694 (set_attr "fp_mode" "single")])
12696 (define_insn "fix_truncsfdi2"
12697 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12698 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12699 "TARGET_SHMEDIA_FPU"
12701 [(set_attr "type" "fpconv_media")])
12703 (define_expand "fix_truncsfsi2"
12704 [(set (match_operand:SI 0 "fpul_operand" "=y")
12705 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12706 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12708 if (!TARGET_SHMEDIA_FPU)
12710 emit_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1]));
12715 (define_insn "*fix_truncsfsi2_media"
12716 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12717 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12718 "TARGET_SHMEDIA_FPU"
12720 [(set_attr "type" "fpconv_media")])
12722 (define_insn "fix_truncsfsi2_i4"
12723 [(set (match_operand:SI 0 "fpul_operand" "=y")
12724 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12725 (clobber (reg:SI FPSCR_STAT_REG))
12726 (use (reg:SI FPSCR_MODES_REG))]
12729 [(set_attr "type" "ftrc_s")
12730 (set_attr "fp_mode" "single")])
12732 (define_insn "cmpgtsf_t"
12733 [(set (reg:SI T_REG)
12734 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12735 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12736 (clobber (reg:SI FPSCR_STAT_REG))
12737 (use (reg:SI FPSCR_MODES_REG))]
12738 "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE"
12740 [(set_attr "type" "fp_cmp")
12741 (set_attr "fp_mode" "single")])
12743 (define_insn "cmpeqsf_t"
12744 [(set (reg:SI T_REG)
12745 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12746 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12747 (clobber (reg:SI FPSCR_STAT_REG))
12748 (use (reg:SI FPSCR_MODES_REG))]
12749 "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE"
12751 [(set_attr "type" "fp_cmp")
12752 (set_attr "fp_mode" "single")])
12754 (define_insn "ieee_ccmpeqsf_t"
12755 [(set (reg:SI T_REG)
12756 (ior:SI (reg:SI T_REG)
12757 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12758 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12759 (clobber (reg:SI FPSCR_STAT_REG))
12760 (use (reg:SI FPSCR_MODES_REG))]
12761 "TARGET_IEEE && TARGET_SH2E"
12763 return output_ieee_ccmpeq (insn, operands);
12765 [(set_attr "length" "4")
12766 (set_attr "fp_mode" "single")])
12768 (define_insn "cmpeqsf_media"
12769 [(set (match_operand:SI 0 "register_operand" "=r")
12770 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12771 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12772 "TARGET_SHMEDIA_FPU"
12773 "fcmpeq.s %1, %2, %0"
12774 [(set_attr "type" "fcmp_media")])
12776 (define_insn "cmpgtsf_media"
12777 [(set (match_operand:SI 0 "register_operand" "=r")
12778 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12779 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12780 "TARGET_SHMEDIA_FPU"
12781 "fcmpgt.s %1, %2, %0"
12782 [(set_attr "type" "fcmp_media")])
12784 (define_insn "cmpgesf_media"
12785 [(set (match_operand:SI 0 "register_operand" "=r")
12786 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12787 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12788 "TARGET_SHMEDIA_FPU"
12789 "fcmpge.s %1, %2, %0"
12790 [(set_attr "type" "fcmp_media")])
12792 (define_insn "cmpunsf_media"
12793 [(set (match_operand:SI 0 "register_operand" "=r")
12794 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12795 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12796 "TARGET_SHMEDIA_FPU"
12797 "fcmpun.s %1, %2, %0"
12798 [(set_attr "type" "fcmp_media")])
12800 (define_expand "cbranchsf4"
12802 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12803 [(match_operand:SF 1 "arith_operand" "")
12804 (match_operand:SF 2 "arith_operand" "")])
12805 (match_operand 3 "" "")
12807 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12809 if (TARGET_SHMEDIA)
12810 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12813 sh_emit_compare_and_branch (operands, SFmode);
12817 (define_expand "negsf2"
12818 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12819 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand")))]
12820 "TARGET_SH2E || TARGET_SHMEDIA_FPU")
12822 (define_insn "*negsf2_media"
12823 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12824 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12825 "TARGET_SHMEDIA_FPU"
12827 [(set_attr "type" "fmove_media")])
12829 (define_insn "*negsf2_i"
12830 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12831 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))]
12834 [(set_attr "type" "fmove")])
12836 (define_expand "sqrtsf2"
12837 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12838 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12839 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12843 emit_insn (gen_sqrtsf2_i (operands[0], operands[1]));
12848 (define_insn "*sqrtsf2_media"
12849 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12850 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12851 "TARGET_SHMEDIA_FPU"
12853 [(set_attr "type" "fdiv_media")])
12855 (define_insn "sqrtsf2_i"
12856 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12857 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12858 (clobber (reg:SI FPSCR_STAT_REG))
12859 (use (reg:SI FPSCR_MODES_REG))]
12862 [(set_attr "type" "fdiv")
12863 (set_attr "fp_mode" "single")])
12865 (define_insn "rsqrtsf2"
12866 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12867 (div:SF (match_operand:SF 1 "immediate_operand" "i")
12868 (sqrt:SF (match_operand:SF 2 "fp_arith_reg_operand" "0"))))
12869 (clobber (reg:SI FPSCR_STAT_REG))
12870 (use (reg:SI FPSCR_MODES_REG))]
12871 "TARGET_FPU_ANY && TARGET_FSRRA
12872 && operands[1] == CONST1_RTX (SFmode)"
12874 [(set_attr "type" "fsrra")
12875 (set_attr "fp_mode" "single")])
12877 ;; When the sincos pattern is defined, the builtin functions sin and cos
12878 ;; will be expanded to the sincos pattern and one of the output values will
12880 (define_expand "sincossf3"
12881 [(set (match_operand:SF 0 "nonimmediate_operand")
12882 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
12883 (set (match_operand:SF 1 "nonimmediate_operand")
12884 (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
12885 "TARGET_FPU_ANY && TARGET_FSCA"
12887 rtx scaled = gen_reg_rtx (SFmode);
12888 rtx truncated = gen_reg_rtx (SImode);
12889 rtx fsca = gen_reg_rtx (V2SFmode);
12890 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12892 emit_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12893 emit_insn (gen_fix_truncsfsi2 (truncated, scaled));
12894 emit_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf ()));
12896 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
12897 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
12901 (define_insn_and_split "fsca"
12902 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12904 (unspec:SF [(mult:SF
12905 (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12906 (match_operand:SF 2 "fsca_scale_factor" "i"))
12908 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12910 (clobber (reg:SI FPSCR_STAT_REG))
12911 (use (reg:SI FPSCR_MODES_REG))]
12912 "TARGET_FPU_ANY && TARGET_FSCA"
12914 "&& !fpul_operand (operands[1], SImode)"
12917 /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12918 to a simple reg, otherwise reload will have trouble reloading the
12919 pseudo into fpul. */
12920 rtx x = XEXP (operands[1], 0);
12921 while (x != NULL_RTX && !fpul_operand (x, SImode))
12923 gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12926 gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12927 emit_insn (gen_fsca (operands[0], x, operands[2]));
12930 [(set_attr "type" "fsca")
12931 (set_attr "fp_mode" "single")])
12933 (define_expand "abssf2"
12934 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12935 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand")))]
12936 "TARGET_SH2E || TARGET_SHMEDIA_FPU")
12938 (define_insn "*abssf2_media"
12939 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12940 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12941 "TARGET_SHMEDIA_FPU"
12943 [(set_attr "type" "fmove_media")])
12945 (define_insn "*abssf2_i"
12946 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12947 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))]
12950 [(set_attr "type" "fmove")])
12952 (define_expand "adddf3"
12953 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12954 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12955 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12956 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12958 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12960 emit_insn (gen_adddf3_i (operands[0], operands[1], operands[2]));
12965 (define_insn "*adddf3_media"
12966 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12967 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12968 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12969 "TARGET_SHMEDIA_FPU"
12970 "fadd.d %1, %2, %0"
12971 [(set_attr "type" "dfparith_media")])
12973 (define_insn "adddf3_i"
12974 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12975 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12976 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12977 (clobber (reg:SI FPSCR_STAT_REG))
12978 (use (reg:SI FPSCR_MODES_REG))]
12979 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12981 [(set_attr "type" "dfp_arith")
12982 (set_attr "fp_mode" "double")])
12984 (define_expand "subdf3"
12985 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12986 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12987 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12988 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12990 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12992 emit_insn (gen_subdf3_i (operands[0], operands[1], operands[2]));
12997 (define_insn "*subdf3_media"
12998 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12999 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
13000 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13001 "TARGET_SHMEDIA_FPU"
13002 "fsub.d %1, %2, %0"
13003 [(set_attr "type" "dfparith_media")])
13005 (define_insn "subdf3_i"
13006 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13007 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
13008 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13009 (clobber (reg:SI FPSCR_STAT_REG))
13010 (use (reg:SI FPSCR_MODES_REG))]
13011 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13013 [(set_attr "type" "dfp_arith")
13014 (set_attr "fp_mode" "double")])
13016 (define_expand "muldf3"
13017 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13018 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
13019 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
13020 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13022 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13024 emit_insn (gen_muldf3_i (operands[0], operands[1], operands[2]));
13029 (define_insn "*muldf3_media"
13030 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13031 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
13032 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13033 "TARGET_SHMEDIA_FPU"
13034 "fmul.d %1, %2, %0"
13035 [(set_attr "type" "dfmul_media")])
13037 (define_insn "muldf3_i"
13038 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13039 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
13040 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13041 (clobber (reg:SI FPSCR_STAT_REG))
13042 (use (reg:SI FPSCR_MODES_REG))]
13043 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13045 [(set_attr "type" "dfp_mul")
13046 (set_attr "fp_mode" "double")])
13048 (define_expand "divdf3"
13049 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13050 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
13051 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
13052 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13054 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13056 emit_insn (gen_divdf3_i (operands[0], operands[1], operands[2]));
13061 (define_insn "*divdf3_media"
13062 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13063 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
13064 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13065 "TARGET_SHMEDIA_FPU"
13066 "fdiv.d %1, %2, %0"
13067 [(set_attr "type" "dfdiv_media")])
13069 (define_insn "divdf3_i"
13070 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13071 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
13072 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13073 (clobber (reg:SI FPSCR_STAT_REG))
13074 (use (reg:SI FPSCR_MODES_REG))]
13075 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13077 [(set_attr "type" "dfdiv")
13078 (set_attr "fp_mode" "double")])
13080 (define_insn "floatdidf2"
13081 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13082 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
13083 "TARGET_SHMEDIA_FPU"
13085 [(set_attr "type" "dfpconv_media")])
13087 (define_expand "floatsidf2"
13088 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13089 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
13090 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13092 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13094 emit_insn (gen_floatsidf2_i (operands[0], operands[1]));
13099 (define_insn "*floatsidf2_media"
13100 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13101 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
13102 "TARGET_SHMEDIA_FPU"
13104 [(set_attr "type" "dfpconv_media")])
13106 (define_insn "floatsidf2_i"
13107 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13108 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
13109 (clobber (reg:SI FPSCR_STAT_REG))
13110 (use (reg:SI FPSCR_MODES_REG))]
13111 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13113 [(set_attr "type" "dfp_conv")
13114 (set_attr "fp_mode" "double")])
13116 (define_insn "fix_truncdfdi2"
13117 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
13118 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13119 "TARGET_SHMEDIA_FPU"
13121 [(set_attr "type" "dfpconv_media")])
13123 (define_expand "fix_truncdfsi2"
13124 [(set (match_operand:SI 0 "fpul_operand" "")
13125 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13126 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13128 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13130 emit_insn (gen_fix_truncdfsi2_i (operands[0], operands[1]));
13135 (define_insn "*fix_truncdfsi2_media"
13136 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
13137 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13138 "TARGET_SHMEDIA_FPU"
13140 [(set_attr "type" "dfpconv_media")])
13142 (define_insn "fix_truncdfsi2_i"
13143 [(set (match_operand:SI 0 "fpul_operand" "=y")
13144 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13145 (clobber (reg:SI FPSCR_STAT_REG))
13146 (use (reg:SI FPSCR_MODES_REG))]
13147 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13149 [(set_attr "type" "dfp_conv")
13150 (set_attr "dfp_comp" "no")
13151 (set_attr "fp_mode" "double")])
13153 (define_insn "cmpgtdf_t"
13154 [(set (reg:SI T_REG)
13155 (gt:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13156 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13157 (clobber (reg:SI FPSCR_STAT_REG))
13158 (use (reg:SI FPSCR_MODES_REG))]
13159 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13161 [(set_attr "type" "dfp_cmp")
13162 (set_attr "fp_mode" "double")])
13164 (define_insn "cmpeqdf_t"
13165 [(set (reg:SI T_REG)
13166 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13167 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13168 (clobber (reg:SI FPSCR_STAT_REG))
13169 (use (reg:SI FPSCR_MODES_REG))]
13170 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13172 [(set_attr "type" "dfp_cmp")
13173 (set_attr "fp_mode" "double")])
13175 (define_insn "*ieee_ccmpeqdf_t"
13176 [(set (reg:SI T_REG)
13177 (ior:SI (reg:SI T_REG)
13178 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13179 (match_operand:DF 1 "fp_arith_reg_operand" "f"))))
13180 (clobber (reg:SI FPSCR_STAT_REG))
13181 (use (reg:SI FPSCR_MODES_REG))]
13182 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13184 return output_ieee_ccmpeq (insn, operands);
13186 [(set_attr "length" "4")
13187 (set_attr "fp_mode" "double")])
13189 (define_insn "cmpeqdf_media"
13190 [(set (match_operand:SI 0 "register_operand" "=r")
13191 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13192 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13193 "TARGET_SHMEDIA_FPU"
13194 "fcmpeq.d %1,%2,%0"
13195 [(set_attr "type" "fcmp_media")])
13197 (define_insn "cmpgtdf_media"
13198 [(set (match_operand:SI 0 "register_operand" "=r")
13199 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13200 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13201 "TARGET_SHMEDIA_FPU"
13202 "fcmpgt.d %1,%2,%0"
13203 [(set_attr "type" "fcmp_media")])
13205 (define_insn "cmpgedf_media"
13206 [(set (match_operand:SI 0 "register_operand" "=r")
13207 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13208 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13209 "TARGET_SHMEDIA_FPU"
13210 "fcmpge.d %1,%2,%0"
13211 [(set_attr "type" "fcmp_media")])
13213 (define_insn "cmpundf_media"
13214 [(set (match_operand:SI 0 "register_operand" "=r")
13215 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13216 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13217 "TARGET_SHMEDIA_FPU"
13218 "fcmpun.d %1,%2,%0"
13219 [(set_attr "type" "fcmp_media")])
13221 (define_expand "cbranchdf4"
13223 (if_then_else (match_operator 0 "sh_float_comparison_operator"
13224 [(match_operand:DF 1 "arith_operand" "")
13225 (match_operand:DF 2 "arith_operand" "")])
13226 (match_operand 3 "" "")
13228 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13230 if (TARGET_SHMEDIA)
13231 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
13234 sh_emit_compare_and_branch (operands, DFmode);
13238 (define_expand "negdf2"
13239 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13240 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13241 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU")
13243 (define_insn "*negdf2_media"
13244 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13245 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13246 "TARGET_SHMEDIA_FPU"
13248 [(set_attr "type" "fmove_media")])
13250 (define_insn "*negdf2_i"
13251 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13252 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))]
13253 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13255 [(set_attr "type" "fmove")])
13257 (define_expand "sqrtdf2"
13258 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13259 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13260 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13262 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13264 emit_insn (gen_sqrtdf2_i (operands[0], operands[1]));
13269 (define_insn "*sqrtdf2_media"
13270 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13271 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13272 "TARGET_SHMEDIA_FPU"
13274 [(set_attr "type" "dfdiv_media")])
13276 (define_insn "sqrtdf2_i"
13277 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13278 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
13279 (clobber (reg:SI FPSCR_STAT_REG))
13280 (use (reg:SI FPSCR_MODES_REG))]
13281 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13283 [(set_attr "type" "dfdiv")
13284 (set_attr "fp_mode" "double")])
13286 (define_expand "absdf2"
13287 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13288 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13289 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU")
13291 (define_insn "*absdf2_media"
13292 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13293 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13294 "TARGET_SHMEDIA_FPU"
13296 [(set_attr "type" "fmove_media")])
13298 (define_insn "*absdf2_i"
13299 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13300 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))]
13301 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13303 [(set_attr "type" "fmove")])
13305 (define_expand "extendsfdf2"
13306 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13307 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
13308 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13310 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13312 emit_insn (gen_extendsfdf2_i4 (operands[0], operands[1]));
13317 (define_insn "*extendsfdf2_media"
13318 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13319 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13320 "TARGET_SHMEDIA_FPU"
13322 [(set_attr "type" "dfpconv_media")])
13324 (define_insn "extendsfdf2_i4"
13325 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13326 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
13327 (clobber (reg:SI FPSCR_STAT_REG))
13328 (use (reg:SI FPSCR_MODES_REG))]
13329 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13331 [(set_attr "type" "fp")
13332 (set_attr "fp_mode" "double")])
13334 (define_expand "truncdfsf2"
13335 [(set (match_operand:SF 0 "fpul_operand" "")
13336 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13337 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13339 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13341 emit_insn (gen_truncdfsf2_i4 (operands[0], operands[1]));
13346 (define_insn "*truncdfsf2_media"
13347 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13348 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13349 "TARGET_SHMEDIA_FPU"
13351 [(set_attr "type" "dfpconv_media")])
13353 (define_insn "truncdfsf2_i4"
13354 [(set (match_operand:SF 0 "fpul_operand" "=y")
13355 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13356 (clobber (reg:SI FPSCR_STAT_REG))
13357 (use (reg:SI FPSCR_MODES_REG))]
13358 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13360 [(set_attr "type" "fp")
13361 (set_attr "fp_mode" "double")])
13363 ;; -------------------------------------------------------------------------
13364 ;; Bit field extract patterns.
13365 ;; -------------------------------------------------------------------------
13367 ;; These give better code for packed bitfields, because they allow
13368 ;; auto-increment addresses to be generated.
13370 (define_expand "insv"
13371 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
13372 (match_operand:SI 1 "immediate_operand" "")
13373 (match_operand:SI 2 "immediate_operand" ""))
13374 (match_operand:SI 3 "general_operand" ""))]
13375 "TARGET_SH1 && TARGET_BIG_ENDIAN"
13377 rtx addr_target, orig_address, shift_reg, qi_val;
13378 HOST_WIDE_INT bitsize, size, v = 0;
13379 rtx x = operands[3];
13381 if (TARGET_SH2A && TARGET_BITOPS
13382 && (satisfies_constraint_Sbw (operands[0])
13383 || satisfies_constraint_Sbv (operands[0]))
13384 && satisfies_constraint_M (operands[1])
13385 && satisfies_constraint_K03 (operands[2]))
13387 if (satisfies_constraint_N (operands[3]))
13389 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
13392 else if (satisfies_constraint_M (operands[3]))
13394 emit_insn (gen_bset_m2a (operands[0], operands[2]));
13397 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
13398 && satisfies_constraint_M (operands[1]))
13400 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13403 else if (REG_P (operands[3])
13404 && satisfies_constraint_M (operands[1]))
13406 emit_insn (gen_bld_reg (operands[3], const0_rtx));
13407 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13411 /* ??? expmed doesn't care for non-register predicates. */
13412 if (! memory_operand (operands[0], VOIDmode)
13413 || ! immediate_operand (operands[1], VOIDmode)
13414 || ! immediate_operand (operands[2], VOIDmode)
13415 || ! general_operand (x, VOIDmode))
13417 /* If this isn't a 16 / 24 / 32 bit field, or if
13418 it doesn't start on a byte boundary, then fail. */
13419 bitsize = INTVAL (operands[1]);
13420 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13421 || (INTVAL (operands[2]) % 8) != 0)
13424 size = bitsize / 8;
13425 orig_address = XEXP (operands[0], 0);
13426 shift_reg = gen_reg_rtx (SImode);
13427 if (CONST_INT_P (x))
13430 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13434 emit_insn (gen_movsi (shift_reg, operands[3]));
13435 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13437 addr_target = copy_addr_to_reg (plus_constant (Pmode,
13438 orig_address, size - 1));
13440 operands[0] = replace_equiv_address (operands[0], addr_target);
13441 emit_insn (gen_movqi (operands[0], qi_val));
13445 if (CONST_INT_P (x))
13447 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13450 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13451 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13453 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13454 emit_insn (gen_movqi (operands[0], qi_val));
13460 (define_insn "movua"
13461 [(set (match_operand:SI 0 "register_operand" "=z")
13462 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13466 [(set_attr "type" "movua")])
13468 ;; We shouldn't need this, but cse replaces increments with references
13469 ;; to other regs before flow has a chance to create post_inc
13470 ;; addressing modes, and only postreload's cse_move2add brings the
13471 ;; increments back to a usable form.
13473 [(set (match_operand:SI 0 "register_operand" "")
13474 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
13475 (const_int 32) (const_int 0)))
13476 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13477 "TARGET_SH4A && REGNO (operands[0]) != REGNO (operands[1])"
13478 [(set (match_operand:SI 0 "register_operand" "")
13479 (sign_extract:SI (mem:SI (post_inc:SI
13480 (match_operand:SI 1 "register_operand" "")))
13481 (const_int 32) (const_int 0)))]
13484 (define_expand "extv"
13485 [(set (match_operand:SI 0 "register_operand" "")
13486 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13487 (match_operand 2 "const_int_operand" "")
13488 (match_operand 3 "const_int_operand" "")))]
13489 "TARGET_SH4A || TARGET_SH2A"
13491 if (TARGET_SH2A && TARGET_BITOPS
13492 && (satisfies_constraint_Sbw (operands[1])
13493 || satisfies_constraint_Sbv (operands[1]))
13494 && satisfies_constraint_M (operands[2])
13495 && satisfies_constraint_K03 (operands[3]))
13497 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
13498 if (REGNO (operands[0]) != T_REG)
13499 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13503 && INTVAL (operands[2]) == 32
13504 && INTVAL (operands[3]) == 0
13505 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13507 rtx src = adjust_address (operands[1], BLKmode, 0);
13508 set_mem_size (src, 4);
13509 emit_insn (gen_movua (operands[0], src));
13516 (define_expand "extzv"
13517 [(set (match_operand:SI 0 "register_operand" "")
13518 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13519 (match_operand 2 "const_int_operand" "")
13520 (match_operand 3 "const_int_operand" "")))]
13521 "TARGET_SH4A || TARGET_SH2A"
13523 if (TARGET_SH2A && TARGET_BITOPS
13524 && (satisfies_constraint_Sbw (operands[1])
13525 || satisfies_constraint_Sbv (operands[1]))
13526 && satisfies_constraint_M (operands[2])
13527 && satisfies_constraint_K03 (operands[3]))
13529 emit_insn (gen_bld_m2a (operands[1], operands[3]));
13530 if (REGNO (operands[0]) != T_REG)
13531 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13535 && INTVAL (operands[2]) == 32
13536 && INTVAL (operands[3]) == 0
13537 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13539 rtx src = adjust_address (operands[1], BLKmode, 0);
13540 set_mem_size (src, 4);
13541 emit_insn (gen_movua (operands[0], src));
13548 ;; SH2A instructions for bitwise operations.
13549 ;; FIXME: Convert multiple instruction insns to insn_and_split.
13550 ;; FIXME: Use iterators to fold at least and,xor,or insn variations.
13552 ;; Clear a bit in a memory location.
13553 (define_insn "bclr_m2a"
13554 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13556 (not:QI (ashift:QI (const_int 1)
13557 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13559 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13562 bclr.b %1,@(0,%t0)"
13563 [(set_attr "length" "4,4")])
13565 (define_insn "bclrmem_m2a"
13566 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13567 (and:QI (match_dup 0)
13568 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
13569 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
13572 bclr.b %W1,@(0,%t0)"
13573 [(set_attr "length" "4,4")])
13575 ;; Set a bit in a memory location.
13576 (define_insn "bset_m2a"
13577 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13579 (ashift:QI (const_int 1)
13580 (match_operand:QI 1 "const_int_operand" "K03,K03"))
13582 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13585 bset.b %1,@(0,%t0)"
13586 [(set_attr "length" "4,4")])
13588 (define_insn "bsetmem_m2a"
13589 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13590 (ior:QI (match_dup 0)
13591 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
13592 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
13595 bset.b %V1,@(0,%t0)"
13596 [(set_attr "length" "4,4")])
13598 ;;; Transfer the contents of the T bit to a specified bit of memory.
13599 (define_insn "bst_m2a"
13600 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
13601 (if_then_else (eq (reg:SI T_REG) (const_int 0))
13603 (not:QI (ashift:QI (const_int 1)
13604 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13607 (ashift:QI (const_int 1) (match_dup 1))
13609 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13613 [(set_attr "length" "4")])
13615 ;; Store a specified bit of memory in the T bit.
13616 (define_insn "bld_m2a"
13617 [(set (reg:SI T_REG)
13619 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13621 (match_operand 1 "const_int_operand" "K03,K03")))]
13622 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13626 [(set_attr "length" "4,4")])
13628 ;; Store a specified bit of memory in the T bit.
13629 (define_insn "bldsign_m2a"
13630 [(set (reg:SI T_REG)
13632 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13634 (match_operand 1 "const_int_operand" "K03,K03")))]
13635 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13639 [(set_attr "length" "4,4")])
13641 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13642 (define_insn "bld_reg"
13643 [(set (reg:SI T_REG)
13644 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13646 (match_operand 1 "const_int_operand" "K03")))]
13647 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13650 (define_insn "*bld_regqi"
13651 [(set (reg:SI T_REG)
13652 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13654 (match_operand 1 "const_int_operand" "K03")))]
13655 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13658 ;; Take logical and of a specified bit of memory with the T bit and
13659 ;; store its result in the T bit.
13660 (define_insn "band_m2a"
13661 [(set (reg:SI T_REG)
13662 (and:SI (reg:SI T_REG)
13664 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13666 (match_operand 1 "const_int_operand" "K03,K03"))))]
13667 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13670 band.b %1,@(0,%t0)"
13671 [(set_attr "length" "4,4")])
13673 (define_insn "bandreg_m2a"
13674 [(set (match_operand:SI 0 "register_operand" "=r,r")
13675 (and:SI (zero_extract:SI
13676 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13678 (match_operand 2 "const_int_operand" "K03,K03"))
13679 (match_operand:SI 3 "register_operand" "r,r")))]
13680 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13682 static const char* alt[] =
13684 "band.b %2,%1" "\n"
13687 "band.b %2,@(0,%t1)" "\n"
13690 return alt[which_alternative];
13692 [(set_attr "length" "6,6")])
13694 ;; Take logical or of a specified bit of memory with the T bit and
13695 ;; store its result in the T bit.
13696 (define_insn "bor_m2a"
13697 [(set (reg:SI T_REG)
13698 (ior:SI (reg:SI T_REG)
13700 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13702 (match_operand 1 "const_int_operand" "K03,K03"))))]
13703 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13707 [(set_attr "length" "4,4")])
13709 (define_insn "borreg_m2a"
13710 [(set (match_operand:SI 0 "register_operand" "=r,r")
13711 (ior:SI (zero_extract:SI
13712 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13714 (match_operand 2 "const_int_operand" "K03,K03"))
13715 (match_operand:SI 3 "register_operand" "=r,r")))]
13716 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13718 static const char* alt[] =
13723 "bor.b %2,@(0,%t1)" "\n"
13726 return alt[which_alternative];
13728 [(set_attr "length" "6,6")])
13730 ;; Take exclusive or of a specified bit of memory with the T bit and
13731 ;; store its result in the T bit.
13732 (define_insn "bxor_m2a"
13733 [(set (reg:SI T_REG)
13734 (xor:SI (reg:SI T_REG)
13736 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13738 (match_operand 1 "const_int_operand" "K03,K03"))))]
13739 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13742 bxor.b %1,@(0,%t0)"
13743 [(set_attr "length" "4,4")])
13745 (define_insn "bxorreg_m2a"
13746 [(set (match_operand:SI 0 "register_operand" "=r,r")
13747 (xor:SI (zero_extract:SI
13748 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13750 (match_operand 2 "const_int_operand" "K03,K03"))
13751 (match_operand:SI 3 "register_operand" "=r,r")))]
13752 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13754 static const char* alt[] =
13756 "bxor.b %2,%1" "\n"
13759 "bxor.b %2,@(0,%t1)" "\n"
13762 return alt[which_alternative];
13764 [(set_attr "length" "6,6")])
13766 ;; -------------------------------------------------------------------------
13768 ;; -------------------------------------------------------------------------
13769 ;; This matches cases where the bit in a memory location is set.
13771 [(set (match_operand:SI 0 "register_operand")
13772 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
13774 (ior:SI (match_dup 0)
13775 (match_operand:SI 2 "const_int_operand")))
13777 (match_operand 3 "arith_reg_operand"))]
13778 "TARGET_SH2A && TARGET_BITOPS
13779 && satisfies_constraint_Pso (operands[2])
13780 && REGNO (operands[0]) == REGNO (operands[3])"
13781 [(set (match_dup 1)
13782 (ior:QI (match_dup 1) (match_dup 2)))]
13785 ;; This matches cases where the bit in a memory location is cleared.
13787 [(set (match_operand:SI 0 "register_operand")
13788 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
13790 (and:SI (match_dup 0)
13791 (match_operand:SI 2 "const_int_operand")))
13793 (match_operand 3 "arith_reg_operand"))]
13794 "TARGET_SH2A && TARGET_BITOPS
13795 && satisfies_constraint_Psz (operands[2])
13796 && REGNO (operands[0]) == REGNO (operands[3])"
13797 [(set (match_dup 1)
13798 (and:QI (match_dup 1) (match_dup 2)))]
13801 ;; This matches cases where a stack pointer increment at the start of the
13802 ;; epilogue combines with a stack slot read loading the return value.
13804 [(set (match_operand:SI 0 "arith_reg_operand" "")
13805 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13806 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13807 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13810 ;; See the comment on the dt combiner pattern above.
13812 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13813 (plus:SI (match_dup 0)
13815 (set (reg:SI T_REG)
13816 (eq:SI (match_dup 0) (const_int 0)))]
13820 ;; The following peepholes fold load sequences for which reload was not
13821 ;; able to generate a displacement addressing move insn.
13822 ;; This can happen when reload has to transform a move insn
13823 ;; without displacement into one with displacement. Or when reload can't
13824 ;; fit a displacement into the insn's constraints. In the latter case, the
13825 ;; load destination reg remains at r0, which reload compensates by inserting
13826 ;; another mov insn.
13830 ;; mov.{b,w} @(r0,r15),r0
13833 ;; mov.{b,w} @(54,r15),r3
13836 [(set (match_operand:SI 0 "arith_reg_dest" "")
13837 (match_operand:SI 1 "const_int_operand" ""))
13838 (set (match_operand:SI 2 "arith_reg_dest" "")
13840 (mem:QI (plus:SI (match_dup 0)
13841 (match_operand:SI 3 "arith_reg_operand" "")))))
13842 (set (match_operand:QI 4 "arith_reg_dest" "")
13843 (match_operand:QI 5 "arith_reg_operand" ""))]
13845 && sh_legitimate_index_p (QImode, operands[1], true, true)
13846 && REGNO (operands[2]) == REGNO (operands[5])
13847 && peep2_reg_dead_p (3, operands[5])"
13848 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13852 [(set (match_operand:SI 0 "arith_reg_dest" "")
13853 (match_operand:SI 1 "const_int_operand" ""))
13854 (set (match_operand:SI 2 "arith_reg_dest" "")
13856 (mem:HI (plus:SI (match_dup 0)
13857 (match_operand:SI 3 "arith_reg_operand" "")))))
13858 (set (match_operand:HI 4 "arith_reg_dest" "")
13859 (match_operand:HI 5 "arith_reg_operand" ""))]
13861 && sh_legitimate_index_p (HImode, operands[1], true, true)
13862 && REGNO (operands[2]) == REGNO (operands[5])
13863 && peep2_reg_dead_p (3, operands[5])"
13864 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13869 ;; mov.{b,w} @(r0,r15),r1
13871 ;; mov.{b,w} @(54,r15),r1
13874 [(set (match_operand:SI 0 "arith_reg_dest" "")
13875 (match_operand:SI 1 "const_int_operand" ""))
13876 (set (match_operand:SI 2 "arith_reg_dest" "")
13878 (mem:QI (plus:SI (match_dup 0)
13879 (match_operand:SI 3 "arith_reg_operand" "")))))]
13881 && sh_legitimate_index_p (QImode, operands[1], true, true)
13882 && (peep2_reg_dead_p (2, operands[0])
13883 || REGNO (operands[0]) == REGNO (operands[2]))"
13884 [(set (match_dup 2)
13885 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13889 [(set (match_operand:SI 0 "arith_reg_dest" "")
13890 (match_operand:SI 1 "const_int_operand" ""))
13891 (set (match_operand:SI 2 "arith_reg_dest" "")
13893 (mem:HI (plus:SI (match_dup 0)
13894 (match_operand:SI 3 "arith_reg_operand" "")))))]
13896 && sh_legitimate_index_p (HImode, operands[1], true, true)
13897 && (peep2_reg_dead_p (2, operands[0])
13898 || REGNO (operands[0]) == REGNO (operands[2]))"
13899 [(set (match_dup 2)
13900 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13904 ;; mov.{b,w} @(r0,r15),r0
13907 ;; mov.{b,w} @(r0,r15),r3
13909 ;; This can happen when initially a displacement address is picked, where
13910 ;; the destination reg is fixed to r0, and then the address is transformed
13911 ;; into 'r0 + reg'.
13913 [(set (match_operand:SI 0 "arith_reg_dest" "")
13915 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13916 (match_operand:SI 2 "arith_reg_operand" "")))))
13917 (set (match_operand:QI 3 "arith_reg_dest" "")
13918 (match_operand:QI 4 "arith_reg_operand" ""))]
13920 && REGNO (operands[0]) == REGNO (operands[4])
13921 && peep2_reg_dead_p (2, operands[0])"
13922 [(set (match_dup 3)
13923 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13927 [(set (match_operand:SI 0 "arith_reg_dest" "")
13929 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13930 (match_operand:SI 2 "arith_reg_operand" "")))))
13931 (set (match_operand:HI 3 "arith_reg_dest" "")
13932 (match_operand:HI 4 "arith_reg_operand" ""))]
13934 && REGNO (operands[0]) == REGNO (operands[4])
13935 && peep2_reg_dead_p (2, operands[0])"
13936 [(set (match_dup 3)
13937 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13941 [(set (match_operand:SI 0 "register_operand" "=r")
13942 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13943 (set (mem:SF (match_dup 0))
13944 (match_operand:SF 2 "general_movsrc_operand" ""))]
13945 "TARGET_SH1 && REGNO (operands[0]) == 0
13946 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13947 || (GET_CODE (operands[2]) == SUBREG
13948 && REGNO (SUBREG_REG (operands[2])) < 16))
13949 && reg_unused_after (operands[0], insn)"
13950 "mov.l %2,@(%0,%1)")
13953 [(set (match_operand:SI 0 "register_operand" "=r")
13954 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13955 (set (match_operand:SF 2 "general_movdst_operand" "")
13957 (mem:SF (match_dup 0)))]
13958 "TARGET_SH1 && REGNO (operands[0]) == 0
13959 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13960 || (GET_CODE (operands[2]) == SUBREG
13961 && REGNO (SUBREG_REG (operands[2])) < 16))
13962 && reg_unused_after (operands[0], insn)"
13963 "mov.l @(%0,%1),%2")
13966 [(set (match_operand:SI 0 "register_operand" "=r")
13967 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13968 (set (mem:SF (match_dup 0))
13969 (match_operand:SF 2 "general_movsrc_operand" ""))]
13970 "TARGET_SH2E && REGNO (operands[0]) == 0
13971 && ((REG_P (operands[2])
13972 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13973 || (GET_CODE (operands[2]) == SUBREG
13974 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13975 && reg_unused_after (operands[0], insn)"
13976 "fmov{.s|} %2,@(%0,%1)")
13979 [(set (match_operand:SI 0 "register_operand" "=r")
13980 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13981 (set (match_operand:SF 2 "general_movdst_operand" "")
13983 (mem:SF (match_dup 0)))]
13984 "TARGET_SH2E && REGNO (operands[0]) == 0
13985 && ((REG_P (operands[2])
13986 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13987 || (GET_CODE (operands[2]) == SUBREG
13988 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13989 && reg_unused_after (operands[0], insn)"
13990 "fmov{.s|} @(%0,%1),%2")
13992 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13993 (define_insn "sp_switch_1"
13994 [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
13995 UNSPECV_SP_SWITCH_B))]
13998 return "mov.l r0,@-r15" "\n"
13999 " mov.l %0,r0" "\n"
14000 " mov.l @r0,r0" "\n"
14001 " mov.l r15,@-r0" "\n"
14004 [(set_attr "length" "10")])
14006 ;; Switch back to the original stack for interrupt functions with the
14007 ;; sp_switch attribute.
14008 (define_insn "sp_switch_2"
14009 [(unspec_volatile [(const_int 0)]
14010 UNSPECV_SP_SWITCH_E)]
14013 return "mov.l @r15,r15" "\n"
14016 [(set_attr "length" "4")])
14018 ;; -------------------------------------------------------------------------
14019 ;; Integer vector moves
14020 ;; -------------------------------------------------------------------------
14022 (define_expand "movv8qi"
14023 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
14024 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
14027 prepare_move_operands (operands, V8QImode);
14030 (define_insn "movv8qi_i"
14031 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
14032 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14034 && (register_operand (operands[0], V8QImode)
14035 || sh_register_operand (operands[1], V8QImode))"
14042 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14043 (set_attr "length" "4,4,16,4,4")])
14046 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
14047 (subreg:V8QI (const_int 0) 0))]
14049 [(set (match_dup 0)
14050 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
14051 (const_int 0) (const_int 0) (const_int 0)
14052 (const_int 0) (const_int 0)]))])
14055 [(set (match_operand 0 "arith_reg_dest" "")
14056 (match_operand 1 "sh_rep_vec" ""))]
14057 "TARGET_SHMEDIA && reload_completed
14058 && GET_MODE (operands[0]) == GET_MODE (operands[1])
14059 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
14060 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
14061 && (XVECEXP (operands[1], 0, 0) != const0_rtx
14062 || XVECEXP (operands[1], 0, 1) != const0_rtx)
14063 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
14064 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
14065 [(set (match_dup 0) (match_dup 1))
14068 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
14069 rtx elt1 = XVECEXP (operands[1], 0, 1);
14072 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
14076 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
14077 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
14079 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
14080 operands[1] = XVECEXP (operands[1], 0, 0);
14083 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
14085 = GEN_INT (TARGET_LITTLE_ENDIAN
14086 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
14087 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
14090 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
14092 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
14098 [(set (match_operand 0 "arith_reg_dest" "")
14099 (match_operand 1 "sh_const_vec" ""))]
14100 "TARGET_SHMEDIA && reload_completed
14101 && GET_MODE (operands[0]) == GET_MODE (operands[1])
14102 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
14103 [(set (match_dup 0) (match_dup 1))]
14105 rtx v = operands[1];
14106 machine_mode new_mode
14107 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
14109 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
14111 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
14114 (define_expand "movv2hi"
14115 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
14116 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
14119 prepare_move_operands (operands, V2HImode);
14122 (define_insn "movv2hi_i"
14123 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
14124 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14126 && (register_operand (operands[0], V2HImode)
14127 || sh_register_operand (operands[1], V2HImode))"
14134 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14135 (set_attr "length" "4,4,16,4,4")
14136 (set (attr "highpart")
14137 (cond [(match_test "sh_contains_memref_p (insn)")
14138 (const_string "user")]
14139 (const_string "ignore")))])
14141 (define_expand "movv4hi"
14142 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
14143 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
14146 prepare_move_operands (operands, V4HImode);
14149 (define_insn "movv4hi_i"
14150 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
14151 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14153 && (register_operand (operands[0], V4HImode)
14154 || sh_register_operand (operands[1], V4HImode))"
14161 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14162 (set_attr "length" "4,4,16,4,4")
14163 (set_attr "highpart" "depend")])
14165 (define_expand "movv2si"
14166 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
14167 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
14170 prepare_move_operands (operands, V2SImode);
14173 (define_insn "movv2si_i"
14174 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
14175 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14177 && (register_operand (operands[0], V2SImode)
14178 || sh_register_operand (operands[1], V2SImode))"
14185 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14186 (set_attr "length" "4,4,16,4,4")
14187 (set_attr "highpart" "depend")])
14189 ;; -------------------------------------------------------------------------
14190 ;; Multimedia Intrinsics
14191 ;; -------------------------------------------------------------------------
14193 (define_insn "absv2si2"
14194 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14195 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
14198 [(set_attr "type" "mcmp_media")
14199 (set_attr "highpart" "depend")])
14201 (define_insn "absv4hi2"
14202 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14203 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
14206 [(set_attr "type" "mcmp_media")
14207 (set_attr "highpart" "depend")])
14209 (define_insn "addv2si3"
14210 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14211 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
14212 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14214 "madd.l %1, %2, %0"
14215 [(set_attr "type" "arith_media")
14216 (set_attr "highpart" "depend")])
14218 (define_insn "addv4hi3"
14219 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14220 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
14221 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14223 "madd.w %1, %2, %0"
14224 [(set_attr "type" "arith_media")
14225 (set_attr "highpart" "depend")])
14227 (define_insn_and_split "addv2hi3"
14228 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14229 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
14230 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
14236 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14237 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14238 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14239 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14240 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14242 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
14243 emit_insn (gen_truncdisi2 (si_dst, di_dst));
14246 [(set_attr "highpart" "must_split")])
14248 (define_insn "ssaddv2si3"
14249 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14250 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
14251 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14253 "madds.l %1, %2, %0"
14254 [(set_attr "type" "mcmp_media")
14255 (set_attr "highpart" "depend")])
14257 (define_insn "usaddv8qi3"
14258 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14259 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
14260 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14262 "madds.ub %1, %2, %0"
14263 [(set_attr "type" "mcmp_media")
14264 (set_attr "highpart" "depend")])
14266 (define_insn "ssaddv4hi3"
14267 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14268 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
14269 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14271 "madds.w %1, %2, %0"
14272 [(set_attr "type" "mcmp_media")
14273 (set_attr "highpart" "depend")])
14275 (define_insn "negcmpeqv8qi"
14276 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14278 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
14279 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
14281 "mcmpeq.b %N1, %N2, %0"
14282 [(set_attr "type" "mcmp_media")
14283 (set_attr "highpart" "depend")])
14285 (define_insn "negcmpeqv2si"
14286 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14288 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
14289 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14291 "mcmpeq.l %N1, %N2, %0"
14292 [(set_attr "type" "mcmp_media")
14293 (set_attr "highpart" "depend")])
14295 (define_insn "negcmpeqv4hi"
14296 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14298 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
14299 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14301 "mcmpeq.w %N1, %N2, %0"
14302 [(set_attr "type" "mcmp_media")
14303 (set_attr "highpart" "depend")])
14305 (define_insn "negcmpgtuv8qi"
14306 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14307 (neg:V8QI (gtu:V8QI
14308 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
14309 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
14311 "mcmpgt.ub %N1, %N2, %0"
14312 [(set_attr "type" "mcmp_media")
14313 (set_attr "highpart" "depend")])
14315 (define_insn "negcmpgtv2si"
14316 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14318 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
14319 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14321 "mcmpgt.l %N1, %N2, %0"
14322 [(set_attr "type" "mcmp_media")
14323 (set_attr "highpart" "depend")])
14325 (define_insn "negcmpgtv4hi"
14326 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14328 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
14329 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14331 "mcmpgt.w %N1, %N2, %0"
14332 [(set_attr "type" "mcmp_media")
14333 (set_attr "highpart" "depend")])
14335 (define_insn "mcmv"
14336 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14337 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14338 (match_operand:DI 2 "arith_reg_operand" "r"))
14339 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
14340 (not:DI (match_dup 2)))))]
14343 [(set_attr "type" "arith_media")
14344 (set_attr "highpart" "depend")])
14346 (define_insn "mcnvs_lw"
14347 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14349 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
14351 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14353 "mcnvs.lw %N1, %N2, %0"
14354 [(set_attr "type" "mcmp_media")])
14356 (define_insn "mcnvs_wb"
14357 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14359 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14361 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14363 "mcnvs.wb %N1, %N2, %0"
14364 [(set_attr "type" "mcmp_media")])
14366 (define_insn "mcnvs_wub"
14367 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14369 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14371 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14373 "mcnvs.wub %N1, %N2, %0"
14374 [(set_attr "type" "mcmp_media")])
14376 (define_insn "mextr_rl"
14377 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14378 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14379 (match_operand:HI 3 "mextr_bit_offset" "i"))
14380 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14381 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14382 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14384 static char templ[21];
14385 sprintf (templ, "mextr%d %%N1, %%N2, %%0",
14386 (int) INTVAL (operands[3]) >> 3);
14389 [(set_attr "type" "arith_media")])
14391 (define_insn "*mextr_lr"
14392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14393 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14394 (match_operand:HI 3 "mextr_bit_offset" "i"))
14395 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14396 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14397 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14399 static char templ[21];
14400 sprintf (templ, "mextr%d %%N2, %%N1, %%0",
14401 (int) INTVAL (operands[4]) >> 3);
14404 [(set_attr "type" "arith_media")])
14406 ; mextrN can be modelled with vec_select / vec_concat, but the selection
14407 ; vector then varies depending on endianness.
14408 (define_expand "mextr1"
14409 [(match_operand:DI 0 "arith_reg_dest" "")
14410 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14411 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14414 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14415 GEN_INT (1 * 8), GEN_INT (7 * 8)));
14419 (define_expand "mextr2"
14420 [(match_operand:DI 0 "arith_reg_dest" "")
14421 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14422 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14425 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14426 GEN_INT (2 * 8), GEN_INT (6 * 8)));
14430 (define_expand "mextr3"
14431 [(match_operand:DI 0 "arith_reg_dest" "")
14432 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14433 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14436 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14437 GEN_INT (3 * 8), GEN_INT (5 * 8)));
14441 (define_expand "mextr4"
14442 [(match_operand:DI 0 "arith_reg_dest" "")
14443 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14444 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14447 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14448 GEN_INT (4 * 8), GEN_INT (4 * 8)));
14452 (define_expand "mextr5"
14453 [(match_operand:DI 0 "arith_reg_dest" "")
14454 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14455 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14458 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14459 GEN_INT (5 * 8), GEN_INT (3 * 8)));
14463 (define_expand "mextr6"
14464 [(match_operand:DI 0 "arith_reg_dest" "")
14465 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14466 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14469 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14470 GEN_INT (6 * 8), GEN_INT (2 * 8)));
14474 (define_expand "mextr7"
14475 [(match_operand:DI 0 "arith_reg_dest" "")
14476 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14477 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14480 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14481 GEN_INT (7 * 8), GEN_INT (1 * 8)));
14485 (define_expand "mmacfx_wl"
14486 [(match_operand:V2SI 0 "arith_reg_dest" "")
14487 (match_operand:V2HI 1 "extend_reg_operand" "")
14488 (match_operand:V2HI 2 "extend_reg_operand" "")
14489 (match_operand:V2SI 3 "arith_reg_operand" "")]
14492 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
14493 operands[1], operands[2]));
14497 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
14499 (define_insn "mmacfx_wl_i"
14500 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14502 (match_operand:V2SI 1 "arith_reg_operand" "0")
14507 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14508 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14511 "mmacfx.wl %2, %3, %0"
14512 [(set_attr "type" "mac_media")
14513 (set_attr "highpart" "depend")])
14515 (define_expand "mmacnfx_wl"
14516 [(match_operand:V2SI 0 "arith_reg_dest" "")
14517 (match_operand:V2HI 1 "extend_reg_operand" "")
14518 (match_operand:V2HI 2 "extend_reg_operand" "")
14519 (match_operand:V2SI 3 "arith_reg_operand" "")]
14522 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
14523 operands[1], operands[2]));
14527 (define_insn "mmacnfx_wl_i"
14528 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14530 (match_operand:V2SI 1 "arith_reg_operand" "0")
14535 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14536 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14539 "mmacnfx.wl %2, %3, %0"
14540 [(set_attr "type" "mac_media")
14541 (set_attr "highpart" "depend")])
14543 (define_insn "mulv2si3"
14544 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14545 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14546 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14548 "mmul.l %1, %2, %0"
14549 [(set_attr "type" "d2mpy_media")
14550 (set_attr "highpart" "depend")])
14552 (define_insn "mulv4hi3"
14553 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14554 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14555 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14557 "mmul.w %1, %2, %0"
14558 [(set_attr "type" "dmpy_media")
14559 (set_attr "highpart" "depend")])
14561 (define_insn "mmulfx_l"
14562 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14566 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14567 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
14570 "mmulfx.l %1, %2, %0"
14571 [(set_attr "type" "d2mpy_media")
14572 (set_attr "highpart" "depend")])
14574 (define_insn "mmulfx_w"
14575 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14579 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14580 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14583 "mmulfx.w %1, %2, %0"
14584 [(set_attr "type" "dmpy_media")
14585 (set_attr "highpart" "depend")])
14587 (define_insn "mmulfxrp_w"
14588 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14593 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14594 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14598 "mmulfxrp.w %1, %2, %0"
14599 [(set_attr "type" "dmpy_media")
14600 (set_attr "highpart" "depend")])
14603 (define_expand "mmulhi_wl"
14604 [(match_operand:V2SI 0 "arith_reg_dest" "")
14605 (match_operand:V4HI 1 "arith_reg_operand" "")
14606 (match_operand:V4HI 2 "arith_reg_operand" "")]
14609 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
14610 (operands[0], operands[1], operands[2]));
14614 (define_expand "mmullo_wl"
14615 [(match_operand:V2SI 0 "arith_reg_dest" "")
14616 (match_operand:V4HI 1 "arith_reg_operand" "")
14617 (match_operand:V4HI 2 "arith_reg_operand" "")]
14620 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14621 (operands[0], operands[1], operands[2]));
14625 (define_insn "mmul23_wl"
14626 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14629 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14630 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14631 (parallel [(const_int 2) (const_int 3)])))]
14634 return (TARGET_LITTLE_ENDIAN
14635 ? "mmulhi.wl %1, %2, %0"
14636 : "mmullo.wl %1, %2, %0");
14638 [(set_attr "type" "dmpy_media")
14639 (set (attr "highpart")
14640 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14641 (const_string "user")))])
14643 (define_insn "mmul01_wl"
14644 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14647 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14648 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14649 (parallel [(const_int 0) (const_int 1)])))]
14652 return (TARGET_LITTLE_ENDIAN
14653 ? "mmullo.wl %1, %2, %0"
14654 : "mmulhi.wl %1, %2, %0");
14656 [(set_attr "type" "dmpy_media")
14657 (set (attr "highpart")
14658 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14659 (const_string "user")))])
14662 (define_expand "mmulsum_wq"
14663 [(match_operand:DI 0 "arith_reg_dest" "")
14664 (match_operand:V4HI 1 "arith_reg_operand" "")
14665 (match_operand:V4HI 2 "arith_reg_operand" "")
14666 (match_operand:DI 3 "arith_reg_operand" "")]
14669 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14670 operands[1], operands[2]));
14674 (define_insn "mmulsum_wq_i"
14675 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14676 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14681 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14682 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14683 (parallel [(const_int 0)]))
14684 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14685 (sign_extend:V4DI (match_dup 3)))
14686 (parallel [(const_int 1)])))
14688 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14689 (sign_extend:V4DI (match_dup 3)))
14690 (parallel [(const_int 2)]))
14691 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14692 (sign_extend:V4DI (match_dup 3)))
14693 (parallel [(const_int 3)]))))))]
14695 "mmulsum.wq %2, %3, %0"
14696 [(set_attr "type" "mac_media")])
14698 (define_expand "mperm_w"
14699 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14700 (match_operand:V4HI 1 "arith_reg_operand" "r")
14701 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14704 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14705 (operands[0], operands[1], operands[2]));
14709 ; This use of vec_select isn't exactly correct according to rtl.texi
14710 ; (because not constant), but it seems a straightforward extension.
14711 (define_insn "mperm_w_little"
14712 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14714 (match_operand:V4HI 1 "arith_reg_operand" "r")
14716 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14717 (const_int 2) (const_int 0))
14718 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14719 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14720 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14721 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14722 "mperm.w %1, %N2, %0"
14723 [(set_attr "type" "arith_media")])
14725 (define_insn "mperm_w_big"
14726 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14728 (match_operand:V4HI 1 "arith_reg_operand" "r")
14730 [(zero_extract:QI (not:QI (match_operand:QI 2
14731 "extend_reg_or_0_operand" "rZ"))
14732 (const_int 2) (const_int 0))
14733 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14734 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14735 (zero_extract:QI (not:QI (match_dup 2))
14736 (const_int 2) (const_int 6))])))]
14737 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
14738 "mperm.w %1, %N2, %0"
14739 [(set_attr "type" "arith_media")])
14741 (define_insn "mperm_w0"
14742 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14743 (vec_duplicate:V4HI (truncate:HI (match_operand 1
14744 "trunc_hi_operand" "r"))))]
14746 "mperm.w %1, r63, %0"
14747 [(set_attr "type" "arith_media")
14748 (set_attr "highpart" "ignore")])
14750 (define_expand "msad_ubq"
14751 [(match_operand:DI 0 "arith_reg_dest" "")
14752 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14753 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14754 (match_operand:DI 3 "arith_reg_operand" "")]
14757 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14758 operands[1], operands[2]));
14762 (define_insn "msad_ubq_i"
14763 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14768 (match_operand:DI 1 "arith_reg_operand" "0")
14769 (abs:DI (vec_select:DI
14772 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14774 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14775 (parallel [(const_int 0)]))))
14776 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14777 (zero_extend:V8DI (match_dup 3)))
14778 (parallel [(const_int 1)]))))
14780 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14781 (zero_extend:V8DI (match_dup 3)))
14782 (parallel [(const_int 2)])))
14783 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14784 (zero_extend:V8DI (match_dup 3)))
14785 (parallel [(const_int 3)])))))
14788 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14789 (zero_extend:V8DI (match_dup 3)))
14790 (parallel [(const_int 4)])))
14791 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14792 (zero_extend:V8DI (match_dup 3)))
14793 (parallel [(const_int 5)]))))
14795 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14796 (zero_extend:V8DI (match_dup 3)))
14797 (parallel [(const_int 6)])))
14798 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14799 (zero_extend:V8DI (match_dup 3)))
14800 (parallel [(const_int 7)])))))))]
14802 "msad.ubq %N2, %N3, %0"
14803 [(set_attr "type" "mac_media")])
14805 (define_insn "mshalds_l"
14806 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14809 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14810 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14811 (const_int 31)))))]
14813 "mshalds.l %1, %2, %0"
14814 [(set_attr "type" "mcmp_media")
14815 (set_attr "highpart" "depend")])
14817 (define_insn "mshalds_w"
14818 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14821 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14822 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14823 (const_int 15)))))]
14825 "mshalds.w %1, %2, %0"
14826 [(set_attr "type" "mcmp_media")
14827 (set_attr "highpart" "depend")])
14829 (define_insn "ashrv2si3"
14830 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14831 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14832 (match_operand:DI 2 "arith_reg_operand" "r")))]
14834 "mshard.l %1, %2, %0"
14835 [(set_attr "type" "arith_media")
14836 (set_attr "highpart" "depend")])
14838 (define_insn "ashrv4hi3"
14839 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14840 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14841 (match_operand:DI 2 "arith_reg_operand" "r")))]
14843 "mshard.w %1, %2, %0"
14844 [(set_attr "type" "arith_media")
14845 (set_attr "highpart" "depend")])
14847 (define_insn "mshards_q"
14848 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14850 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14851 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14853 "mshards.q %1, %N2, %0"
14854 [(set_attr "type" "mcmp_media")])
14856 (define_expand "mshfhi_b"
14857 [(match_operand:V8QI 0 "arith_reg_dest" "")
14858 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14859 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14862 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14863 (operands[0], operands[1], operands[2]));
14867 (define_expand "mshflo_b"
14868 [(match_operand:V8QI 0 "arith_reg_dest" "")
14869 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14870 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14873 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14874 (operands[0], operands[1], operands[2]));
14878 (define_insn "mshf4_b"
14880 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14882 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14883 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14884 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14885 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14888 return (TARGET_LITTLE_ENDIAN
14889 ? "mshfhi.b %N1, %N2, %0"
14890 : "mshflo.b %N1, %N2, %0");
14892 [(set_attr "type" "arith_media")
14893 (set (attr "highpart")
14894 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14895 (const_string "user")))])
14897 (define_insn "mshf0_b"
14899 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14901 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14902 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14903 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14904 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14907 return (TARGET_LITTLE_ENDIAN
14908 ? "mshflo.b %N1, %N2, %0"
14909 : "mshfhi.b %N1, %N2, %0");
14911 [(set_attr "type" "arith_media")
14912 (set (attr "highpart")
14913 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14914 (const_string "user")))])
14916 (define_expand "mshfhi_l"
14917 [(match_operand:V2SI 0 "arith_reg_dest" "")
14918 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14919 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14922 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14923 (operands[0], operands[1], operands[2]));
14927 (define_expand "mshflo_l"
14928 [(match_operand:V2SI 0 "arith_reg_dest" "")
14929 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14930 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14933 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14934 (operands[0], operands[1], operands[2]));
14938 (define_insn "mshf4_l"
14939 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14941 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14942 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14943 (parallel [(const_int 1) (const_int 3)])))]
14946 return (TARGET_LITTLE_ENDIAN
14947 ? "mshfhi.l %N1, %N2, %0"
14948 : "mshflo.l %N1, %N2, %0");
14950 [(set_attr "type" "arith_media")
14951 (set (attr "highpart")
14952 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14953 (const_string "user")))])
14955 (define_insn "mshf0_l"
14956 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14958 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14959 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14960 (parallel [(const_int 0) (const_int 2)])))]
14963 return (TARGET_LITTLE_ENDIAN
14964 ? "mshflo.l %N1, %N2, %0"
14965 : "mshfhi.l %N1, %N2, %0");
14967 [(set_attr "type" "arith_media")
14968 (set (attr "highpart")
14969 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14970 (const_string "user")))])
14972 (define_expand "mshfhi_w"
14973 [(match_operand:V4HI 0 "arith_reg_dest" "")
14974 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14975 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14978 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14979 (operands[0], operands[1], operands[2]));
14983 (define_expand "mshflo_w"
14984 [(match_operand:V4HI 0 "arith_reg_dest" "")
14985 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14986 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14989 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14990 (operands[0], operands[1], operands[2]));
14994 (define_insn "mshf4_w"
14995 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14997 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14998 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14999 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
15002 return (TARGET_LITTLE_ENDIAN
15003 ? "mshfhi.w %N1, %N2, %0"
15004 : "mshflo.w %N1, %N2, %0");
15006 [(set_attr "type" "arith_media")
15007 (set (attr "highpart")
15008 (cond [(eq_attr "endian" "big") (const_string "ignore")]
15009 (const_string "user")))])
15011 (define_insn "mshf0_w"
15012 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15014 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15015 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
15016 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
15019 return (TARGET_LITTLE_ENDIAN
15020 ? "mshflo.w %N1, %N2, %0"
15021 : "mshfhi.w %N1, %N2, %0");
15023 [(set_attr "type" "arith_media")
15024 (set (attr "highpart")
15025 (cond [(eq_attr "endian" "little") (const_string "ignore")]
15026 (const_string "user")))])
15028 (define_insn "mshflo_w_x"
15029 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15031 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
15032 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
15033 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
15035 "mshflo.w %N1, %N2, %0"
15036 [(set_attr "type" "arith_media")
15037 (set_attr "highpart" "ignore")])
15039 ;; These are useful to expand ANDs and as combiner patterns.
15040 (define_insn_and_split "mshfhi_l_di"
15041 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
15042 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
15044 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
15045 (const_int -4294967296))))]
15048 mshfhi.l %N1, %N2, %0
15050 "TARGET_SHMEDIA && reload_completed
15051 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
15052 [(set (match_dup 3) (match_dup 4))
15053 (set (match_dup 5) (match_dup 6))]
15055 operands[3] = gen_lowpart (SImode, operands[0]);
15056 operands[4] = gen_highpart (SImode, operands[1]);
15057 operands[5] = gen_highpart (SImode, operands[0]);
15058 operands[6] = gen_highpart (SImode, operands[2]);
15060 [(set_attr "type" "arith_media")])
15062 (define_insn "*mshfhi_l_di_rev"
15063 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15064 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15065 (const_int -4294967296))
15066 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15069 "mshfhi.l %N2, %N1, %0"
15070 [(set_attr "type" "arith_media")])
15073 [(set (match_operand:DI 0 "arith_reg_dest" "")
15074 (ior:DI (zero_extend:DI (match_operand:SI 1
15075 "extend_reg_or_0_operand" ""))
15076 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
15077 (const_int -4294967296))))
15078 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
15082 emit_insn (gen_ashldi3_media (operands[3],
15083 simplify_gen_subreg (DImode, operands[1],
15086 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
15090 (define_insn "mshflo_l_di"
15091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15092 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15093 (const_int 4294967295))
15094 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15098 "mshflo.l %N1, %N2, %0"
15099 [(set_attr "type" "arith_media")
15100 (set_attr "highpart" "ignore")])
15102 (define_insn "*mshflo_l_di_rev"
15103 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15104 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15106 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15107 (const_int 4294967295))))]
15110 "mshflo.l %N2, %N1, %0"
15111 [(set_attr "type" "arith_media")
15112 (set_attr "highpart" "ignore")])
15114 ;; Combiner pattern for trampoline initialization.
15115 (define_insn_and_split "*double_shori"
15116 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15117 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
15119 (match_operand:DI 2 "const_int_operand" "n")))]
15121 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
15123 "rtx_equal_p (operands[0], operands[1])"
15126 HOST_WIDE_INT v = INTVAL (operands[2]);
15128 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
15129 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
15132 [(set_attr "highpart" "ignore")])
15134 (define_insn "*mshflo_l_di_x"
15135 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15136 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
15138 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15141 "mshflo.l %N1, %N2, %0"
15142 [(set_attr "type" "arith_media")
15143 (set_attr "highpart" "ignore")])
15145 (define_insn_and_split "concat_v2sf"
15146 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
15147 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
15148 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
15149 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
15152 mshflo.l %N1, %N2, %0
15155 "TARGET_SHMEDIA && reload_completed
15156 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
15157 [(set (match_dup 3) (match_dup 1))
15158 (set (match_dup 4) (match_dup 2))]
15160 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
15161 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
15163 [(set_attr "type" "arith_media")
15164 (set_attr "highpart" "ignore")])
15166 (define_insn "*mshflo_l_di_x_rev"
15167 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15168 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15171 (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
15173 "mshflo.l %N2, %N1, %0"
15174 [(set_attr "type" "arith_media")
15175 (set_attr "highpart" "ignore")])
15177 (define_insn "ashlv2si3"
15178 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15179 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15180 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15182 "mshlld.l %1, %2, %0"
15183 [(set_attr "type" "arith_media")
15184 (set_attr "highpart" "depend")])
15187 [(set (match_operand 0 "any_register_operand" "")
15188 (match_operator 3 "shift_operator"
15189 [(match_operand 1 "any_register_operand" "")
15190 (match_operand 2 "shift_count_reg_operand" "")]))]
15191 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
15192 [(set (match_dup 0) (match_dup 3))]
15194 rtx count = operands[2];
15195 machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
15197 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
15198 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
15199 || GET_CODE (count) == TRUNCATE)
15200 count = XEXP (count, 0);
15201 inner_mode = GET_MODE (count);
15202 count = simplify_gen_subreg (outer_mode, count, inner_mode,
15203 subreg_lowpart_offset (outer_mode, inner_mode));
15204 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
15205 operands[1], count);
15208 (define_insn "ashlv4hi3"
15209 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15210 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15211 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15213 "mshlld.w %1, %2, %0"
15214 [(set_attr "type" "arith_media")
15215 (set_attr "highpart" "depend")])
15217 (define_insn "lshrv2si3"
15218 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15219 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15220 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15222 "mshlrd.l %1, %2, %0"
15223 [(set_attr "type" "arith_media")
15224 (set_attr "highpart" "depend")])
15226 (define_insn "lshrv4hi3"
15227 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15228 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15229 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15231 "mshlrd.w %1, %2, %0"
15232 [(set_attr "type" "arith_media")
15233 (set_attr "highpart" "depend")])
15235 (define_insn "subv2si3"
15236 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15237 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15238 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15240 "msub.l %N1, %2, %0"
15241 [(set_attr "type" "arith_media")
15242 (set_attr "highpart" "depend")])
15244 (define_insn "subv4hi3"
15245 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15246 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15247 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15249 "msub.w %N1, %2, %0"
15250 [(set_attr "type" "arith_media")
15251 (set_attr "highpart" "depend")])
15253 (define_insn_and_split "subv2hi3"
15254 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
15255 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
15256 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
15262 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
15263 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
15264 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
15265 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
15266 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
15268 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
15269 emit_insn (gen_truncdisi2 (si_dst, di_dst));
15272 [(set_attr "highpart" "must_split")])
15274 (define_insn "sssubv2si3"
15275 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15276 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15277 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15279 "msubs.l %N1, %2, %0"
15280 [(set_attr "type" "mcmp_media")
15281 (set_attr "highpart" "depend")])
15283 (define_insn "ussubv8qi3"
15284 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15285 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15286 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
15288 "msubs.ub %N1, %2, %0"
15289 [(set_attr "type" "mcmp_media")
15290 (set_attr "highpart" "depend")])
15292 (define_insn "sssubv4hi3"
15293 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15294 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15295 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15297 "msubs.w %N1, %2, %0"
15298 [(set_attr "type" "mcmp_media")
15299 (set_attr "highpart" "depend")])
15301 ;; -------------------------------------------------------------------------
15302 ;; Floating Point Intrinsics
15303 ;; -------------------------------------------------------------------------
15305 (define_insn "fcosa_s"
15306 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15307 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
15311 [(set_attr "type" "atrans_media")])
15313 (define_insn "fsina_s"
15314 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15315 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
15319 [(set_attr "type" "atrans_media")])
15321 (define_insn "fipr"
15322 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15323 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
15324 "fp_arith_reg_operand" "f")
15325 (match_operand:V4SF 2
15326 "fp_arith_reg_operand" "f"))
15327 (parallel [(const_int 0)]))
15328 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15329 (parallel [(const_int 1)])))
15330 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15331 (parallel [(const_int 2)]))
15332 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15333 (parallel [(const_int 3)])))))]
15335 "fipr.s %1, %2, %0"
15336 [(set_attr "type" "fparith_media")])
15338 (define_insn "fsrra_s"
15339 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15340 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
15344 [(set_attr "type" "atrans_media")])
15346 (define_insn "ftrv"
15347 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
15351 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
15352 (parallel [(const_int 0) (const_int 5)
15353 (const_int 10) (const_int 15)]))
15354 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
15356 (vec_select:V4SF (match_dup 1)
15357 (parallel [(const_int 4) (const_int 9)
15358 (const_int 14) (const_int 3)]))
15359 (vec_select:V4SF (match_dup 2)
15360 (parallel [(const_int 1) (const_int 2)
15361 (const_int 3) (const_int 0)]))))
15364 (vec_select:V4SF (match_dup 1)
15365 (parallel [(const_int 8) (const_int 13)
15366 (const_int 2) (const_int 7)]))
15367 (vec_select:V4SF (match_dup 2)
15368 (parallel [(const_int 2) (const_int 3)
15369 (const_int 0) (const_int 1)])))
15371 (vec_select:V4SF (match_dup 1)
15372 (parallel [(const_int 12) (const_int 1)
15373 (const_int 6) (const_int 11)]))
15374 (vec_select:V4SF (match_dup 2)
15375 (parallel [(const_int 3) (const_int 0)
15376 (const_int 1) (const_int 2)]))))))]
15378 "ftrv.s %1, %2, %0"
15379 [(set_attr "type" "fparith_media")])
15381 (define_insn "ldhi_l"
15382 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15384 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15387 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
15391 [(set_attr "type" "load_media")])
15393 (define_insn "ldhi_q"
15394 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15396 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15399 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
15403 [(set_attr "type" "load_media")])
15405 (define_insn_and_split "*ldhi_q_comb0"
15406 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15408 (mem:DI (plus:SI (ior:SI (plus:SI
15409 (match_operand:SI 1 "register_operand" "r")
15410 (match_operand:SI 2 "ua_offset" "I06"))
15413 (plus:SI (and:SI (match_dup 1) (const_int 7))
15416 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15421 emit_insn (gen_ldhi_q (operands[0],
15422 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15426 (define_insn_and_split "*ldhi_q_comb1"
15427 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15429 (mem:DI (plus:SI (ior:SI (plus:SI
15430 (match_operand:SI 1 "register_operand" "r")
15431 (match_operand:SI 2 "ua_offset" "I06"))
15434 (plus:SI (and:SI (plus:SI (match_dup 1)
15435 (match_operand:SI 3 "ua_offset" "I06"))
15439 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15440 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15445 emit_insn (gen_ldhi_q (operands[0],
15446 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15450 (define_insn "ldlo_l"
15451 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15453 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15455 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
15456 (and:SI (match_dup 1) (const_int 3))))]
15459 [(set_attr "type" "load_media")])
15461 (define_insn "ldlo_q"
15462 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15464 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15466 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15467 (and:SI (match_dup 1) (const_int 7))))]
15470 [(set_attr "type" "load_media")])
15472 (define_insn_and_split "*ldlo_q_comb0"
15473 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15475 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15476 (match_operand:SI 2 "ua_offset" "I06"))
15478 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15479 (and:SI (match_dup 1) (const_int 7))))]
15480 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15485 emit_insn (gen_ldlo_q (operands[0],
15486 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15490 (define_insn_and_split "*ldlo_q_comb1"
15491 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15493 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15494 (match_operand:SI 2 "ua_offset" "I06"))
15496 (minus:SI (const_int 8)
15497 (and:SI (plus:SI (match_dup 1)
15498 (match_operand:SI 3 "ua_offset" "I06"))
15500 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
15501 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15502 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15507 emit_insn (gen_ldlo_q (operands[0],
15508 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15512 (define_insn "sthi_l"
15513 [(set (zero_extract:SI
15514 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15517 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
15519 (match_operand:SI 1 "arith_reg_operand" "r"))]
15522 [(set_attr "type" "ustore_media")])
15524 ;; All unaligned stores are considered to be 'narrow' because they typically
15525 ;; operate on less that a quadword, and when they operate on a full quadword,
15526 ;; the vanilla store high / store low sequence will cause a stall if not
15527 ;; scheduled apart.
15528 (define_insn "sthi_q"
15529 [(set (zero_extract:DI
15530 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15533 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15535 (match_operand:DI 1 "arith_reg_operand" "r"))]
15538 [(set_attr "type" "ustore_media")])
15540 (define_insn_and_split "*sthi_q_comb0"
15541 [(set (zero_extract:DI
15542 (mem:DI (plus:SI (ior:SI (plus:SI
15543 (match_operand:SI 0 "register_operand" "r")
15544 (match_operand:SI 1 "ua_offset" "I06"))
15547 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15549 (match_operand:DI 2 "arith_reg_operand" "r"))]
15550 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15555 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15560 (define_insn_and_split "*sthi_q_comb1"
15561 [(set (zero_extract:DI
15562 (mem:DI (plus:SI (ior:SI (plus:SI
15563 (match_operand:SI 0 "register_operand" "r")
15564 (match_operand:SI 1 "ua_offset" "I06"))
15567 (plus:SI (and:SI (plus:SI (match_dup 0)
15568 (match_operand:SI 2 "ua_offset" "I06"))
15572 (match_operand:DI 3 "arith_reg_operand" "r"))]
15573 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
15574 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15579 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15584 ;; This is highpart user because the address is used as full 64 bit.
15585 (define_insn "stlo_l"
15586 [(set (zero_extract:SI
15587 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15589 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
15590 (and:SI (match_dup 0) (const_int 3)))
15591 (match_operand:SI 1 "arith_reg_operand" "r"))]
15594 [(set_attr "type" "ustore_media")])
15596 (define_insn "stlo_q"
15597 [(set (zero_extract:DI
15598 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15600 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15601 (and:SI (match_dup 0) (const_int 7)))
15602 (match_operand:DI 1 "arith_reg_operand" "r"))]
15605 [(set_attr "type" "ustore_media")])
15607 (define_insn_and_split "*stlo_q_comb0"
15608 [(set (zero_extract:DI
15609 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15610 (match_operand:SI 1 "ua_offset" "I06"))
15612 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15613 (and:SI (match_dup 0) (const_int 7)))
15614 (match_operand:DI 2 "arith_reg_operand" "r"))]
15615 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15620 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15625 (define_insn_and_split "*stlo_q_comb1"
15626 [(set (zero_extract:DI
15627 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15628 (match_operand:SI 1 "ua_offset" "I06"))
15630 (minus:SI (const_int 8)
15631 (and:SI (plus:SI (match_dup 0)
15632 (match_operand:SI 2 "ua_offset" "I06"))
15634 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15635 (match_operand:DI 3 "arith_reg_operand" "r"))]
15636 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15641 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15646 (define_insn "ldhi_l64"
15647 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15649 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15652 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15656 [(set_attr "type" "load_media")])
15658 (define_insn "ldhi_q64"
15659 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15661 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15664 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15668 [(set_attr "type" "load_media")])
15670 (define_insn "ldlo_l64"
15671 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15673 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15675 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15676 (and:DI (match_dup 1) (const_int 3))))]
15679 [(set_attr "type" "load_media")])
15681 (define_insn "ldlo_q64"
15682 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15684 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15686 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15687 (and:DI (match_dup 1) (const_int 7))))]
15690 [(set_attr "type" "load_media")])
15692 (define_insn "sthi_l64"
15693 [(set (zero_extract:SI
15694 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15697 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15699 (match_operand:SI 1 "arith_reg_operand" "r"))]
15702 [(set_attr "type" "ustore_media")])
15704 (define_insn "sthi_q64"
15705 [(set (zero_extract:DI
15706 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15709 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15711 (match_operand:DI 1 "arith_reg_operand" "r"))]
15714 [(set_attr "type" "ustore_media")])
15716 (define_insn "stlo_l64"
15717 [(set (zero_extract:SI
15718 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15720 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15721 (and:DI (match_dup 0) (const_int 3)))
15722 (match_operand:SI 1 "arith_reg_operand" "r"))]
15725 [(set_attr "type" "ustore_media")])
15727 (define_insn "stlo_q64"
15728 [(set (zero_extract:DI
15729 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15731 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15732 (and:DI (match_dup 0) (const_int 7)))
15733 (match_operand:DI 1 "arith_reg_operand" "r"))]
15736 [(set_attr "type" "ustore_media")])
15739 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15740 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15744 [(set_attr "type" "arith_media")])
15746 (define_insn "nsbsi"
15747 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15749 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15753 [(set_attr "type" "arith_media")])
15755 (define_insn "nsbdi"
15756 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15758 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15762 [(set_attr "type" "arith_media")])
15764 (define_expand "ffsdi2"
15765 [(set (match_operand:DI 0 "arith_reg_dest" "")
15766 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15769 rtx scratch = gen_reg_rtx (DImode);
15772 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15773 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15774 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15775 emit_insn (gen_nsbdi (scratch, scratch));
15776 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15777 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15778 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15779 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15784 (define_expand "ffssi2"
15785 [(set (match_operand:SI 0 "arith_reg_dest" "")
15786 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15789 rtx scratch = gen_reg_rtx (SImode);
15790 rtx discratch = gen_reg_rtx (DImode);
15793 emit_insn (gen_adddi3 (discratch,
15794 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15796 emit_insn (gen_andcdi3 (discratch,
15797 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15799 emit_insn (gen_nsbsi (scratch, discratch));
15800 last = emit_insn (gen_subsi3 (operands[0],
15801 force_reg (SImode, GEN_INT (63)), scratch));
15802 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15807 (define_insn "byterev"
15808 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15809 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15810 (parallel [(const_int 7) (const_int 6) (const_int 5)
15811 (const_int 4) (const_int 3) (const_int 2)
15812 (const_int 1) (const_int 0)])))]
15815 [(set_attr "type" "arith_media")])
15817 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15818 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
15819 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15820 (define_expand "prefetch"
15821 [(prefetch (match_operand 0 "address_operand" "")
15822 (match_operand:SI 1 "const_int_operand" "")
15823 (match_operand:SI 2 "const_int_operand" ""))]
15824 "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15825 && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15827 (define_insn "*prefetch"
15828 [(prefetch (match_operand:SI 0 "register_operand" "r")
15829 (match_operand:SI 1 "const_int_operand" "n")
15830 (match_operand:SI 2 "const_int_operand" "n"))]
15831 "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15833 [(set_attr "type" "other")])
15835 (define_insn "*prefetch_media"
15836 [(prefetch (match_operand:QI 0 "address_operand" "p")
15837 (match_operand:SI 1 "const_int_operand" "n")
15838 (match_operand:SI 2 "const_int_operand" "n"))]
15841 operands[0] = gen_rtx_MEM (QImode, operands[0]);
15842 output_asm_insn ("ld%M0.b %m0,r63", operands);
15845 [(set_attr "type" "other")])
15847 (define_insn "alloco_i"
15848 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15849 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15854 if (GET_CODE (operands[0]) == PLUS)
15856 xops[0] = XEXP (operands[0], 0);
15857 xops[1] = XEXP (operands[0], 1);
15861 xops[0] = operands[0];
15862 xops[1] = const0_rtx;
15864 output_asm_insn ("alloco %0, %1", xops);
15867 [(set_attr "type" "other")])
15870 [(set (match_operand 0 "any_register_operand" "")
15871 (match_operand 1 "" ""))]
15872 "TARGET_SHMEDIA && reload_completed"
15873 [(set (match_dup 0) (match_dup 1))]
15875 if (!shmedia_cleanup_truncate (operands[1]))
15879 ;; -------------------------------------------------------------------------
15880 ;; Stack Protector Patterns
15881 ;; -------------------------------------------------------------------------
15883 (define_expand "stack_protect_set"
15884 [(set (match_operand 0 "memory_operand" "")
15885 (match_operand 1 "memory_operand" ""))]
15888 if (TARGET_SHMEDIA)
15890 if (TARGET_SHMEDIA64)
15891 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15893 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15896 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15901 (define_insn "stack_protect_set_si"
15902 [(set (match_operand:SI 0 "memory_operand" "=m")
15903 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15904 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15907 return "mov.l %1,%2" "\n"
15908 " mov.l %2,%0" "\n"
15911 [(set_attr "type" "other")
15912 (set_attr "length" "6")])
15914 (define_insn "stack_protect_set_si_media"
15915 [(set (match_operand:SI 0 "memory_operand" "=m")
15916 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15917 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15920 return "ld%M1.l %m1,%2" "\n"
15921 " st%M0.l %m0,%2" "\n"
15924 [(set_attr "type" "other")
15925 (set_attr "length" "12")])
15927 (define_insn "stack_protect_set_di_media"
15928 [(set (match_operand:DI 0 "memory_operand" "=m")
15929 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15930 (set (match_scratch:DI 2 "=&r") (const_int 0))]
15933 return "ld%M1.q %m1,%2" "\n"
15934 " st%M0.q %m0,%2" "\n"
15937 [(set_attr "type" "other")
15938 (set_attr "length" "12")])
15940 (define_expand "stack_protect_test"
15941 [(match_operand 0 "memory_operand" "")
15942 (match_operand 1 "memory_operand" "")
15943 (match_operand 2 "" "")]
15946 if (TARGET_SHMEDIA)
15948 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15951 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15952 if (TARGET_SHMEDIA64)
15954 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15956 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15960 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15962 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15967 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15968 emit_jump_insn (gen_branch_true (operands[2]));
15974 (define_insn "stack_protect_test_si"
15975 [(set (reg:SI T_REG)
15976 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15977 (match_operand:SI 1 "memory_operand" "m")]
15979 (set (match_scratch:SI 2 "=&r") (const_int 0))
15980 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15983 return "mov.l %0,%2" "\n"
15984 " mov.l %1,%3" "\n"
15985 " cmp/eq %2,%3" "\n"
15989 [(set_attr "type" "other")
15990 (set_attr "length" "10")])
15992 (define_insn "stack_protect_test_si_media"
15993 [(set (match_operand:SI 0 "register_operand" "=&r")
15994 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15995 (match_operand:SI 2 "memory_operand" "m")]
15997 (set (match_scratch:SI 3 "=&r") (const_int 0))]
16000 return "ld%M1.l %m1,%0" "\n"
16001 " ld%M2.l %m2,%3" "\n"
16002 " cmpeq %0,%3,%0" "\n"
16005 [(set_attr "type" "other")
16006 (set_attr "length" "16")])
16008 (define_insn "stack_protect_test_di_media"
16009 [(set (match_operand:DI 0 "register_operand" "=&r")
16010 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
16011 (match_operand:DI 2 "memory_operand" "m")]
16013 (set (match_scratch:DI 3 "=&r") (const_int 0))]
16016 return "ld%M1.q %m1,%0" "\n"
16017 " ld%M2.q %m2,%3" "\n"
16018 " cmpeq %0,%3,%0" "\n"
16021 [(set_attr "type" "other")
16022 (set_attr "length" "16")])
16024 ;; -------------------------------------------------------------------------
16025 ;; Atomic operations
16026 ;; -------------------------------------------------------------------------
16028 (include "sync.md")