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 ;; Conditional move combine pattern for div0s comparisons.
1090 ;; This is used when TARGET_PRETEND_CMOVE is in effect.
1091 (define_insn_and_split "*movsicc_div0s"
1092 [(set (match_operand:SI 0 "arith_reg_dest" "")
1093 (if_then_else:SI (ge (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
1094 (match_operand:SI 2 "arith_reg_operand" ""))
1096 (match_operand:SI 3 "arith_reg_operand" "")
1097 (match_operand:SI 4 "general_movsrc_operand" "")))
1098 (clobber (reg:SI T_REG))]
1099 "TARGET_PRETEND_CMOVE"
1102 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1105 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1109 (define_insn_and_split "*movsicc_div0s"
1110 [(set (match_operand:SI 0 "arith_reg_dest")
1111 (if_then_else:SI (eq (lshiftrt:SI
1112 (match_operand:SI 1 "arith_reg_operand")
1115 (match_operand:SI 2 "arith_reg_operand")
1117 (match_operand:SI 3 "arith_reg_operand")
1118 (match_operand:SI 4 "general_movsrc_operand")))
1119 (clobber (reg:SI T_REG))]
1120 "TARGET_PRETEND_CMOVE"
1123 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1126 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1130 ;; -------------------------------------------------------------------------
1131 ;; SImode unsigned integer comparisons
1132 ;; -------------------------------------------------------------------------
1134 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1135 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1136 ;; might remain and we have to handle them. If the '>= 0' case wasn't
1137 ;; handled here, something else would just load a '0' into the second operand
1138 ;; and do the comparison. We can do slightly better by just setting the
1140 (define_insn_and_split "cmpgeusi_t"
1141 [(set (reg:SI T_REG)
1142 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1143 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1146 "&& satisfies_constraint_Z (operands[1])"
1147 [(set (reg:SI T_REG) (const_int 1))]
1149 [(set_attr "type" "mt_group")])
1151 (define_insn "cmpgtusi_t"
1152 [(set (reg:SI T_REG)
1153 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1154 (match_operand:SI 1 "arith_reg_operand" "r")))]
1157 [(set_attr "type" "mt_group")])
1159 ;; -------------------------------------------------------------------------
1160 ;; DImode compare and branch
1161 ;; -------------------------------------------------------------------------
1163 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1164 ;; Therefore, we aim to have a set of three branches that go straight to the
1165 ;; destination, i.e. only one of them is taken at any one time.
1166 ;; This mechanism should also be slightly better for the sh4-200.
1168 (define_expand "cbranchdi4"
1170 (if_then_else (match_operator 0 "comparison_operator"
1171 [(match_operand:DI 1 "arith_operand" "")
1172 (match_operand:DI 2 "arith_operand" "")])
1173 (label_ref (match_operand 3 "" ""))
1175 (clobber (match_dup 4))
1176 (clobber (reg:SI T_REG))]
1177 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1179 enum rtx_code comparison;
1183 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1184 operands[2], operands[3]));
1187 else if (!TARGET_CBRANCHDI4)
1189 sh_emit_compare_and_branch (operands, DImode);
1194 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1197 comparison = prepare_cbranch_operands (operands, DImode,
1198 LAST_AND_UNUSED_RTX_CODE);
1199 if (comparison != GET_CODE (operands[0]))
1201 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1202 operands[4] = gen_rtx_SCRATCH (SImode);
1206 (define_insn_and_split "cbranchdi4_i"
1208 (if_then_else (match_operator 0 "comparison_operator"
1209 [(match_operand:DI 1 "arith_operand" "r,r")
1210 (match_operand:DI 2 "arith_operand" "rN,I08")])
1211 (label_ref (match_operand 3 "" ""))
1213 (clobber (match_scratch:SI 4 "=X,&r"))
1214 (clobber (reg:SI T_REG))]
1217 "&& reload_completed"
1220 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1225 ;; -------------------------------------------------------------------------
1226 ;; DImode signed integer comparisons
1227 ;; -------------------------------------------------------------------------
1230 [(set (reg:SI T_REG)
1231 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1232 (match_operand:DI 1 "arith_operand" "r"))
1236 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1239 [(set_attr "length" "6")
1240 (set_attr "type" "arith3b")])
1242 (define_insn "cmpeqdi_t"
1243 [(set (reg:SI T_REG)
1244 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1245 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1248 static const char* alt[] =
1255 "cmp/eq %S1,%S0" "\n"
1257 " cmp/eq %R1,%R0" "\n"
1260 return alt[which_alternative];
1262 [(set_attr "length" "6")
1263 (set_attr "type" "arith3b")])
1266 [(set (reg:SI T_REG)
1267 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1268 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1269 ;; If we applied this split when not optimizing, it would only be
1270 ;; applied during the machine-dependent reorg, when no new basic blocks
1272 "TARGET_SH1 && reload_completed && optimize"
1273 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1274 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1275 (label_ref (match_dup 6))
1277 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1280 operands[2] = gen_highpart (SImode, operands[0]);
1281 operands[3] = operands[1] == const0_rtx
1283 : gen_highpart (SImode, operands[1]);
1284 operands[4] = gen_lowpart (SImode, operands[0]);
1285 operands[5] = gen_lowpart (SImode, operands[1]);
1286 operands[6] = gen_label_rtx ();
1289 (define_insn "cmpgtdi_t"
1290 [(set (reg:SI T_REG)
1291 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1292 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1295 static const char* alt[] =
1297 "cmp/eq %S1,%S0" "\n"
1299 " cmp/gt %S1,%S0" "\n"
1300 " cmp/hi %R1,%R0" "\n"
1306 " cmp/hi %S0,%R0" "\n"
1309 return alt[which_alternative];
1311 [(set_attr "length" "8")
1312 (set_attr "type" "arith3")])
1314 (define_insn "cmpgedi_t"
1315 [(set (reg:SI T_REG)
1316 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1317 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1320 static const char* alt[] =
1322 "cmp/eq %S1,%S0" "\n"
1324 " cmp/ge %S1,%S0" "\n"
1325 " cmp/hs %R1,%R0" "\n"
1330 return alt[which_alternative];
1332 [(set_attr "length" "8,2")
1333 (set_attr "type" "arith3,mt_group")])
1335 ;; -------------------------------------------------------------------------
1336 ;; DImode unsigned integer comparisons
1337 ;; -------------------------------------------------------------------------
1339 (define_insn "cmpgeudi_t"
1340 [(set (reg:SI T_REG)
1341 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1342 (match_operand:DI 1 "arith_reg_operand" "r")))]
1345 return "cmp/eq %S1,%S0" "\n"
1347 " cmp/hs %S1,%S0" "\n"
1348 " cmp/hs %R1,%R0" "\n"
1351 [(set_attr "length" "8")
1352 (set_attr "type" "arith3")])
1354 (define_insn "cmpgtudi_t"
1355 [(set (reg:SI T_REG)
1356 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1357 (match_operand:DI 1 "arith_reg_operand" "r")))]
1360 return "cmp/eq %S1,%S0" "\n"
1362 " cmp/hi %S1,%S0" "\n"
1363 " cmp/hi %R1,%R0" "\n"
1366 [(set_attr "length" "8")
1367 (set_attr "type" "arith3")])
1369 (define_insn "cmpeqsi_media"
1370 [(set (match_operand:SI 0 "register_operand" "=r")
1371 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1372 (match_operand:SI 2 "cmp_operand" "Nr")))]
1375 [(set_attr "type" "cmp_media")])
1377 (define_insn "cmpeqdi_media"
1378 [(set (match_operand:SI 0 "register_operand" "=r")
1379 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1380 (match_operand:DI 2 "cmp_operand" "Nr")))]
1383 [(set_attr "type" "cmp_media")])
1385 (define_insn "cmpgtsi_media"
1386 [(set (match_operand:SI 0 "register_operand" "=r")
1387 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1388 (match_operand:SI 2 "cmp_operand" "rN")))]
1390 "cmpgt %N1, %N2, %0"
1391 [(set_attr "type" "cmp_media")])
1393 (define_insn "cmpgtdi_media"
1394 [(set (match_operand:SI 0 "register_operand" "=r")
1395 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1396 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1398 "cmpgt %N1, %N2, %0"
1399 [(set_attr "type" "cmp_media")])
1401 (define_insn "cmpgtusi_media"
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1404 (match_operand:SI 2 "cmp_operand" "rN")))]
1406 "cmpgtu %N1, %N2, %0"
1407 [(set_attr "type" "cmp_media")])
1409 (define_insn "cmpgtudi_media"
1410 [(set (match_operand:SI 0 "register_operand" "=r")
1411 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1412 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1414 "cmpgtu %N1, %N2, %0"
1415 [(set_attr "type" "cmp_media")])
1417 ; This pattern is for combine.
1418 (define_insn "*cmpne0sisi_media"
1419 [(set (match_operand:SI 0 "register_operand" "=r")
1420 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1423 [(set_attr "type" "cmp_media")])
1425 ;; -------------------------------------------------------------------------
1426 ;; Conditional move instructions
1427 ;; -------------------------------------------------------------------------
1429 ;; The insn names may seem reversed, but note that cmveq performs the move
1430 ;; if op1 == 0, and cmvne does it if op1 != 0.
1432 (define_insn "movdicc_false"
1433 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1434 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1436 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1437 (match_operand:DI 3 "arith_reg_operand" "0")))]
1440 [(set_attr "type" "arith_media")])
1442 (define_insn "movdicc_true"
1443 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1444 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1446 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1447 (match_operand:DI 3 "arith_reg_operand" "0")))]
1450 [(set_attr "type" "arith_media")])
1453 [(set (match_operand:DI 0 "arith_reg_dest" "")
1454 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1455 [(match_operand:DI 1 "arith_reg_operand" "")
1457 (match_operand:DI 2 "arith_reg_dest" "")
1459 (set (match_dup 2) (match_dup 0))]
1460 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1462 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1464 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1465 VOIDmode, operands[1], CONST0_RTX (DImode));
1469 [(set (match_operand:DI 0 "general_movdst_operand" "")
1470 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1471 (set (match_operand:DI 2 "arith_reg_dest" "")
1472 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1473 [(match_operand:DI 3 "arith_reg_operand" "")
1477 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1479 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1482 (define_expand "movdicc"
1483 [(set (match_operand:DI 0 "register_operand" "")
1484 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1485 (match_operand:DI 2 "register_operand" "")
1486 (match_operand:DI 3 "register_operand" "")))]
1489 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1490 && GET_MODE (XEXP (operands[1], 0)) == DImode
1491 && XEXP (operands[1], 1) == const0_rtx)
1495 if (!can_create_pseudo_p ())
1498 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1499 GET_CODE (operands[1]),
1500 XEXP (operands[1], 0),
1501 XEXP (operands[1], 1));
1507 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1508 ;; SImode to DImode.
1509 (define_insn "movsicc_false"
1510 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1511 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1513 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1514 (match_operand:SI 3 "arith_reg_operand" "0")))]
1517 [(set_attr "type" "arith_media")])
1519 (define_insn "movsicc_true"
1520 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1521 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1523 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1524 (match_operand:SI 3 "arith_reg_operand" "0")))]
1527 [(set_attr "type" "arith_media")])
1530 [(set (match_operand:SI 0 "arith_reg_dest" "")
1531 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1532 [(match_operand:SI 1 "arith_reg_operand" "")
1534 (match_operand:SI 2 "arith_reg_dest" "")
1536 (set (match_dup 2) (match_dup 0))]
1537 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1539 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1541 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1542 VOIDmode, operands[1], CONST0_RTX (SImode));
1546 [(set (match_operand:SI 0 "general_movdst_operand" "")
1547 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1548 (set (match_operand:SI 2 "arith_reg_dest" "")
1549 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1550 [(match_operand:SI 3 "arith_reg_operand" "")
1554 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1555 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1557 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1559 replace_rtx (operands[4], operands[0], operands[1]);
1563 [(set (match_operand 0 "any_register_operand" "")
1564 (match_operand 1 "any_register_operand" ""))
1565 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1566 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1567 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1568 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1569 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1570 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1571 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1572 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1573 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1574 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1575 && (REGNO_REG_CLASS (REGNO (operands[0]))
1576 == REGNO_REG_CLASS (REGNO (operands[2])))
1577 && (REGNO_REG_CLASS (REGNO (operands[1]))
1578 == REGNO_REG_CLASS (REGNO (operands[0])))"
1579 [(set (match_dup 0) (match_dup 3))
1580 (set (match_dup 4) (match_dup 5))]
1583 rtx_insn *insn1, *insn2;
1584 rtx replacements[4];
1586 /* We want to replace occurrences of operands[0] with operands[1] and
1587 operands[2] with operands[0] in operands[4]/operands[5].
1588 Doing just two replace_rtx calls naively would result in the second
1589 replacement undoing all that the first did if operands[1] and operands[2]
1590 are identical, so we must do this simultaneously. */
1591 replacements[0] = operands[0];
1592 replacements[1] = operands[1];
1593 replacements[2] = operands[2];
1594 replacements[3] = operands[0];
1595 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1596 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1597 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1600 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1601 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1602 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1603 /* The operands array is aliased to recog_data.operand, which gets
1604 clobbered by extract_insn, so finish with it now. */
1605 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1606 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1607 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1608 always uses emit_insn. */
1609 /* Check that we don't violate matching constraints or earlyclobbers. */
1610 basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2));
1611 insn1 = emit_insn (set1);
1612 extract_insn (insn1);
1613 if (! constrain_operands (1, get_preferred_alternatives (insn1, bb)))
1615 insn2 = emit (set2);
1616 if (GET_CODE (insn2) == BARRIER)
1618 extract_insn (insn2);
1619 if (! constrain_operands (1, get_preferred_alternatives (insn2, bb)))
1623 tmp = replacements[0];
1624 replacements[0] = replacements[1];
1625 replacements[1] = tmp;
1626 tmp = replacements[2];
1627 replacements[2] = replacements[3];
1628 replacements[3] = tmp;
1629 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1630 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1631 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1637 ;; The register allocator is rather clumsy in handling multi-way conditional
1638 ;; moves, so allow the combiner to make them, and we split them up after
1640 (define_insn_and_split "*movsicc_umin"
1641 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1642 (umin:SI (if_then_else:SI
1643 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1645 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1646 (match_operand:SI 3 "register_operand" "0"))
1647 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1648 (clobber (match_scratch:SI 5 "=&r"))]
1649 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1651 "TARGET_SHMEDIA && reload_completed"
1654 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1656 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1657 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1662 (define_insn "*movsicc_t_false"
1663 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1664 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1665 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1666 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1667 "TARGET_PRETEND_CMOVE
1668 && (arith_reg_operand (operands[1], SImode)
1669 || (immediate_operand (operands[1], SImode)
1670 && satisfies_constraint_I08 (operands[1])))"
1676 [(set_attr "type" "mt_group,arith") ;; poor approximation
1677 (set_attr "length" "4")])
1679 (define_insn "*movsicc_t_true"
1680 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1681 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1682 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1683 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1684 "TARGET_PRETEND_CMOVE
1685 && (arith_reg_operand (operands[1], SImode)
1686 || (immediate_operand (operands[1], SImode)
1687 && satisfies_constraint_I08 (operands[1])))"
1693 [(set_attr "type" "mt_group,arith") ;; poor approximation
1694 (set_attr "length" "4")])
1696 (define_expand "movsicc"
1697 [(set (match_operand:SI 0 "arith_reg_dest" "")
1698 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1699 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1700 (match_operand:SI 3 "arith_reg_operand" "")))]
1701 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1703 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1704 && GET_MODE (XEXP (operands[1], 0)) == SImode
1706 || (REG_P (XEXP (operands[1], 0))
1707 && REGNO (XEXP (operands[1], 0)) == T_REG))
1708 && XEXP (operands[1], 1) == const0_rtx)
1711 else if (TARGET_PRETEND_CMOVE)
1713 enum rtx_code code = GET_CODE (operands[1]);
1714 enum rtx_code new_code = code;
1715 rtx op0 = XEXP (operands[1], 0);
1716 rtx op1 = XEXP (operands[1], 1);
1718 if (! currently_expanding_to_rtl)
1722 case LT: case LE: case LEU: case LTU:
1723 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1726 new_code = reverse_condition (code);
1728 case EQ: case GT: case GE: case GEU: case GTU:
1733 sh_emit_scc_to_t (new_code, op0, op1);
1734 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1735 gen_rtx_REG (SImode, T_REG), const0_rtx);
1739 if (!can_create_pseudo_p ())
1742 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1743 GET_CODE (operands[1]),
1744 XEXP (operands[1], 0),
1745 XEXP (operands[1], 1));
1751 (define_expand "movqicc"
1752 [(set (match_operand:QI 0 "register_operand" "")
1753 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1754 (match_operand:QI 2 "register_operand" "")
1755 (match_operand:QI 3 "register_operand" "")))]
1758 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1759 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1760 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1761 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1765 ;; -------------------------------------------------------------------------
1766 ;; Addition instructions
1767 ;; -------------------------------------------------------------------------
1769 (define_expand "adddi3"
1770 [(set (match_operand:DI 0 "arith_reg_operand")
1771 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1772 (match_operand:DI 2 "arith_operand")))]
1777 operands[2] = force_reg (DImode, operands[2]);
1778 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1783 (define_insn "*adddi3_media"
1784 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1785 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1786 (match_operand:DI 2 "arith_operand" "r,I10")))]
1791 [(set_attr "type" "arith_media")])
1793 (define_insn "*adddisi3_media"
1794 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1795 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1796 (match_operand:DI 2 "arith_operand" "r,I10")))]
1801 [(set_attr "type" "arith_media")
1802 (set_attr "highpart" "ignore")])
1804 (define_insn "adddi3z_media"
1805 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1807 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1808 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1810 "addz.l %1, %N2, %0"
1811 [(set_attr "type" "arith_media")
1812 (set_attr "highpart" "ignore")])
1814 (define_insn_and_split "adddi3_compact"
1815 [(set (match_operand:DI 0 "arith_reg_dest")
1816 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1817 (match_operand:DI 2 "arith_reg_operand")))
1818 (clobber (reg:SI T_REG))]
1821 "&& can_create_pseudo_p ()"
1824 emit_insn (gen_clrt ());
1825 emit_insn (gen_addc (gen_lowpart (SImode, operands[0]),
1826 gen_lowpart (SImode, operands[1]),
1827 gen_lowpart (SImode, operands[2])));
1828 emit_insn (gen_addc (gen_highpart (SImode, operands[0]),
1829 gen_highpart (SImode, operands[1]),
1830 gen_highpart (SImode, operands[2])));
1835 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1836 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1837 (match_operand:SI 2 "arith_reg_operand" "r"))
1840 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1843 [(set_attr "type" "arith")])
1845 ;; A simplified version of the addc insn, where the exact value of the
1846 ;; T bit doesn't matter. This is easier for combine to pick up.
1847 ;; We allow a reg or 0 for one of the operands in order to be able to
1848 ;; do 'reg + T' sequences. Reload will load the constant 0 into the reg
1850 ;; FIXME: The load of constant 0 should be split out before reload, or else
1851 ;; it will be difficult to hoist or combine the constant load.
1852 (define_insn "*addc"
1853 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1854 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1855 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1856 (match_operand:SI 3 "t_reg_operand" "")))
1857 (clobber (reg:SI T_REG))]
1860 [(set_attr "type" "arith")])
1862 ;; Split 'reg + reg + 1' into a sett addc sequence, as it can be scheduled
1863 ;; better, if the sett insn can be done early.
1864 (define_insn_and_split "*addc_r_r_1"
1865 [(set (match_operand:SI 0 "arith_reg_dest" "")
1866 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
1867 (match_operand:SI 2 "arith_reg_operand" ""))
1869 (clobber (reg:SI T_REG))]
1873 [(set (reg:SI T_REG) (const_int 1))
1874 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
1876 (clobber (reg:SI T_REG))])])
1878 ;; Left shifts by one are usually done with an add insn to avoid T_REG
1879 ;; clobbers. Thus addc can also be used to do something like '(x << 1) + 1'.
1880 (define_insn_and_split "*addc_2r_1"
1881 [(set (match_operand:SI 0 "arith_reg_dest")
1882 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
1885 (clobber (reg:SI T_REG))]
1889 [(set (reg:SI T_REG) (const_int 1))
1890 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
1892 (clobber (reg:SI T_REG))])])
1894 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1895 ;; matched. Split this up into a simple sub add sequence, as this will save
1896 ;; us one sett insn.
1897 (define_insn_and_split "*minus_plus_one"
1898 [(set (match_operand:SI 0 "arith_reg_dest" "")
1899 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1900 (match_operand:SI 2 "arith_reg_operand" ""))
1905 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1906 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
1908 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
1909 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1910 ;; operation, as opposed to sequences such as
1914 ;; Even if the constant is not CSE-ed, a sequence such as
1917 ;; can be scheduled much better since the load of the constant can be
1918 ;; done earlier, before any comparison insns that store the result in
1920 (define_insn_and_split "*addc_t_r"
1921 [(set (match_operand:SI 0 "arith_reg_dest")
1922 (plus:SI (match_operand:SI 1 "t_reg_operand")
1923 (match_operand:SI 2 "arith_reg_operand")))
1924 (clobber (reg:SI T_REG))]
1928 [(parallel [(set (match_dup 0)
1929 (plus:SI (plus:SI (match_dup 2) (const_int 0))
1931 (clobber (reg:SI T_REG))])])
1933 (define_insn_and_split "*addc_r_t"
1934 [(set (match_operand:SI 0 "arith_reg_dest")
1935 (plus:SI (match_operand:SI 1 "arith_reg_operand")
1936 (match_operand:SI 2 "t_reg_operand")))
1937 (clobber (reg:SI T_REG))]
1941 [(parallel [(set (match_dup 0)
1942 (plus:SI (plus:SI (match_dup 1) (const_int 0))
1944 (clobber (reg:SI T_REG))])])
1946 ;; Use shlr-addc to do 'reg + (reg & 1)'.
1947 (define_insn_and_split "*addc_r_lsb"
1948 [(set (match_operand:SI 0 "arith_reg_dest")
1949 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1951 (match_operand:SI 2 "arith_reg_operand")))
1952 (clobber (reg:SI T_REG))]
1955 "&& can_create_pseudo_p ()"
1956 [(parallel [(set (match_dup 0) (plus:SI (reg:SI T_REG) (match_dup 2)))
1957 (clobber (reg:SI T_REG))])]
1959 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[1]));
1962 ;; Use shlr-addc to do 'reg + reg + (reg & 1)'.
1963 (define_insn_and_split "*addc_r_r_lsb"
1964 [(set (match_operand:SI 0 "arith_reg_dest")
1965 (plus:SI (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1967 (match_operand:SI 2 "arith_reg_operand"))
1968 (match_operand:SI 3 "arith_reg_operand")))
1969 (clobber (reg:SI T_REG))]
1972 "&& can_create_pseudo_p ()"
1973 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
1975 (clobber (reg:SI T_REG))])]
1977 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[1]));
1980 ;; Canonicalize 'reg + (reg & 1) + reg' into 'reg + reg + (reg & 1)'.
1981 (define_insn_and_split "*addc_r_lsb_r"
1982 [(set (match_operand:SI 0 "arith_reg_dest")
1983 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1985 (plus:SI (match_operand:SI 2 "arith_reg_operand")
1986 (match_operand:SI 3 "arith_reg_operand"))))
1987 (clobber (reg:SI T_REG))]
1990 "&& can_create_pseudo_p ()"
1991 [(parallel [(set (match_dup 0)
1992 (plus:SI (plus:SI (and:SI (match_dup 1) (const_int 1))
1995 (clobber (reg:SI T_REG))])])
1997 ;; Canonicalize '2 * reg + (reg & 1)' into 'reg + reg + (reg & 1)'.
1998 (define_insn_and_split "*addc_2r_lsb"
1999 [(set (match_operand:SI 0 "arith_reg_dest")
2000 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
2002 (mult:SI (match_operand:SI 2 "arith_reg_operand")
2004 (clobber (reg:SI T_REG))]
2007 "&& can_create_pseudo_p ()"
2008 [(parallel [(set (match_dup 0)
2009 (plus:SI (plus:SI (and:SI (match_dup 1) (const_int 1))
2012 (clobber (reg:SI T_REG))])])
2014 ;; Use shll-addc to do 'reg + ((unsigned int)reg >> 31)'.
2015 (define_insn_and_split "*addc_r_msb"
2016 [(set (match_operand:SI 0 "arith_reg_dest")
2017 (plus:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
2019 (match_operand:SI 2 "arith_reg_operand")))
2020 (clobber (reg:SI T_REG))]
2023 "&& can_create_pseudo_p ()"
2024 [(parallel [(set (match_dup 0) (plus:SI (reg:SI T_REG) (match_dup 2)))
2025 (clobber (reg:SI T_REG))])]
2027 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[1]));
2030 ;; Use shll-addc to do 'reg + reg + ((unsigned int)reg >> 31)'.
2031 (define_insn_and_split "*addc_r_r_msb"
2032 [(set (match_operand:SI 0 "arith_reg_dest")
2033 (plus:SI (plus:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
2035 (match_operand:SI 2 "arith_reg_operand"))
2036 (match_operand:SI 3 "arith_reg_operand")))
2037 (clobber (reg:SI T_REG))]
2040 "&& can_create_pseudo_p ()"
2041 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
2043 (clobber (reg:SI T_REG))])]
2045 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[1]));
2048 ;; Canonicalize '2 * reg + ((unsigned int)reg >> 31)'
2049 ;; into 'reg + reg + (reg & 1)'.
2050 (define_insn_and_split "*addc_2r_msb"
2051 [(set (match_operand:SI 0 "arith_reg_dest")
2052 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
2054 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
2056 (clobber (reg:SI T_REG))]
2059 "&& can_create_pseudo_p ()"
2060 [(parallel [(set (match_dup 0)
2061 (plus:SI (plus:SI (lshiftrt:SI (match_dup 2) (const_int 31))
2064 (clobber (reg:SI T_REG))])])
2066 (define_expand "addsi3"
2067 [(set (match_operand:SI 0 "arith_reg_operand" "")
2068 (plus:SI (match_operand:SI 1 "arith_operand" "")
2069 (match_operand:SI 2 "arith_operand" "")))]
2073 operands[1] = force_reg (SImode, operands[1]);
2076 (define_insn "addsi3_media"
2077 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2078 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
2079 (match_operand:SI 2 "arith_operand" "r,I10")))]
2084 [(set_attr "type" "arith_media")
2085 (set_attr "highpart" "ignore")])
2087 (define_insn "addsidi3_media"
2088 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
2089 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
2091 (match_operand:SI 2 "arith_operand"
2097 [(set_attr "type" "arith_media")
2098 (set_attr "highpart" "ignore")])
2100 (define_insn "*addsi3_compact"
2101 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2102 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
2103 (match_operand:SI 2 "arith_operand" "rI08")))]
2106 [(set_attr "type" "arith")])
2108 ;; -------------------------------------------------------------------------
2109 ;; Subtraction instructions
2110 ;; -------------------------------------------------------------------------
2112 (define_expand "subdi3"
2113 [(set (match_operand:DI 0 "arith_reg_operand" "")
2114 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
2115 (match_operand:DI 2 "arith_reg_operand" "")))]
2120 operands[1] = force_reg (DImode, operands[1]);
2121 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
2126 (define_insn "*subdi3_media"
2127 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2128 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2129 (match_operand:DI 2 "arith_reg_operand" "r")))]
2132 [(set_attr "type" "arith_media")])
2134 (define_insn "subdisi3_media"
2135 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
2136 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2137 (match_operand:DI 2 "arith_reg_operand" "r")))]
2140 [(set_attr "type" "arith_media")
2141 (set_attr "highpart" "ignore")])
2143 (define_insn_and_split "subdi3_compact"
2144 [(set (match_operand:DI 0 "arith_reg_dest")
2145 (minus:DI (match_operand:DI 1 "arith_reg_operand")
2146 (match_operand:DI 2 "arith_reg_operand")))
2147 (clobber (reg:SI T_REG))]
2150 "&& can_create_pseudo_p ()"
2153 emit_insn (gen_clrt ());
2154 emit_insn (gen_subc (gen_lowpart (SImode, operands[0]),
2155 gen_lowpart (SImode, operands[1]),
2156 gen_lowpart (SImode, operands[2])));
2157 emit_insn (gen_subc (gen_highpart (SImode, operands[0]),
2158 gen_highpart (SImode, operands[1]),
2159 gen_highpart (SImode, operands[2])));
2164 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2165 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2166 (match_operand:SI 2 "arith_reg_operand" "r"))
2169 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
2174 [(set_attr "type" "arith")])
2176 ;; A simplified version of the subc insn, where the exact value of the
2177 ;; T bit doesn't matter. This is easier for combine to pick up.
2178 ;; We allow a reg or 0 for one of the operands in order to be able to
2179 ;; do 'reg - T' sequences. Reload will load the constant 0 into the reg
2181 (define_insn "*subc"
2182 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2183 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2184 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
2185 (match_operand:SI 3 "t_reg_operand" "")))
2186 (clobber (reg:SI T_REG))]
2189 [(set_attr "type" "arith")])
2191 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
2192 ;; better, if the sett insn can be done early.
2193 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
2194 (define_insn_and_split "*subc"
2195 [(set (match_operand:SI 0 "arith_reg_dest" "")
2196 (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
2197 (match_operand:SI 2 "arith_reg_operand" "")))
2198 (clobber (reg:SI T_REG))]
2202 [(set (reg:SI T_REG) (const_int 1))
2203 (parallel [(set (match_dup 0)
2204 (minus:SI (minus:SI (match_dup 2) (match_dup 1))
2206 (clobber (reg:SI T_REG))])])
2208 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
2209 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2210 ;; operation, as opposed to sequences such as
2214 ;; Even if the constant is not CSE-ed, a sequence such as
2217 ;; can be scheduled much better since the load of the constant can be
2218 ;; done earlier, before any comparison insns that store the result in
2220 (define_insn_and_split "*subc"
2221 [(set (match_operand:SI 0 "arith_reg_dest" "")
2222 (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2223 (match_operand:SI 2 "t_reg_operand" "")))
2224 (clobber (reg:SI T_REG))]
2228 [(parallel [(set (match_dup 0)
2229 (minus:SI (minus:SI (match_dup 1) (const_int 0))
2231 (clobber (reg:SI T_REG))])])
2233 (define_insn "*subsi3_internal"
2234 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2235 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2236 (match_operand:SI 2 "arith_reg_operand" "r")))]
2239 [(set_attr "type" "arith")])
2241 (define_insn_and_split "*subsi3_media"
2242 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2243 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2244 (match_operand:SI 2 "extend_reg_operand" "r")))]
2246 && (operands[1] != constm1_rtx
2247 || (GET_CODE (operands[2]) != TRUNCATE
2248 && GET_CODE (operands[2]) != SUBREG))"
2250 "operands[1] == constm1_rtx"
2251 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2253 [(set_attr "type" "arith_media")
2254 (set_attr "highpart" "ignore")])
2257 [(set (match_operand:SI 0 "arith_reg_dest" "")
2258 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2259 "general_extend_operand"
2261 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2262 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2263 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2267 [(set (match_operand:SI 0 "arith_reg_dest" "")
2268 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2269 "general_extend_operand"
2271 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
2272 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2273 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2281 ;; since this will sometimes save one instruction.
2282 ;; Otherwise we might get a sequence like
2286 ;; if the source and dest regs are the same.
2287 (define_expand "subsi3"
2288 [(set (match_operand:SI 0 "arith_reg_operand" "")
2289 (minus:SI (match_operand:SI 1 "arith_operand" "")
2290 (match_operand:SI 2 "arith_reg_operand" "")))]
2293 if (TARGET_SH1 && CONST_INT_P (operands[1]))
2295 emit_insn (gen_negsi2 (operands[0], operands[2]));
2296 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2301 if (!can_create_pseudo_p ()
2302 && ! arith_reg_or_0_operand (operands[1], SImode))
2304 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2305 operands[1] = force_reg (SImode, operands[1]);
2309 ;; -------------------------------------------------------------------------
2310 ;; Division instructions
2311 ;; -------------------------------------------------------------------------
2313 ;; We take advantage of the library routines which don't clobber as many
2314 ;; registers as a normal function call would.
2316 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2317 ;; also has an effect on the register that holds the address of the sfunc.
2318 ;; To make this work, we have an extra dummy insn that shows the use
2319 ;; of this register for reorg.
2321 (define_insn "use_sfunc_addr"
2322 [(set (reg:SI PR_REG)
2323 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2324 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2326 [(set_attr "length" "0")])
2328 (define_insn "udivsi3_sh2a"
2329 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2330 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2331 (match_operand:SI 2 "arith_reg_operand" "z")))]
2334 [(set_attr "type" "arith")
2335 (set_attr "in_delay_slot" "no")])
2337 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2338 ;; hard register 0. If we used hard register 0, then the next instruction
2339 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
2340 ;; gets allocated to a stack slot that needs its address reloaded, then
2341 ;; there is nothing to prevent reload from using r0 to reload the address.
2342 ;; This reload would clobber the value in r0 we are trying to store.
2343 ;; If we let reload allocate r0, then this problem can never happen.
2344 (define_insn "udivsi3_i1"
2345 [(set (match_operand:SI 0 "register_operand" "=z")
2346 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2347 (clobber (reg:SI T_REG))
2348 (clobber (reg:SI PR_REG))
2349 (clobber (reg:SI R1_REG))
2350 (clobber (reg:SI R4_REG))
2351 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2352 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2354 [(set_attr "type" "sfunc")
2355 (set_attr "needs_delay_slot" "yes")])
2357 ; Since shmedia-nofpu code could be linked against shcompact code, and
2358 ; the udivsi3 libcall has the same name, we must consider all registers
2359 ; clobbered that are in the union of the registers clobbered by the
2360 ; shmedia and the shcompact implementation. Note, if the shcompact
2361 ; implementation actually used shcompact code, we'd need to clobber
2362 ; also r23 and fr23.
2363 (define_insn "udivsi3_i1_media"
2364 [(set (match_operand:SI 0 "register_operand" "=z")
2365 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2366 (clobber (reg:SI T_MEDIA_REG))
2367 (clobber (reg:SI PR_MEDIA_REG))
2368 (clobber (reg:SI R20_REG))
2369 (clobber (reg:SI R21_REG))
2370 (clobber (reg:SI R22_REG))
2371 (clobber (reg:DI TR0_REG))
2372 (clobber (reg:DI TR1_REG))
2373 (clobber (reg:DI TR2_REG))
2374 (use (match_operand 1 "target_reg_operand" "b"))]
2375 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2377 [(set_attr "type" "sfunc")
2378 (set_attr "needs_delay_slot" "yes")])
2380 (define_expand "udivsi3_i4_media"
2382 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2384 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2385 (set (match_dup 5) (float:DF (match_dup 3)))
2386 (set (match_dup 6) (float:DF (match_dup 4)))
2387 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2388 (set (match_dup 8) (fix:DI (match_dup 7)))
2389 (set (match_operand:SI 0 "register_operand" "")
2390 (truncate:SI (match_dup 8)))]
2391 "TARGET_SHMEDIA_FPU"
2393 operands[3] = gen_reg_rtx (DImode);
2394 operands[4] = gen_reg_rtx (DImode);
2395 operands[5] = gen_reg_rtx (DFmode);
2396 operands[6] = gen_reg_rtx (DFmode);
2397 operands[7] = gen_reg_rtx (DFmode);
2398 operands[8] = gen_reg_rtx (DImode);
2401 (define_insn "udivsi3_i4"
2402 [(set (match_operand:SI 0 "register_operand" "=y")
2403 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2404 (clobber (reg:SI T_REG))
2405 (clobber (reg:SI PR_REG))
2406 (clobber (reg:DF DR0_REG))
2407 (clobber (reg:DF DR2_REG))
2408 (clobber (reg:DF DR4_REG))
2409 (clobber (reg:SI R0_REG))
2410 (clobber (reg:SI R1_REG))
2411 (clobber (reg:SI R4_REG))
2412 (clobber (reg:SI R5_REG))
2413 (clobber (reg:SI FPSCR_STAT_REG))
2414 (use (reg:SI FPSCR_MODES_REG))
2415 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2416 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2418 [(set_attr "type" "sfunc")
2419 (set_attr "fp_mode" "double")
2420 (set_attr "needs_delay_slot" "yes")])
2422 (define_insn "udivsi3_i4_single"
2423 [(set (match_operand:SI 0 "register_operand" "=y")
2424 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2425 (clobber (reg:SI T_REG))
2426 (clobber (reg:SI PR_REG))
2427 (clobber (reg:DF DR0_REG))
2428 (clobber (reg:DF DR2_REG))
2429 (clobber (reg:DF DR4_REG))
2430 (clobber (reg:SI R0_REG))
2431 (clobber (reg:SI R1_REG))
2432 (clobber (reg:SI R4_REG))
2433 (clobber (reg:SI R5_REG))
2434 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2435 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2436 && TARGET_FPU_SINGLE"
2438 [(set_attr "type" "sfunc")
2439 (set_attr "needs_delay_slot" "yes")])
2441 (define_insn "udivsi3_i4_int"
2442 [(set (match_operand:SI 0 "register_operand" "=z")
2443 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2444 (clobber (reg:SI T_REG))
2445 (clobber (reg:SI R1_REG))
2446 (clobber (reg:SI PR_REG))
2447 (clobber (reg:SI MACH_REG))
2448 (clobber (reg:SI MACL_REG))
2449 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2452 [(set_attr "type" "sfunc")
2453 (set_attr "needs_delay_slot" "yes")])
2456 (define_expand "udivsi3"
2457 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2458 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2459 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2460 (parallel [(set (match_operand:SI 0 "register_operand" "")
2461 (udiv:SI (reg:SI R4_REG)
2463 (clobber (reg:SI T_REG))
2464 (clobber (reg:SI PR_REG))
2465 (clobber (reg:SI R4_REG))
2466 (use (match_dup 3))])]
2471 operands[3] = gen_reg_rtx (Pmode);
2472 /* Emit the move of the address to a pseudo outside of the libcall. */
2473 if (TARGET_DIVIDE_CALL_TABLE)
2475 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2476 that causes problems when the divide code is supposed to come from a
2477 separate library. Division by zero is undefined, so dividing 1 can be
2478 implemented by comparing with the divisor. */
2479 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2481 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2482 emit_insn (gen_cstoresi4 (operands[0], test,
2483 operands[1], operands[2]));
2486 else if (operands[2] == const0_rtx)
2488 emit_move_insn (operands[0], operands[2]);
2491 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2492 last = gen_udivsi3_i4_int (operands[0], operands[3]);
2494 else if (TARGET_DIVIDE_CALL_FP)
2496 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2497 if (TARGET_FPU_SINGLE)
2498 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2500 last = gen_udivsi3_i4 (operands[0], operands[3]);
2502 else if (TARGET_SHMEDIA_FPU)
2504 operands[1] = force_reg (SImode, operands[1]);
2505 operands[2] = force_reg (SImode, operands[2]);
2506 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2509 else if (TARGET_SH2A)
2511 operands[1] = force_reg (SImode, operands[1]);
2512 operands[2] = force_reg (SImode, operands[2]);
2513 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2516 else if (TARGET_SH5)
2518 function_symbol (operands[3],
2519 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2523 last = gen_udivsi3_i1_media (operands[0], operands[3]);
2524 else if (TARGET_FPU_ANY)
2525 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2527 last = gen_udivsi3_i1 (operands[0], operands[3]);
2531 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2532 last = gen_udivsi3_i1 (operands[0], operands[3]);
2534 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2535 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2540 (define_insn "divsi3_sh2a"
2541 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2542 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2543 (match_operand:SI 2 "arith_reg_operand" "z")))]
2546 [(set_attr "type" "arith")
2547 (set_attr "in_delay_slot" "no")])
2549 (define_insn "divsi3_i1"
2550 [(set (match_operand:SI 0 "register_operand" "=z")
2551 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2552 (clobber (reg:SI T_REG))
2553 (clobber (reg:SI PR_REG))
2554 (clobber (reg:SI R1_REG))
2555 (clobber (reg:SI R2_REG))
2556 (clobber (reg:SI R3_REG))
2557 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2558 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2560 [(set_attr "type" "sfunc")
2561 (set_attr "needs_delay_slot" "yes")])
2563 (define_insn "divsi3_i1_media"
2564 [(set (match_operand:SI 0 "register_operand" "=z")
2565 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2566 (clobber (reg:SI T_MEDIA_REG))
2567 (clobber (reg:SI PR_MEDIA_REG))
2568 (clobber (reg:SI R1_REG))
2569 (clobber (reg:SI R20_REG))
2570 (clobber (reg:SI R21_REG))
2571 (clobber (reg:SI TR0_REG))
2572 (use (match_operand 1 "target_reg_operand" "b"))]
2573 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2575 [(set_attr "type" "sfunc")])
2577 (define_insn "divsi3_media_2"
2578 [(set (match_operand:SI 0 "register_operand" "=z")
2579 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2580 (clobber (reg:SI T_MEDIA_REG))
2581 (clobber (reg:SI PR_MEDIA_REG))
2582 (clobber (reg:SI R1_REG))
2583 (clobber (reg:SI R21_REG))
2584 (clobber (reg:SI TR0_REG))
2585 (use (reg:SI R20_REG))
2586 (use (match_operand 1 "target_reg_operand" "b"))]
2587 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2589 [(set_attr "type" "sfunc")])
2591 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2592 ;; hard reg clobbers and data dependencies that we need when we want
2593 ;; to rematerialize the division into a call.
2594 (define_insn_and_split "divsi_inv_call"
2595 [(set (match_operand:SI 0 "register_operand" "=r")
2596 (div:SI (match_operand:SI 1 "register_operand" "r")
2597 (match_operand:SI 2 "register_operand" "r")))
2598 (clobber (reg:SI R4_REG))
2599 (clobber (reg:SI R5_REG))
2600 (clobber (reg:SI T_MEDIA_REG))
2601 (clobber (reg:SI PR_MEDIA_REG))
2602 (clobber (reg:SI R1_REG))
2603 (clobber (reg:SI R21_REG))
2604 (clobber (reg:SI TR0_REG))
2605 (clobber (reg:SI R20_REG))
2606 (use (match_operand:SI 3 "register_operand" "r"))]
2609 "&& (reload_in_progress || reload_completed)"
2610 [(set (match_dup 0) (match_dup 3))]
2612 [(set_attr "highpart" "must_split")])
2614 ;; This is the combiner pattern for -mdiv=inv:call .
2615 (define_insn_and_split "*divsi_inv_call_combine"
2616 [(set (match_operand:SI 0 "register_operand" "=z")
2617 (div:SI (match_operand:SI 1 "register_operand" "r")
2618 (match_operand:SI 2 "register_operand" "r")))
2619 (clobber (reg:SI R4_REG))
2620 (clobber (reg:SI R5_REG))
2621 (clobber (reg:SI T_MEDIA_REG))
2622 (clobber (reg:SI PR_MEDIA_REG))
2623 (clobber (reg:SI R1_REG))
2624 (clobber (reg:SI R21_REG))
2625 (clobber (reg:SI TR0_REG))
2626 (clobber (reg:SI R20_REG))
2627 (use (unspec:SI [(match_dup 1)
2628 (match_operand:SI 3 "" "")
2629 (unspec:SI [(match_operand:SI 4 "" "")
2631 (match_operand:DI 5 "" "")]
2633 (match_operand:DI 6 "" "")
2636 UNSPEC_DIV_INV_M3))]
2639 "&& (reload_in_progress || reload_completed)"
2642 const char *name = sh_divsi3_libfunc;
2643 enum sh_function_kind kind = SFUNC_GOT;
2646 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2647 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2648 while (TARGET_DIVIDE_INV_CALL2)
2650 rtx x = operands[3];
2652 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2654 x = XVECEXP (x, 0, 0);
2655 name = "__sdivsi3_2";
2656 kind = SFUNC_STATIC;
2657 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2660 sym = function_symbol (NULL, name, kind);
2661 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2664 [(set_attr "highpart" "must_split")])
2666 (define_expand "divsi3_i4_media"
2667 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2668 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2669 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2670 (set (match_operand:SI 0 "register_operand" "=r")
2671 (fix:SI (match_dup 5)))]
2672 "TARGET_SHMEDIA_FPU"
2674 operands[3] = gen_reg_rtx (DFmode);
2675 operands[4] = gen_reg_rtx (DFmode);
2676 operands[5] = gen_reg_rtx (DFmode);
2679 (define_insn "divsi3_i4"
2680 [(set (match_operand:SI 0 "register_operand" "=y")
2681 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2682 (clobber (reg:SI PR_REG))
2683 (clobber (reg:DF DR0_REG))
2684 (clobber (reg:DF DR2_REG))
2685 (clobber (reg:SI FPSCR_STAT_REG))
2686 (use (reg:SI FPSCR_MODES_REG))
2687 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2688 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2690 [(set_attr "type" "sfunc")
2691 (set_attr "fp_mode" "double")
2692 (set_attr "needs_delay_slot" "yes")])
2694 (define_insn "divsi3_i4_single"
2695 [(set (match_operand:SI 0 "register_operand" "=y")
2696 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2697 (clobber (reg:SI PR_REG))
2698 (clobber (reg:DF DR0_REG))
2699 (clobber (reg:DF DR2_REG))
2700 (clobber (reg:SI R2_REG))
2701 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2702 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2703 && TARGET_FPU_SINGLE"
2705 [(set_attr "type" "sfunc")
2706 (set_attr "needs_delay_slot" "yes")])
2708 (define_insn "divsi3_i4_int"
2709 [(set (match_operand:SI 0 "register_operand" "=z")
2710 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2711 (clobber (reg:SI T_REG))
2712 (clobber (reg:SI PR_REG))
2713 (clobber (reg:SI R1_REG))
2714 (clobber (reg:SI MACH_REG))
2715 (clobber (reg:SI MACL_REG))
2716 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2719 [(set_attr "type" "sfunc")
2720 (set_attr "needs_delay_slot" "yes")])
2722 (define_expand "divsi3"
2723 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2724 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2725 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2726 (parallel [(set (match_operand:SI 0 "register_operand" "")
2727 (div:SI (reg:SI R4_REG)
2729 (clobber (reg:SI T_REG))
2730 (clobber (reg:SI PR_REG))
2731 (clobber (reg:SI R1_REG))
2732 (clobber (reg:SI R2_REG))
2733 (clobber (reg:SI R3_REG))
2734 (use (match_dup 3))])]
2739 operands[3] = gen_reg_rtx (Pmode);
2740 /* Emit the move of the address to a pseudo outside of the libcall. */
2741 if (TARGET_DIVIDE_CALL_TABLE)
2743 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2744 last = gen_divsi3_i4_int (operands[0], operands[3]);
2746 else if (TARGET_DIVIDE_CALL_FP)
2748 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2749 if (TARGET_FPU_SINGLE)
2750 last = gen_divsi3_i4_single (operands[0], operands[3]);
2752 last = gen_divsi3_i4 (operands[0], operands[3]);
2754 else if (TARGET_SH2A)
2756 operands[1] = force_reg (SImode, operands[1]);
2757 operands[2] = force_reg (SImode, operands[2]);
2758 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2761 else if (TARGET_DIVIDE_INV)
2763 rtx dividend = operands[1];
2764 rtx divisor = operands[2];
2766 rtx nsb_res = gen_reg_rtx (DImode);
2767 rtx norm64 = gen_reg_rtx (DImode);
2768 rtx tab_ix = gen_reg_rtx (DImode);
2769 rtx norm32 = gen_reg_rtx (SImode);
2770 rtx i92 = force_reg (DImode, GEN_INT (92));
2771 rtx scratch0a = gen_reg_rtx (DImode);
2772 rtx scratch0b = gen_reg_rtx (DImode);
2773 rtx inv0 = gen_reg_rtx (SImode);
2774 rtx scratch1a = gen_reg_rtx (DImode);
2775 rtx scratch1b = gen_reg_rtx (DImode);
2776 rtx shift = gen_reg_rtx (DImode);
2778 rtx inv1 = gen_reg_rtx (SImode);
2779 rtx scratch2a = gen_reg_rtx (DImode);
2780 rtx scratch2b = gen_reg_rtx (SImode);
2781 rtx inv2 = gen_reg_rtx (SImode);
2782 rtx scratch3a = gen_reg_rtx (DImode);
2783 rtx scratch3b = gen_reg_rtx (DImode);
2784 rtx scratch3c = gen_reg_rtx (DImode);
2785 rtx scratch3d = gen_reg_rtx (SImode);
2786 rtx scratch3e = gen_reg_rtx (DImode);
2787 rtx result = gen_reg_rtx (SImode);
2789 if (! arith_reg_or_0_operand (dividend, SImode))
2790 dividend = force_reg (SImode, dividend);
2791 if (! arith_reg_operand (divisor, SImode))
2792 divisor = force_reg (SImode, divisor);
2793 if (flag_pic && Pmode != DImode)
2795 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2796 tab_base = gen_datalabel_ref (tab_base);
2797 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2801 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2802 tab_base = gen_datalabel_ref (tab_base);
2803 tab_base = force_reg (DImode, tab_base);
2805 if (TARGET_DIVIDE_INV20U)
2806 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2808 i2p27 = GEN_INT (0);
2809 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2810 i43 = force_reg (DImode, GEN_INT (43));
2813 emit_insn (gen_nsbdi (nsb_res,
2814 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2815 emit_insn (gen_ashldi3_media (norm64,
2816 gen_rtx_SUBREG (DImode, divisor, 0),
2818 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2819 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2820 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2821 inv0, scratch0a, scratch0b,
2822 scratch1a, scratch1b));
2823 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2824 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2826 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2828 scratch3a, scratch3b, scratch3c,
2829 scratch2a, scratch2b, scratch3d, scratch3e));
2830 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2831 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2832 else if (TARGET_DIVIDE_INV_FP)
2833 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2834 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2835 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2836 gen_reg_rtx (DFmode)));
2838 emit_move_insn (operands[0], result);
2841 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2843 operands[1] = force_reg (SImode, operands[1]);
2844 operands[2] = force_reg (SImode, operands[2]);
2845 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2848 else if (TARGET_SH5)
2850 if (TARGET_DIVIDE_CALL2)
2852 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2853 tab_base = gen_datalabel_ref (tab_base);
2854 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2856 if (TARGET_FPU_ANY && TARGET_SH1)
2857 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2858 else if (TARGET_DIVIDE_CALL2)
2859 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2861 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2864 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2865 (operands[0], operands[3]));
2866 else if (TARGET_FPU_ANY)
2867 last = gen_divsi3_i4_single (operands[0], operands[3]);
2869 last = gen_divsi3_i1 (operands[0], operands[3]);
2873 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2874 last = gen_divsi3_i1 (operands[0], operands[3]);
2876 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2877 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2882 ;; operands: scratch, tab_base, tab_ix
2883 ;; These are unspecs because we could generate an indexed addressing mode
2884 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2885 ;; confuse reload. See PR27117.
2886 (define_insn "divsi_inv_qitable"
2887 [(set (match_operand:DI 0 "register_operand" "=r")
2888 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2889 (match_operand:DI 2 "register_operand" "r")]
2890 UNSPEC_DIV_INV_TABLE)))]
2893 [(set_attr "type" "load_media")
2894 (set_attr "highpart" "user")])
2896 ;; operands: scratch, tab_base, tab_ix
2897 (define_insn "divsi_inv_hitable"
2898 [(set (match_operand:DI 0 "register_operand" "=r")
2899 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2900 (match_operand:DI 2 "register_operand" "r")]
2901 UNSPEC_DIV_INV_TABLE)))]
2904 [(set_attr "type" "load_media")
2905 (set_attr "highpart" "user")])
2907 ;; operands: inv0, tab_base, tab_ix, norm32
2908 ;; scratch equiv in sdivsi3_2: r19, r21
2909 (define_expand "divsi_inv_m0"
2910 [(set (match_operand:SI 0 "register_operand" "=r")
2911 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2912 (match_operand:DI 2 "register_operand" "r")
2913 (match_operand:SI 3 "register_operand" "r")]
2915 (clobber (match_operand:DI 4 "register_operand" "=r"))
2916 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2923 ldx.ub r20, r21, r19 // u0.8
2925 muls.l r25, r19, r19 // s2.38
2926 ldx.w r20, r21, r21 // s2.14
2927 shari r19, 24, r19 // truncate to s2.14
2928 sub r21, r19, r19 // some 11 bit inverse in s1.14
2931 rtx inv0 = operands[0];
2932 rtx tab_base = operands[1];
2933 rtx tab_ix = operands[2];
2934 rtx norm32 = operands[3];
2935 rtx scratch0 = operands[4];
2936 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2937 rtx scratch1 = operands[5];
2939 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2940 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2941 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2942 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2943 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2944 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2948 ;; operands: inv1, tab_base, tab_ix, norm32
2949 (define_insn_and_split "divsi_inv_m1"
2950 [(set (match_operand:SI 0 "register_operand" "=r")
2951 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2952 (match_operand:DI 2 "register_operand" "r")
2953 (match_operand:SI 3 "register_operand" "r")]
2955 (clobber (match_operand:SI 4 "register_operand" "=r"))
2956 (clobber (match_operand:DI 5 "register_operand" "=r"))
2957 (clobber (match_operand:DI 6 "register_operand" "=r"))
2958 (clobber (match_operand:DI 7 "register_operand" "=r"))
2959 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2962 "&& !can_create_pseudo_p ()"
2966 muls.l r19, r19, r18 // u0.28
2967 muls.l r25, r18, r18 // s2.58
2968 shlli r19, 45, r0 // multiply by two and convert to s2.58
2970 shari r18, 28, r18 // some 18 bit inverse in s1.30
2973 rtx inv1 = operands[0];
2974 rtx tab_base = operands[1];
2975 rtx tab_ix = operands[2];
2976 rtx norm32 = operands[3];
2977 rtx inv0 = operands[4];
2978 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2979 rtx scratch0a = operands[5];
2980 rtx scratch0b = operands[6];
2981 rtx scratch0 = operands[7];
2982 rtx scratch1 = operands[8];
2983 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2985 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2986 scratch0a, scratch0b));
2987 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2988 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2989 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2990 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2991 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2995 ;; operands: inv2, norm32, inv1, i92
2996 (define_insn_and_split "divsi_inv_m2"
2997 [(set (match_operand:SI 0 "register_operand" "=r")
2998 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2999 (match_operand:SI 2 "register_operand" "r")
3000 (match_operand:DI 3 "register_operand" "r")]
3002 (clobber (match_operand:DI 4 "register_operand" "=r"))]
3005 "&& !can_create_pseudo_p ()"
3009 muls.l r18, r25, r0 // s2.60
3010 shari r0, 16, r0 // s-16.44
3012 muls.l r0, r18, r19 // s-16.74
3013 shari r19, 30, r19 // s-16.44
3015 rtx inv2 = operands[0];
3016 rtx norm32 = operands[1];
3017 rtx inv1 = operands[2];
3018 rtx i92 = operands[3];
3019 rtx scratch0 = operands[4];
3020 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3022 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
3023 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
3024 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
3025 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
3026 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
3030 (define_insn_and_split "divsi_inv_m3"
3031 [(set (match_operand:SI 0 "register_operand" "=r")
3032 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3033 (match_operand:SI 2 "register_operand" "r")
3034 (match_operand:SI 3 "register_operand" "r")
3035 (match_operand:DI 4 "register_operand" "r")
3036 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
3037 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
3039 (clobber (match_operand:DI 7 "register_operand" "=r"))
3040 (clobber (match_operand:DI 8 "register_operand" "=r"))
3041 (clobber (match_operand:DI 9 "register_operand" "=r"))
3042 (clobber (match_operand:DI 10 "register_operand" "=r"))
3043 (clobber (match_operand:SI 11 "register_operand" "=r"))
3044 (clobber (match_operand:SI 12 "register_operand" "=r"))
3045 (clobber (match_operand:DI 13 "register_operand" "=r"))]
3048 "&& !can_create_pseudo_p ()"
3052 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
3053 r0: scratch0 r19: scratch1 r21: scratch2
3055 muls.l r18, r4, r25 // s32.30
3056 muls.l r19, r4, r19 // s15.30
3058 shari r19, 14, r19 // s18.-14
3064 rtx result = operands[0];
3065 rtx dividend = operands[1];
3066 rtx inv1 = operands[2];
3067 rtx inv2 = operands[3];
3068 rtx shift = operands[4];
3069 rtx scratch0 = operands[7];
3070 rtx scratch1 = operands[8];
3071 rtx scratch2 = operands[9];
3073 if (satisfies_constraint_N (dividend))
3075 emit_move_insn (result, dividend);
3079 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
3080 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
3081 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
3082 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
3083 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
3084 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
3085 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
3089 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
3090 ;; inv1: tab_base, tab_ix, norm32
3091 ;; inv2: norm32, inv1, i92
3092 (define_insn_and_split "divsi_inv_m1_3"
3093 [(set (match_operand:SI 0 "register_operand" "=r")
3094 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3095 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
3096 (match_operand:DI 3 "register_operand" "r")
3097 (match_operand:SI 4 "register_operand" "r")]
3099 (unspec:SI [(match_dup 4)
3100 (unspec:SI [(match_dup 2)
3102 (match_dup 4)] UNSPEC_DIV_INV_M1)
3103 (match_operand:SI 5 "" "")]
3105 (match_operand:DI 6 "register_operand" "r")
3106 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
3107 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
3109 (clobber (match_operand:DI 9 "register_operand" "=r"))
3110 (clobber (match_operand:DI 10 "register_operand" "=r"))
3111 (clobber (match_operand:DI 11 "register_operand" "=r"))
3112 (clobber (match_operand:DI 12 "register_operand" "=r"))
3113 (clobber (match_operand:SI 13 "register_operand" "=r"))
3114 (clobber (match_operand:SI 14 "register_operand" "=r"))
3115 (clobber (match_operand:DI 15 "register_operand" "=r"))]
3117 && (TARGET_DIVIDE_INV_MINLAT
3118 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3120 "&& !can_create_pseudo_p ()"
3123 rtx result = operands[0];
3124 rtx dividend = operands[1];
3125 rtx tab_base = operands[2];
3126 rtx tab_ix = operands[3];
3127 rtx norm32 = operands[4];
3128 /* rtx i92 = operands[5]; */
3129 rtx shift = operands[6];
3130 rtx i2p27 = operands[7];
3131 rtx i43 = operands[8];
3132 rtx scratch0 = operands[9];
3133 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3134 rtx scratch1 = operands[10];
3135 rtx scratch1_si = gen_lowpart (SImode, scratch1);
3136 rtx scratch2 = operands[11];
3137 rtx scratch3 = operands[12];
3138 rtx scratch4 = operands[13];
3139 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
3140 rtx scratch5 = operands[14];
3141 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
3142 rtx scratch6 = operands[15];
3144 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
3145 scratch0, scratch1));
3146 /* inv0 == scratch4 */
3147 if (! TARGET_DIVIDE_INV20U)
3149 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
3151 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
3155 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
3156 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
3158 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
3159 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
3160 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
3161 /* inv1 == scratch4 */
3163 if (TARGET_DIVIDE_INV_MINLAT)
3165 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
3166 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
3167 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
3168 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
3169 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
3170 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
3171 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
3172 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
3173 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
3174 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
3175 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
3179 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
3180 /* Use separate scratch regs for nsb and sign to allow scheduling. */
3181 emit_insn (gen_nsbdi (scratch6,
3182 simplify_gen_subreg (DImode, dividend, SImode, 0)));
3183 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
3184 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
3185 emit_insn (gen_divsi_inv20 (scratch2,
3186 norm32, scratch4, dividend,
3187 scratch6, scratch3, i43,
3188 /* scratch0 may be shared with i2p27. */
3189 scratch0, scratch1, scratch5,
3190 label, label, i2p27));
3192 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
3193 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
3197 (define_insn "divsi_inv20"
3198 [(set (match_operand:DI 0 "register_operand" "=&r")
3199 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
3200 (match_operand:SI 2 "register_operand" "r")
3201 (match_operand:SI 3 "register_operand" "r")
3202 (match_operand:DI 4 "register_operand" "r")
3203 (match_operand:DI 5 "register_operand" "r")
3204 (match_operand:DI 6 "register_operand" "r")
3205 (match_operand:DI 12 "register_operand" "r")
3206 (match_operand 10 "target_operand" "b")
3207 (match_operand 11 "immediate_operand" "i")]
3209 (clobber (match_operand:DI 7 "register_operand" "=&r"))
3210 (clobber (match_operand:DI 8 "register_operand" "=&r"))
3211 (clobber (match_operand:SI 9 "register_operand" "=r"))]
3213 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3215 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
3216 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
3217 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
3218 %10 label (tr), %11 label (imm)
3220 muls.l inv1, norm32, scratch0 // s2.60
3221 muls.l inv1, dividend, result // s32.30
3222 xor i2p27, result_sign, round_scratch
3223 bge/u dividend_nsb, i43, tr.. (label)
3224 shari scratch0, 16, scratch0 // s-16.44
3225 muls.l sratch0_si, inv1, scratch0 // s-16.74
3226 sub result, round_scratch, result
3227 shari dividend, 14, scratch1 // s19.-14
3228 shari scratch0, 30, scratch0 // s-16.44
3229 muls.l scratch0, scratch1, round_scratch // s15.30
3231 sub result, round_scratch, result */
3233 const bool likely = TARGET_DIVIDE_INV20L;
3236 "muls.l %2, %3, %0" "\n"
3237 " xor %12, %5, %7" "\n"
3238 " bge/l %4, %6, %10" "\n"
3239 " muls.l %2, %1, %8" "\n"
3240 " shari %8, 16, %8" "\n"
3241 " muls.l %8, %2, %8" "\n"
3242 " shari %3, 14, %9" "\n"
3243 " shari %8, 30, %8" "\n"
3244 " muls.l %8, %9, %8" "\n"
3245 " sub %0, %8, %0" "\n"
3246 "%11: add %0, %7, %0";
3249 "muls.l %2, %1, %8" "\n"
3250 " muls.l %2, %3, %0" "\n"
3251 " xor %12, %5, %7" "\n"
3252 " bge/u %4, %6, %10" "\n"
3253 " shari %8, 16, %8" "\n"
3254 " muls.l %8, %2, %8" "\n"
3255 " sub %0, %7, %0" "\n"
3256 " shari %3, 14, %9" "\n"
3257 " shari %8, 30, %8" "\n"
3258 " muls.l %8, %9, %7" "\n"
3259 "%11: sub %0, %7, %0";
3262 (define_insn_and_split "divsi_inv_fp"
3263 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3264 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3265 (match_operand:SI 2 "register_operand" "rf")))
3266 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3267 (clobber (match_operand:SI 4 "register_operand" "=r"))
3268 (clobber (match_operand:SI 5 "register_operand" "=r"))
3269 (clobber (match_operand:DF 6 "register_operand" "=r"))
3270 (clobber (match_operand:DF 7 "register_operand" "=r"))
3271 (clobber (match_operand:DF 8 "register_operand" "=r"))]
3272 "TARGET_SHMEDIA_FPU"
3274 "&& (reload_in_progress || reload_completed)"
3275 [(set (match_dup 0) (match_dup 3))]
3277 [(set_attr "highpart" "must_split")])
3279 ;; If a matching group of divide-by-inverse instructions is in the same
3280 ;; basic block after gcse & loop optimizations, we want to transform them
3281 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3282 (define_insn_and_split "*divsi_inv_fp_combine"
3283 [(set (match_operand:SI 0 "register_operand" "=f")
3284 (div:SI (match_operand:SI 1 "register_operand" "f")
3285 (match_operand:SI 2 "register_operand" "f")))
3286 (use (unspec:SI [(match_dup 1)
3287 (match_operand:SI 3 "" "")
3288 (unspec:SI [(match_operand:SI 4 "" "")
3290 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3291 (match_operand:DI 6 "" "")
3293 (const_int 0)] UNSPEC_DIV_INV_M3))
3294 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3295 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3296 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3297 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3298 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3299 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3302 [(set (match_dup 9) (float:DF (match_dup 1)))
3303 (set (match_dup 10) (float:DF (match_dup 2)))
3304 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3306 (fix:SI (match_dup 11)))
3307 (set (match_dup 0) (match_dup 8))]
3309 if (! fp_arith_reg_operand (operands[1], SImode))
3311 emit_move_insn (operands[7], operands[1]);
3312 operands[1] = operands[7];
3314 if (! fp_arith_reg_operand (operands[2], SImode))
3316 emit_move_insn (operands[8], operands[2]);
3317 operands[2] = operands[8];
3320 [(set_attr "highpart" "must_split")])
3322 ;; -------------------------------------------------------------------------
3323 ;; Multiplication instructions
3324 ;; -------------------------------------------------------------------------
3326 (define_insn "umulhisi3_i"
3327 [(set (reg:SI MACL_REG)
3328 (mult:SI (zero_extend:SI
3329 (match_operand:HI 0 "arith_reg_operand" "r"))
3331 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3334 [(set_attr "type" "smpy")])
3336 (define_insn "mulhisi3_i"
3337 [(set (reg:SI MACL_REG)
3338 (mult:SI (sign_extend:SI
3339 (match_operand:HI 0 "arith_reg_operand" "r"))
3341 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3344 [(set_attr "type" "smpy")])
3346 (define_expand "mulhisi3"
3347 [(set (reg:SI MACL_REG)
3348 (mult:SI (sign_extend:SI
3349 (match_operand:HI 1 "arith_reg_operand" ""))
3351 (match_operand:HI 2 "arith_reg_operand" ""))))
3352 (set (match_operand:SI 0 "arith_reg_operand" "")
3359 macl = gen_rtx_REG (SImode, MACL_REG);
3361 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3362 insn = get_insns ();
3364 /* expand_binop can't find a suitable code in umul_widen_optab to
3365 make a REG_EQUAL note from, so make one here.
3366 See also smulsi3_highpart.
3367 ??? Alternatively, we could put this at the calling site of expand_binop,
3368 i.e. expand_expr. */
3369 /* Use emit_libcall_block for loop invariant code motion and to make
3370 a REG_EQUAL note. */
3371 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3376 (define_expand "umulhisi3"
3377 [(set (reg:SI MACL_REG)
3378 (mult:SI (zero_extend:SI
3379 (match_operand:HI 1 "arith_reg_operand" ""))
3381 (match_operand:HI 2 "arith_reg_operand" ""))))
3382 (set (match_operand:SI 0 "arith_reg_operand" "")
3389 macl = gen_rtx_REG (SImode, MACL_REG);
3391 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3392 insn = get_insns ();
3394 /* expand_binop can't find a suitable code in umul_widen_optab to
3395 make a REG_EQUAL note from, so make one here.
3396 See also smulsi3_highpart.
3397 ??? Alternatively, we could put this at the calling site of expand_binop,
3398 i.e. expand_expr. */
3399 /* Use emit_libcall_block for loop invariant code motion and to make
3400 a REG_EQUAL note. */
3401 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3406 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3407 ;; a call to a routine which clobbers known registers.
3409 [(set (match_operand:SI 1 "register_operand" "=z")
3410 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3411 (clobber (reg:SI MACL_REG))
3412 (clobber (reg:SI T_REG))
3413 (clobber (reg:SI PR_REG))
3414 (clobber (reg:SI R3_REG))
3415 (clobber (reg:SI R2_REG))
3416 (clobber (reg:SI R1_REG))
3417 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3420 [(set_attr "type" "sfunc")
3421 (set_attr "needs_delay_slot" "yes")])
3423 (define_expand "mulsi3_call"
3424 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3425 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3426 (parallel[(set (match_operand:SI 0 "register_operand" "")
3427 (mult:SI (reg:SI R4_REG)
3429 (clobber (reg:SI MACL_REG))
3430 (clobber (reg:SI T_REG))
3431 (clobber (reg:SI PR_REG))
3432 (clobber (reg:SI R3_REG))
3433 (clobber (reg:SI R2_REG))
3434 (clobber (reg:SI R1_REG))
3435 (use (match_operand:SI 3 "register_operand" ""))])]
3439 (define_insn "mul_r"
3440 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3441 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3442 (match_operand:SI 2 "arith_reg_operand" "z")))]
3445 [(set_attr "type" "dmpy")])
3447 (define_insn "mul_l"
3448 [(set (reg:SI MACL_REG)
3449 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3450 (match_operand:SI 1 "arith_reg_operand" "r")))]
3453 [(set_attr "type" "dmpy")])
3455 (define_expand "mulsi3"
3456 [(set (reg:SI MACL_REG)
3457 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
3458 (match_operand:SI 2 "arith_reg_operand" "")))
3459 (set (match_operand:SI 0 "arith_reg_operand" "")
3465 /* The address must be set outside the libcall,
3466 since it goes into a pseudo. */
3467 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3468 rtx addr = force_reg (SImode, sym);
3469 rtx insns = gen_mulsi3_call (operands[0], operands[1],
3475 rtx macl = gen_rtx_REG (SImode, MACL_REG);
3477 emit_insn (gen_mul_l (operands[1], operands[2]));
3478 /* consec_sets_giv can only recognize the first insn that sets a
3479 giv as the giv insn. So we must tag this also with a REG_EQUAL
3481 emit_insn (gen_movsi_i ((operands[0]), macl));
3486 (define_insn "mulsidi3_i"
3487 [(set (reg:SI MACH_REG)
3491 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3492 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3494 (set (reg:SI MACL_REG)
3495 (mult:SI (match_dup 0)
3499 [(set_attr "type" "dmpy")])
3501 (define_expand "mulsidi3"
3502 [(set (match_operand:DI 0 "arith_reg_dest" "")
3503 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3504 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3505 "TARGET_SH2 || TARGET_SHMEDIA"
3509 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3514 (define_insn "mulsidi3_media"
3515 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3516 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3517 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3520 [(set_attr "type" "dmpy_media")
3521 (set_attr "highpart" "ignore")])
3523 (define_insn_and_split "mulsidi3_compact"
3524 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3526 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3527 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3528 (clobber (reg:SI MACH_REG))
3529 (clobber (reg:SI MACL_REG))]
3535 rtx low_dst = gen_lowpart (SImode, operands[0]);
3536 rtx high_dst = gen_highpart (SImode, operands[0]);
3538 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3540 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3541 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3542 /* We need something to tag the possible REG_EQUAL notes on to. */
3543 emit_move_insn (operands[0], operands[0]);
3547 (define_insn "umulsidi3_i"
3548 [(set (reg:SI MACH_REG)
3552 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3553 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3555 (set (reg:SI MACL_REG)
3556 (mult:SI (match_dup 0)
3560 [(set_attr "type" "dmpy")])
3562 (define_expand "umulsidi3"
3563 [(set (match_operand:DI 0 "arith_reg_dest" "")
3564 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3565 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3566 "TARGET_SH2 || TARGET_SHMEDIA"
3570 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3575 (define_insn "umulsidi3_media"
3576 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3577 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3578 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3581 [(set_attr "type" "dmpy_media")
3582 (set_attr "highpart" "ignore")])
3584 (define_insn_and_split "umulsidi3_compact"
3585 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3587 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3588 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3589 (clobber (reg:SI MACH_REG))
3590 (clobber (reg:SI MACL_REG))]
3596 rtx low_dst = gen_lowpart (SImode, operands[0]);
3597 rtx high_dst = gen_highpart (SImode, operands[0]);
3599 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3601 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3602 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3603 /* We need something to tag the possible REG_EQUAL notes on to. */
3604 emit_move_insn (operands[0], operands[0]);
3608 (define_insn "smulsi3_highpart_i"
3609 [(set (reg:SI MACH_REG)
3613 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3614 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3616 (clobber (reg:SI MACL_REG))]
3619 [(set_attr "type" "dmpy")])
3621 (define_expand "smulsi3_highpart"
3623 [(set (reg:SI MACH_REG)
3627 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3628 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3630 (clobber (reg:SI MACL_REG))])
3631 (set (match_operand:SI 0 "arith_reg_operand" "")
3638 mach = gen_rtx_REG (SImode, MACH_REG);
3640 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3641 insn = get_insns ();
3643 /* expand_binop can't find a suitable code in mul_highpart_optab to
3644 make a REG_EQUAL note from, so make one here.
3645 See also {,u}mulhisi.
3646 ??? Alternatively, we could put this at the calling site of expand_binop,
3647 i.e. expand_mult_highpart. */
3648 /* Use emit_libcall_block for loop invariant code motion and to make
3649 a REG_EQUAL note. */
3650 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3655 (define_insn "umulsi3_highpart_i"
3656 [(set (reg:SI MACH_REG)
3660 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3661 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3663 (clobber (reg:SI MACL_REG))]
3666 [(set_attr "type" "dmpy")])
3668 (define_expand "umulsi3_highpart"
3670 [(set (reg:SI MACH_REG)
3674 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3675 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3677 (clobber (reg:SI MACL_REG))])
3678 (set (match_operand:SI 0 "arith_reg_operand" "")
3685 mach = gen_rtx_REG (SImode, MACH_REG);
3687 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3688 insn = get_insns ();
3690 /* Use emit_libcall_block for loop invariant code motion and to make
3691 a REG_EQUAL note. */
3692 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3697 (define_insn_and_split "muldi3"
3698 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3699 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3700 (match_operand:DI 2 "arith_reg_operand" "r")))
3701 (clobber (match_scratch:DI 3 "=&r"))
3702 (clobber (match_scratch:DI 4 "=r"))]
3708 rtx op3_v2si, op2_v2si;
3710 op3_v2si = operands[3];
3711 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3713 op3_v2si = XEXP (op3_v2si, 0);
3714 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3716 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3717 op2_v2si = operands[2];
3718 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3720 op2_v2si = XEXP (op2_v2si, 0);
3721 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3723 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3724 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3725 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3726 emit_insn (gen_umulsidi3_media (operands[4],
3727 sh_gen_truncate (SImode, operands[1], 0),
3728 sh_gen_truncate (SImode, operands[2], 0)));
3729 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3730 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3731 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3732 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3736 ;; -------------------------------------------------------------------------
3737 ;; Logical operations
3738 ;; -------------------------------------------------------------------------
3740 (define_expand "andsi3"
3741 [(set (match_operand:SI 0 "arith_reg_operand" "")
3742 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3743 (match_operand:SI 2 "logical_and_operand" "")))]
3746 /* If it is possible to turn the and insn into a zero extension
3747 already, redundant zero extensions will be folded, which results
3749 Ideally the splitter of *andsi_compact would be enough, if redundant
3750 zero extensions were detected after the combine pass, which does not
3751 happen at the moment. */
3754 if (satisfies_constraint_Jmb (operands[2]))
3756 emit_insn (gen_zero_extendqisi2 (operands[0],
3757 gen_lowpart (QImode, operands[1])));
3760 else if (satisfies_constraint_Jmw (operands[2]))
3762 emit_insn (gen_zero_extendhisi2 (operands[0],
3763 gen_lowpart (HImode, operands[1])));
3769 (define_insn_and_split "*andsi_compact"
3770 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3771 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3772 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3780 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3782 if (satisfies_constraint_Jmb (operands[2]))
3783 operands[1] = gen_lowpart (QImode, operands[1]);
3784 else if (satisfies_constraint_Jmw (operands[2]))
3785 operands[1] = gen_lowpart (HImode, operands[1]);
3789 [(set_attr "type" "arith")])
3791 (define_insn "*andsi3_media"
3792 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3793 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3794 (match_operand:SI 2 "logical_operand" "r,I10")))]
3799 [(set_attr "type" "arith_media")])
3801 (define_insn "*andsi3_bclr"
3802 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3803 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3804 (match_operand:SI 2 "const_int_operand" "Psz")))]
3805 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3807 [(set_attr "type" "arith")])
3809 (define_insn_and_split "anddi3"
3810 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3811 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3812 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3819 && ! logical_operand (operands[2], DImode)"
3822 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3823 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3825 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3828 [(set_attr "type" "arith_media")])
3830 (define_insn "andcsi3"
3831 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3832 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3833 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3836 [(set_attr "type" "arith_media")])
3838 (define_insn "andcdi3"
3839 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3840 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3841 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3844 [(set_attr "type" "arith_media")])
3846 (define_expand "iorsi3"
3847 [(set (match_operand:SI 0 "arith_reg_operand" "")
3848 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3849 (match_operand:SI 2 "logical_operand" "")))]
3853 (define_insn "*iorsi3_compact"
3854 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3855 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3856 (match_operand:SI 2 "logical_operand" "r,K08")))]
3858 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3860 [(set_attr "type" "arith")])
3862 (define_insn "*iorsi3_media"
3863 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3864 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3865 (match_operand:SI 2 "logical_operand" "r,I10")))]
3870 [(set_attr "type" "arith_media")])
3872 (define_insn "*iorsi3_bset"
3873 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3874 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3875 (match_operand:SI 2 "const_int_operand" "Pso")))]
3876 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3878 [(set_attr "type" "arith")])
3880 (define_insn "iordi3"
3881 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3882 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3883 (match_operand:DI 2 "logical_operand" "r,I10")))]
3888 [(set_attr "type" "arith_media")])
3890 (define_insn_and_split "*logical_sidi3"
3891 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3892 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3893 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3894 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3897 "&& reload_completed"
3898 [(set (match_dup 0) (match_dup 3))]
3901 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3902 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3903 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3906 (define_insn_and_split "*logical_sidisi3"
3907 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3908 (truncate:SI (sign_extend:DI
3909 (match_operator:SI 3 "logical_operator"
3910 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3911 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3915 [(set (match_dup 0) (match_dup 3))])
3917 (define_insn_and_split "*logical_sidi3_2"
3918 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3919 (sign_extend:DI (truncate:SI (sign_extend:DI
3920 (match_operator:SI 3 "logical_operator"
3921 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3922 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3926 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3928 (define_expand "xorsi3"
3929 [(set (match_operand:SI 0 "arith_reg_operand" "")
3930 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3931 (match_operand:SI 2 "xor_operand" "")))]
3935 (define_insn "*xorsi3_compact"
3936 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3937 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3938 (match_operand:SI 2 "logical_operand" "K08,r")))]
3941 [(set_attr "type" "arith")])
3943 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
3944 ;; of results where one of the inputs is a T bit store. Notice that this
3945 ;; pattern must not match during reload. If reload picks this pattern it
3946 ;; will be impossible to split it afterwards.
3947 (define_insn_and_split "*logical_op_t"
3948 [(set (match_operand:SI 0 "arith_reg_dest")
3949 (match_operator:SI 3 "logical_operator"
3950 [(match_operand:SI 1 "arith_reg_operand")
3951 (match_operand:SI 2 "t_reg_operand")]))]
3952 "TARGET_SH1 && can_create_pseudo_p ()"
3955 [(set (match_dup 4) (reg:SI T_REG))
3956 (set (match_dup 0) (match_dup 3))]
3958 operands[4] = gen_reg_rtx (SImode);
3959 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3960 operands[1], operands[4]);
3963 (define_insn "*xorsi3_media"
3964 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3965 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3966 (match_operand:SI 2 "xor_operand" "r,I06")))]
3971 [(set_attr "type" "arith_media")])
3973 (define_insn "xordi3"
3974 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3975 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3976 (match_operand:DI 2 "xor_operand" "r,I06")))]
3981 [(set_attr "type" "arith_media")])
3983 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3984 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3986 [(set (match_operand:DI 0 "arith_reg_dest" "")
3987 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3988 [(match_operand 1 "any_register_operand" "")
3989 (match_operand 2 "any_register_operand" "")])))]
3991 [(set (match_dup 5) (match_dup 4))
3992 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3994 machine_mode inmode = GET_MODE (operands[1]);
3997 if (GET_CODE (operands[0]) == SUBREG)
3999 offset = SUBREG_BYTE (operands[0]);
4000 operands[0] = SUBREG_REG (operands[0]);
4002 gcc_assert (REG_P (operands[0]));
4003 if (TARGET_BIG_ENDIAN)
4004 offset += 8 - GET_MODE_SIZE (inmode);
4005 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
4008 ;; -------------------------------------------------------------------------
4009 ;; Shifts and rotates
4010 ;; -------------------------------------------------------------------------
4012 (define_expand "rotldi3"
4013 [(set (match_operand:DI 0 "arith_reg_dest" "")
4014 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
4015 (match_operand:HI 2 "mextr_bit_offset" "")))]
4018 if (! mextr_bit_offset (operands[2], HImode))
4022 (define_insn "rotldi3_mextr"
4023 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4024 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
4025 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4028 static char templ[16];
4029 sprintf (templ, "mextr%d %%1,%%1,%%0",
4030 8 - (int) (INTVAL (operands[2]) >> 3));
4033 [(set_attr "type" "arith_media")])
4035 (define_expand "rotrdi3"
4036 [(set (match_operand:DI 0 "arith_reg_dest" "")
4037 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
4038 (match_operand:HI 2 "mextr_bit_offset" "")))]
4041 if (! mextr_bit_offset (operands[2], HImode))
4045 (define_insn "rotrdi3_mextr"
4046 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4047 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
4048 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4051 static char templ[16];
4052 sprintf (templ, "mextr%d %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
4055 [(set_attr "type" "arith_media")])
4058 [(set (match_operand:DI 0 "arith_reg_dest" "")
4059 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
4060 "ua_address_operand" "")))
4061 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
4063 (clobber (match_operand:DI 3 "register_operand" ""))]
4065 [(match_dup 4) (match_dup 5)]
4067 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
4068 (operands[3], operands[1]));
4069 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
4070 GEN_INT (56), GEN_INT (8));
4073 (define_expand "rotrsi3"
4074 [(set (match_operand:SI 0 "arith_reg_dest")
4075 (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
4076 (match_operand:SI 2 "const_int_operand")))]
4079 HOST_WIDE_INT ival = INTVAL (operands[2]);
4082 emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
4089 (define_insn "rotrsi3_1"
4090 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4091 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4094 (and:SI (match_dup 1) (const_int 1)))]
4097 [(set_attr "type" "arith")])
4099 ;; A slimplified version of rotr for combine.
4100 (define_insn "*rotrsi3_1"
4101 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4102 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4104 (clobber (reg:SI T_REG))]
4107 [(set_attr "type" "arith")])
4109 (define_insn "rotlsi3_1"
4110 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4111 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4114 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4117 [(set_attr "type" "arith")])
4119 ;; A simplified version of rotl for combine.
4120 (define_insn "*rotlsi3_1"
4121 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4122 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4124 (clobber (reg:SI T_REG))]
4127 [(set_attr "type" "arith")])
4129 (define_insn "rotlsi3_31"
4130 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4131 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4133 (clobber (reg:SI T_REG))]
4136 [(set_attr "type" "arith")])
4138 (define_insn "rotlsi3_16"
4139 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4140 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
4144 [(set_attr "type" "arith")])
4146 (define_expand "rotlsi3"
4147 [(set (match_operand:SI 0 "arith_reg_dest")
4148 (rotate:SI (match_operand:SI 1 "arith_reg_operand")
4149 (match_operand:SI 2 "const_int_operand")))]
4152 static const char rot_tab[] = {
4153 000, 000, 000, 000, 000, 000, 010, 001,
4154 001, 001, 011, 013, 003, 003, 003, 003,
4155 003, 003, 003, 003, 003, 013, 012, 002,
4156 002, 002, 010, 000, 000, 000, 000, 000,
4159 int count = INTVAL (operands[2]);
4160 int choice = rot_tab[count];
4161 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
4167 emit_move_insn (operands[0], operands[1]);
4168 count -= (count & 16) * 2;
4171 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
4178 parts[0] = gen_reg_rtx (SImode);
4179 parts[1] = gen_reg_rtx (SImode);
4180 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
4181 emit_move_insn (parts[choice-1], operands[1]);
4182 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
4183 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
4184 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
4185 count = (count & ~16) - 8;
4189 for (; count > 0; count--)
4190 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
4191 for (; count < 0; count++)
4192 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4197 (define_insn "rotlhi3_8"
4198 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4199 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
4203 [(set_attr "type" "arith")])
4205 (define_expand "rotlhi3"
4206 [(set (match_operand:HI 0 "arith_reg_operand")
4207 (rotate:HI (match_operand:HI 1 "arith_reg_operand")
4208 (match_operand:HI 2 "const_int_operand")))]
4211 if (INTVAL (operands[2]) != 8)
4215 ;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
4216 ;; They can also be used to implement things like
4218 ;; int x0 = (y >> 1) | (t << 31); // rotcr
4219 ;; int x1 = (y << 1) | t; // rotcl
4220 (define_insn "rotcr"
4221 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4222 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4224 (ashift:SI (match_operand:SI 2 "t_reg_operand")
4227 (and:SI (match_dup 1) (const_int 1)))]
4230 [(set_attr "type" "arith")])
4232 (define_insn "rotcl"
4233 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4234 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4236 (match_operand:SI 2 "t_reg_operand")))
4238 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4241 [(set_attr "type" "arith")])
4243 ;; Simplified rotcr version for combine, which allows arbitrary shift
4244 ;; amounts for the reg. If the shift amount is '1' rotcr can be used
4245 ;; directly. Otherwise we have to insert a shift in between.
4246 (define_insn_and_split "*rotcr"
4247 [(set (match_operand:SI 0 "arith_reg_dest")
4248 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4249 (match_operand:SI 2 "const_int_operand"))
4250 (ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4252 (clobber (reg:SI T_REG))]
4255 "&& can_create_pseudo_p ()"
4258 if (INTVAL (operands[2]) > 1)
4260 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4261 rtx prev_set_t_insn = NULL_RTX;
4262 rtx tmp_t_reg = NULL_RTX;
4264 /* If we're going to emit a shift sequence that clobbers the T_REG,
4265 try to find the previous insn that sets the T_REG and emit the
4266 shift insn before that insn, to remove the T_REG dependency.
4267 If the insn that sets the T_REG cannot be found, store the T_REG
4268 in a temporary reg and restore it after the shift. */
4269 if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4270 && ! sh_dynamicalize_shift_p (shift_count))
4272 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4274 /* Skip the nott insn, which was probably inserted by the splitter
4275 of *rotcr_neg_t. Don't use one of the recog functions
4276 here during insn splitting, since that causes problems in later
4278 if (prev_set_t_insn != NULL_RTX)
4280 rtx pat = PATTERN (prev_set_t_insn);
4281 if (GET_CODE (pat) == SET
4282 && t_reg_operand (XEXP (pat, 0), SImode)
4283 && negt_reg_operand (XEXP (pat, 1), SImode))
4284 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4287 if (! (prev_set_t_insn != NULL_RTX
4288 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4289 && ! reg_referenced_p (get_t_reg_rtx (),
4290 PATTERN (prev_set_t_insn))))
4292 prev_set_t_insn = NULL_RTX;
4293 tmp_t_reg = gen_reg_rtx (SImode);
4294 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4298 rtx shift_result = gen_reg_rtx (SImode);
4299 rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4300 operands[1] = shift_result;
4302 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4303 if (prev_set_t_insn != NULL_RTX)
4304 emit_insn_before (shift_insn, prev_set_t_insn);
4306 emit_insn (shift_insn);
4308 /* Restore T_REG if it has been saved before. */
4309 if (tmp_t_reg != NULL_RTX)
4310 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4313 /* For the rotcr insn to work, operands[3] must be in T_REG.
4314 If it is not we can get it there by shifting it right one bit.
4315 In this case T_REG is not an input for this insn, thus we don't have to
4316 pay attention as of where to insert the shlr insn. */
4317 if (! t_reg_operand (operands[3], SImode))
4319 /* We don't care about the shifted result here, only the T_REG. */
4320 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4321 operands[3] = get_t_reg_rtx ();
4324 emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4328 ;; If combine tries the same as above but with swapped operands, split
4329 ;; it so that it will try the pattern above.
4331 [(set (match_operand:SI 0 "arith_reg_dest")
4332 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4334 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4335 (match_operand:SI 3 "const_int_operand"))))]
4336 "TARGET_SH1 && can_create_pseudo_p ()"
4337 [(parallel [(set (match_dup 0)
4338 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4339 (ashift:SI (match_dup 1) (const_int 31))))
4340 (clobber (reg:SI T_REG))])])
4342 ;; Basically the same as the rotcr pattern above, but for rotcl.
4343 ;; FIXME: Fold copy pasted split code for rotcr and rotcl.
4344 (define_insn_and_split "*rotcl"
4345 [(set (match_operand:SI 0 "arith_reg_dest")
4346 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4347 (match_operand:SI 2 "const_int_operand"))
4348 (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4350 (clobber (reg:SI T_REG))]
4353 "&& can_create_pseudo_p ()"
4356 gcc_assert (INTVAL (operands[2]) > 0);
4358 if (INTVAL (operands[2]) > 1)
4360 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4361 rtx prev_set_t_insn = NULL_RTX;
4362 rtx tmp_t_reg = NULL_RTX;
4364 /* If we're going to emit a shift sequence that clobbers the T_REG,
4365 try to find the previous insn that sets the T_REG and emit the
4366 shift insn before that insn, to remove the T_REG dependency.
4367 If the insn that sets the T_REG cannot be found, store the T_REG
4368 in a temporary reg and restore it after the shift. */
4369 if (sh_ashlsi_clobbers_t_reg_p (shift_count)
4370 && ! sh_dynamicalize_shift_p (shift_count))
4372 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4374 /* Skip the nott insn, which was probably inserted by the splitter
4375 of *rotcl_neg_t. Don't use one of the recog functions
4376 here during insn splitting, since that causes problems in later
4378 if (prev_set_t_insn != NULL_RTX)
4380 rtx pat = PATTERN (prev_set_t_insn);
4381 if (GET_CODE (pat) == SET
4382 && t_reg_operand (XEXP (pat, 0), SImode)
4383 && negt_reg_operand (XEXP (pat, 1), SImode))
4384 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4387 if (! (prev_set_t_insn != NULL_RTX
4388 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4389 && ! reg_referenced_p (get_t_reg_rtx (),
4390 PATTERN (prev_set_t_insn))))
4392 prev_set_t_insn = NULL_RTX;
4393 tmp_t_reg = gen_reg_rtx (SImode);
4394 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4398 rtx shift_result = gen_reg_rtx (SImode);
4399 rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
4400 operands[1] = shift_result;
4402 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4403 if (prev_set_t_insn != NULL_RTX)
4404 emit_insn_before (shift_insn, prev_set_t_insn);
4406 emit_insn (shift_insn);
4408 /* Restore T_REG if it has been saved before. */
4409 if (tmp_t_reg != NULL_RTX)
4410 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4413 /* For the rotcl insn to work, operands[3] must be in T_REG.
4414 If it is not we can get it there by shifting it right one bit.
4415 In this case T_REG is not an input for this insn, thus we don't have to
4416 pay attention as of where to insert the shlr insn. */
4417 if (! t_reg_operand (operands[3], SImode))
4419 /* We don't care about the shifted result here, only the T_REG. */
4420 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4421 operands[3] = get_t_reg_rtx ();
4424 emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
4428 ;; rotcl combine pattern variations
4429 (define_insn_and_split "*rotcl"
4430 [(set (match_operand:SI 0 "arith_reg_dest")
4431 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4432 (match_operand:SI 2 "const_int_operand"))
4433 (match_operand:SI 3 "t_reg_operand")))
4434 (clobber (reg:SI T_REG))]
4437 "&& can_create_pseudo_p ()"
4438 [(parallel [(set (match_dup 0)
4439 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4440 (and:SI (match_dup 3) (const_int 1))))
4441 (clobber (reg:SI T_REG))])])
4443 (define_insn_and_split "*rotcl"
4444 [(set (match_operand:SI 0 "arith_reg_dest")
4445 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4447 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4448 (match_operand:SI 3 "const_int_operand"))))
4449 (clobber (reg:SI T_REG))]
4452 "&& can_create_pseudo_p ()"
4453 [(parallel [(set (match_dup 0)
4454 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4455 (and:SI (match_dup 1) (const_int 1))))
4456 (clobber (reg:SI T_REG))])])
4458 (define_insn_and_split "*rotcl"
4459 [(set (match_operand:SI 0 "arith_reg_dest")
4460 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4461 (match_operand:SI 2 "const_int_operand"))
4462 (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4464 (clobber (reg:SI T_REG))]
4467 "&& can_create_pseudo_p ()"
4468 [(parallel [(set (match_dup 0)
4469 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4470 (and:SI (reg:SI T_REG) (const_int 1))))
4471 (clobber (reg:SI T_REG))])]
4473 /* We don't care about the result of the left shift, only the T_REG. */
4474 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4477 (define_insn_and_split "*rotcl"
4478 [(set (match_operand:SI 0 "arith_reg_dest")
4479 (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4481 (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4482 (match_operand:SI 2 "const_int_operand"))))
4483 (clobber (reg:SI T_REG))]
4486 "&& can_create_pseudo_p ()"
4487 [(parallel [(set (match_dup 0)
4488 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4489 (and:SI (reg:SI T_REG) (const_int 1))))
4490 (clobber (reg:SI T_REG))])]
4492 /* We don't care about the result of the left shift, only the T_REG. */
4493 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4496 ;; rotcr combine bridge pattern which will make combine try out more
4497 ;; complex patterns.
4498 (define_insn_and_split "*rotcr"
4499 [(set (match_operand:SI 0 "arith_reg_dest")
4500 (ashift:SI (match_operand:SI 1 "t_reg_operand") (const_int 31)))]
4504 [(set (match_dup 0) (match_dup 1))
4505 (parallel [(set (match_dup 0)
4506 (ior:SI (lshiftrt:SI (match_dup 0) (const_int 1))
4507 (ashift:SI (match_dup 1) (const_int 31))))
4509 (and:SI (match_dup 0) (const_int 1)))])])
4511 (define_insn_and_split "*rotcr"
4512 [(set (match_operand:SI 0 "arith_reg_dest")
4513 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4514 (const_int -2147483648)) ;; 0xffffffff80000000
4515 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4517 (clobber (reg:SI T_REG))]
4520 "&& can_create_pseudo_p ()"
4523 rtx tmp = gen_reg_rtx (SImode);
4524 emit_insn (gen_shll (tmp, operands[1]));
4525 emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4529 ;; rotcr combine patterns for rotating in the negated T_REG value.
4530 (define_insn_and_split "*rotcr_neg_t"
4531 [(set (match_operand:SI 0 "arith_reg_dest")
4532 (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4533 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4534 (match_operand:SI 3 "const_int_operand"))))
4535 (clobber (reg:SI T_REG))]
4538 "&& can_create_pseudo_p ()"
4539 [(parallel [(set (match_dup 0)
4540 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4541 (ashift:SI (reg:SI T_REG) (const_int 31))))
4542 (clobber (reg:SI T_REG))])]
4544 emit_insn (gen_nott (get_t_reg_rtx ()));
4547 (define_insn_and_split "*rotcr_neg_t"
4548 [(set (match_operand:SI 0 "arith_reg_dest")
4549 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4550 (match_operand:SI 2 "const_int_operand"))
4551 (match_operand:SI 3 "negt_reg_shl31_operand")))
4552 (clobber (reg:SI T_REG))]
4555 "&& can_create_pseudo_p ()"
4556 [(parallel [(set (match_dup 0)
4557 (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4558 (ashift:SI (reg:SI T_REG) (const_int 31))))
4559 (clobber (reg:SI T_REG))])]
4561 emit_insn (gen_nott (get_t_reg_rtx ()));
4564 ;; rotcl combine patterns for rotating in the negated T_REG value.
4565 ;; For some strange reason these have to be specified as splits which combine
4566 ;; will pick up. If they are specified as insn_and_split like the
4567 ;; *rotcr_neg_t patterns above, combine would recognize them successfully
4568 ;; but not emit them on non-SH2A targets.
4570 [(set (match_operand:SI 0 "arith_reg_dest")
4571 (ior:SI (match_operand:SI 1 "negt_reg_operand")
4572 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4573 (match_operand:SI 3 "const_int_operand"))))]
4575 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4576 (parallel [(set (match_dup 0)
4577 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4578 (and:SI (reg:SI T_REG) (const_int 1))))
4579 (clobber (reg:SI T_REG))])])
4582 [(set (match_operand:SI 0 "arith_reg_dest")
4583 (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4584 (match_operand:SI 3 "const_int_operand"))
4585 (match_operand:SI 1 "negt_reg_operand")))]
4587 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4588 (parallel [(set (match_dup 0)
4589 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4590 (and:SI (reg:SI T_REG) (const_int 1))))
4591 (clobber (reg:SI T_REG))])])
4593 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4594 ;; SImode shift left
4596 (define_expand "ashlsi3"
4597 [(set (match_operand:SI 0 "arith_reg_operand" "")
4598 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4599 (match_operand:SI 2 "shift_count_operand" "")))]
4604 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4606 operands[2] = GEN_INT (-INTVAL (operands[2]));
4607 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4610 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4614 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4615 operands[2] = force_reg (SImode, operands[2]);
4617 /* If the ashlsi3_* insn is going to clobber the T_REG it must be
4619 if (CONST_INT_P (operands[2])
4620 && sh_ashlsi_clobbers_t_reg_p (operands[2])
4621 && ! sh_dynamicalize_shift_p (operands[2]))
4623 emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4628 /* Expand a library call for the dynamic shift. */
4629 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4631 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4632 rtx funcaddr = gen_reg_rtx (Pmode);
4633 function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4634 emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4640 (define_insn "ashlsi3_k"
4641 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4642 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4643 (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4648 [(set_attr "type" "arith")])
4650 (define_insn_and_split "ashlsi3_d"
4651 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4652 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4653 (match_operand:SI 2 "shift_count_operand" "r")))]
4656 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4657 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4660 if (satisfies_constraint_P27 (operands[2]))
4662 emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
4665 else if (! satisfies_constraint_P27 (operands[2]))
4667 /* This must happen before reload, otherwise the constant will be moved
4668 into a register due to the "r" constraint, after which this split
4669 cannot be done anymore.
4670 Unfortunately the move insn will not always be eliminated.
4671 Also, here we must not create a shift sequence that clobbers the
4673 emit_move_insn (operands[0], operands[1]);
4674 gen_shifty_op (ASHIFT, operands);
4680 [(set_attr "type" "dyn_shift")])
4682 ;; If dynamic shifts are not available use a library function.
4683 ;; By specifying the pattern we reduce the number of call clobbered regs.
4684 ;; In order to make combine understand the truncation of the shift amount
4685 ;; operand we have to allow it to use pseudo regs for the shift operands.
4686 (define_insn "ashlsi3_d_call"
4687 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4688 (ashift:SI (reg:SI R4_REG)
4689 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4691 (use (match_operand:SI 2 "arith_reg_operand" "r"))
4692 (clobber (reg:SI T_REG))
4693 (clobber (reg:SI PR_REG))]
4694 "TARGET_SH1 && !TARGET_DYNSHIFT"
4696 [(set_attr "type" "sfunc")
4697 (set_attr "needs_delay_slot" "yes")])
4699 (define_insn_and_split "ashlsi3_n"
4700 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4701 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4702 (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
4703 "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4705 "&& (reload_completed
4706 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4709 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4711 /* If this pattern was picked and dynamic shifts are supported, switch
4712 to dynamic shift pattern before reload. */
4713 operands[2] = force_reg (SImode, operands[2]);
4714 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4717 gen_shifty_op (ASHIFT, operands);
4722 (define_insn_and_split "ashlsi3_n_clobbers_t"
4723 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4724 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4725 (match_operand:SI 2 "not_p27_shift_count_operand" "")))
4726 (clobber (reg:SI T_REG))]
4727 "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
4729 "&& (reload_completed || INTVAL (operands[2]) == 31
4730 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4733 if (INTVAL (operands[2]) == 31)
4735 /* If the shift amount is 31 we split into a different sequence before
4736 reload so that it gets a chance to allocate R0 for the sequence.
4737 If it fails to do so (due to pressure on R0), it will take one insn
4738 more for the and. */
4739 emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
4740 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4742 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4744 /* If this pattern was picked and dynamic shifts are supported, switch
4745 to dynamic shift pattern before reload. */
4746 operands[2] = force_reg (SImode, operands[2]);
4747 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4750 gen_shifty_op (ASHIFT, operands);
4756 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4757 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4759 (lt:SI (match_dup 1) (const_int 0)))]
4762 [(set_attr "type" "arith")])
4764 (define_insn "*ashlsi_c_void"
4765 [(set (reg:SI T_REG)
4766 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
4767 (clobber (match_scratch:SI 1 "=0"))]
4768 "TARGET_SH1 && cse_not_expected"
4770 [(set_attr "type" "arith")])
4773 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
4775 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
4777 && peep2_reg_dead_p (2, operands[0])
4778 && peep2_reg_dead_p (2, operands[1])"
4781 emit_insn (gen_shll (operands[1], operands[1]));
4785 (define_insn "ashlsi3_media"
4786 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4787 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4788 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4793 [(set_attr "type" "arith_media")
4794 (set_attr "highpart" "ignore")])
4796 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4797 ;; HImode shift left
4799 (define_expand "ashlhi3"
4800 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
4801 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
4802 (match_operand:SI 2 "nonmemory_operand" "")))
4803 (clobber (reg:SI T_REG))])]
4806 if (!CONST_INT_P (operands[2]))
4808 /* It may be possible to call gen_ashlhi3 directly with more generic
4809 operands. Make sure operands[1] is a HImode register here. */
4810 if (!arith_reg_operand (operands[1], HImode))
4811 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4814 (define_insn "ashlhi3_k"
4815 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4816 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
4817 (match_operand:HI 2 "const_int_operand" "M,P27")))]
4818 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
4822 [(set_attr "type" "arith")])
4824 (define_insn_and_split "*ashlhi3_n"
4825 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4826 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
4827 (match_operand:HI 2 "const_int_operand" "n")))
4828 (clobber (reg:SI T_REG))]
4831 "&& reload_completed"
4832 [(use (reg:SI R0_REG))]
4834 gen_shifty_hi_op (ASHIFT, operands);
4838 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4839 ;; DImode shift left
4841 (define_expand "ashldi3"
4842 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4843 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4844 (match_operand:DI 2 "immediate_operand" "")))
4845 (clobber (reg:SI T_REG))])]
4850 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4852 operands[2] = GEN_INT (-INTVAL (operands[2]));
4853 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4856 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4859 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
4861 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4864 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
4866 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4873 ;; Expander for DImode shift left with SImode operations.
4874 (define_expand "ashldi3_std"
4875 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4876 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4877 (match_operand:DI 2 "const_int_operand" "n")))]
4878 "TARGET_SH1 && INTVAL (operands[2]) < 32"
4880 rtx low_src = gen_lowpart (SImode, operands[1]);
4881 rtx high_src = gen_highpart (SImode, operands[1]);
4882 rtx dst = gen_reg_rtx (DImode);
4883 rtx low_dst = gen_lowpart (SImode, dst);
4884 rtx high_dst = gen_highpart (SImode, dst);
4885 rtx tmp0 = gen_reg_rtx (SImode);
4886 rtx tmp1 = gen_reg_rtx (SImode);
4888 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4889 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
4890 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
4891 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4892 emit_move_insn (operands[0], dst);
4896 (define_insn_and_split "ashldi3_k"
4897 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4898 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
4900 (clobber (reg:SI T_REG))]
4903 "&& reload_completed"
4906 rtx high = gen_highpart (SImode, operands[0]);
4907 rtx low = gen_lowpart (SImode, operands[0]);
4908 emit_insn (gen_shll (low, low));
4909 emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
4913 (define_insn "ashldi3_media"
4914 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4915 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4916 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4921 [(set_attr "type" "arith_media")])
4923 (define_insn "*ashldisi3_media"
4924 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4925 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4926 (match_operand:DI 2 "const_int_operand" "n")))]
4927 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4928 "shlli.l %1, %2, %0"
4929 [(set_attr "type" "arith_media")
4930 (set_attr "highpart" "ignore")])
4932 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4933 ;; SImode arithmetic shift right
4935 ;; We can't do HImode right shifts correctly unless we start out with an
4936 ;; explicit zero / sign extension; doing that would result in worse overall
4937 ;; code, so just let the machine independent code widen the mode.
4938 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
4940 (define_expand "ashrsi3"
4941 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4942 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4943 (match_operand:SI 2 "nonmemory_operand" "")))
4944 (clobber (reg:SI T_REG))])]
4949 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4951 operands[2] = GEN_INT (-INTVAL (operands[2]));
4952 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4955 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4958 if (expand_ashiftrt (operands))
4965 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4966 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4969 (and:SI (match_dup 1) (const_int 1)))]
4972 [(set_attr "type" "arith")])
4974 (define_insn "ashrsi3_k"
4975 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4976 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4977 (match_operand:SI 2 "const_int_operand" "M")))
4978 (clobber (reg:SI T_REG))]
4979 "TARGET_SH1 && INTVAL (operands[2]) == 1"
4981 [(set_attr "type" "arith")])
4983 (define_insn_and_split "ashrsi2_16"
4984 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4985 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
4990 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
4991 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
4993 operands[2] = gen_lowpart (HImode, operands[0]);
4996 (define_insn_and_split "ashrsi2_31"
4997 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4998 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5000 (clobber (reg:SI T_REG))]
5006 emit_insn (gen_shll (operands[0], operands[1]));
5007 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
5011 (define_insn "ashrsi3_d"
5012 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5013 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5014 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
5017 [(set_attr "type" "dyn_shift")])
5019 (define_insn "ashrsi3_n"
5020 [(set (reg:SI R4_REG)
5021 (ashiftrt:SI (reg:SI R4_REG)
5022 (match_operand:SI 0 "const_int_operand" "i")))
5023 (clobber (reg:SI T_REG))
5024 (clobber (reg:SI PR_REG))
5025 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
5028 [(set_attr "type" "sfunc")
5029 (set_attr "needs_delay_slot" "yes")])
5031 (define_insn "ashrsi3_media"
5032 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5033 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5034 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5039 [(set_attr "type" "arith_media")
5040 (set_attr "highpart" "ignore")])
5042 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5043 ;; DImode arithmetic shift right
5045 (define_expand "ashrdi3"
5046 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5047 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5048 (match_operand:DI 2 "immediate_operand" "")))
5049 (clobber (reg:SI T_REG))])]
5054 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5056 operands[2] = GEN_INT (-INTVAL (operands[2]));
5057 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5060 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
5063 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5067 (define_insn_and_split "ashrdi3_k"
5068 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5069 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5071 (clobber (reg:SI T_REG))]
5074 "&& reload_completed"
5077 rtx high = gen_highpart (SImode, operands[0]);
5078 rtx low = gen_lowpart (SImode, operands[0]);
5079 emit_insn (gen_shar (high, high));
5080 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5084 (define_insn "ashrdi3_media"
5085 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5086 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5087 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5089 && (arith_reg_dest (operands[0], DImode)
5090 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
5094 [(set_attr "type" "arith_media")])
5096 (define_insn "*ashrdisi3_media"
5097 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5098 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5099 (match_operand:DI 2 "const_int_operand" "n")))]
5100 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5101 "shari.l %1, %2, %0"
5102 [(set_attr "type" "arith_media")
5103 (set_attr "highpart" "ignore")])
5105 (define_insn "ashrdisi3_media_high"
5106 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5108 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5109 (match_operand:DI 2 "const_int_operand" "n"))))]
5110 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
5112 [(set_attr "type" "arith_media")])
5114 (define_insn "ashrdisi3_media_opaque"
5115 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5116 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
5117 (match_operand:DI 2 "const_int_operand" "n")]
5121 [(set_attr "type" "arith_media")])
5123 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5124 ;; SImode logical shift right
5126 (define_expand "lshrsi3"
5127 [(set (match_operand:SI 0 "arith_reg_dest" "")
5128 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
5129 (match_operand:SI 2 "shift_count_operand" "")))]
5134 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5136 operands[2] = GEN_INT (-INTVAL (operands[2]));
5137 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
5140 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
5144 /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
5145 here, otherwise the pattern will never match due to the shift amount reg
5148 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
5150 rtx neg_count = force_reg (SImode,
5151 gen_int_mode (- INTVAL (operands[2]), SImode));
5152 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5156 if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
5158 rtx neg_count = gen_reg_rtx (SImode);
5159 emit_insn (gen_negsi2 (neg_count, operands[2]));
5160 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5164 /* If the lshrsi3_* insn is going to clobber the T_REG it must be
5166 if (CONST_INT_P (operands[2])
5167 && sh_lshrsi_clobbers_t_reg_p (operands[2])
5168 && ! sh_dynamicalize_shift_p (operands[2]))
5170 emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
5175 /* Expand a library call for the dynamic shift. */
5176 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
5178 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
5179 rtx funcaddr = gen_reg_rtx (Pmode);
5180 function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
5181 emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
5186 (define_insn "lshrsi3_k"
5187 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5188 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5189 (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
5192 [(set_attr "type" "arith")])
5194 (define_insn_and_split "lshrsi3_d"
5195 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5196 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5197 (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
5200 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
5201 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5204 if (satisfies_constraint_P27 (operands[2]))
5206 /* This will not be done for a shift amount of 1, because it would
5207 clobber the T_REG. */
5208 emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
5211 else if (! satisfies_constraint_P27 (operands[2]))
5213 /* This must happen before reload, otherwise the constant will be moved
5214 into a register due to the "r" constraint, after which this split
5215 cannot be done anymore.
5216 Unfortunately the move insn will not always be eliminated.
5217 Also, here we must not create a shift sequence that clobbers the
5219 emit_move_insn (operands[0], operands[1]);
5220 gen_shifty_op (LSHIFTRT, operands);
5226 [(set_attr "type" "dyn_shift")])
5228 ;; If dynamic shifts are not available use a library function.
5229 ;; By specifying the pattern we reduce the number of call clobbered regs.
5230 ;; In order to make combine understand the truncation of the shift amount
5231 ;; operand we have to allow it to use pseudo regs for the shift operands.
5232 (define_insn "lshrsi3_d_call"
5233 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
5234 (lshiftrt:SI (reg:SI R4_REG)
5235 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5237 (use (match_operand:SI 2 "arith_reg_operand" "r"))
5238 (clobber (reg:SI T_REG))
5239 (clobber (reg:SI PR_REG))]
5240 "TARGET_SH1 && !TARGET_DYNSHIFT"
5242 [(set_attr "type" "sfunc")
5243 (set_attr "needs_delay_slot" "yes")])
5245 (define_insn_and_split "lshrsi3_n"
5246 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5247 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5248 (match_operand:SI 2 "not_p27_rshift_count_operand")))]
5249 "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5251 "&& (reload_completed
5252 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5255 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5257 /* If this pattern was picked and dynamic shifts are supported, switch
5258 to dynamic shift pattern before reload. */
5259 operands[2] = force_reg (SImode,
5260 gen_int_mode (- INTVAL (operands[2]), SImode));
5261 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5264 gen_shifty_op (LSHIFTRT, operands);
5269 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
5270 ;; the shlr pattern.
5271 (define_insn_and_split "lshrsi3_n_clobbers_t"
5272 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5273 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5274 (match_operand:SI 2 "not_p27_rshift_count_operand")))
5275 (clobber (reg:SI T_REG))]
5276 "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
5278 "&& (reload_completed || INTVAL (operands[2]) == 31
5279 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5282 if (INTVAL (operands[2]) == 31)
5284 emit_insn (gen_shll (operands[0], operands[1]));
5285 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
5287 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5289 /* If this pattern was picked and dynamic shifts are supported, switch
5290 to dynamic shift pattern before reload. */
5291 operands[2] = force_reg (SImode,
5292 gen_int_mode (- INTVAL (operands[2]), SImode));
5293 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5296 gen_shifty_op (LSHIFTRT, operands);
5302 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5303 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5306 (and:SI (match_dup 1) (const_int 1)))]
5309 [(set_attr "type" "arith")])
5311 (define_insn "lshrsi3_media"
5312 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5313 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5314 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5319 [(set_attr "type" "arith_media")
5320 (set_attr "highpart" "ignore")])
5322 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5323 ;; DImode logical shift right
5325 (define_expand "lshrdi3"
5326 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5327 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5328 (match_operand:DI 2 "immediate_operand" "")))
5329 (clobber (reg:SI T_REG))])]
5334 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5336 operands[2] = GEN_INT (-INTVAL (operands[2]));
5337 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5340 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
5343 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5347 (define_insn_and_split "lshrdi3_k"
5348 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5349 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5351 (clobber (reg:SI T_REG))]
5354 "&& reload_completed"
5357 rtx high = gen_highpart (SImode, operands[0]);
5358 rtx low = gen_lowpart (SImode, operands[0]);
5359 emit_insn (gen_shlr (high, high));
5360 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5364 (define_insn "lshrdi3_media"
5365 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5366 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5367 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5369 && (arith_reg_dest (operands[0], DImode)
5370 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
5374 [(set_attr "type" "arith_media")])
5376 (define_insn "*lshrdisi3_media"
5377 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5378 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5379 (match_operand:DI 2 "const_int_operand" "n")))]
5380 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5381 "shlri.l %1, %2, %0"
5382 [(set_attr "type" "arith_media")
5383 (set_attr "highpart" "ignore")])
5385 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5386 ;; Combined left/right shifts
5389 [(set (match_operand:SI 0 "register_operand" "")
5390 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5391 (match_operand:SI 2 "const_int_operand" ""))
5392 (match_operand:SI 3 "const_int_operand" "")))]
5393 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5394 [(use (reg:SI R0_REG))]
5396 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5402 [(set (match_operand:SI 0 "register_operand" "")
5403 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5404 (match_operand:SI 2 "const_int_operand" ""))
5405 (match_operand:SI 3 "const_int_operand" "")))
5406 (clobber (reg:SI T_REG))]
5407 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5408 [(use (reg:SI R0_REG))]
5410 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5416 [(set (match_operand:SI 0 "register_operand" "=r")
5417 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5418 (match_operand:SI 2 "const_int_operand" "n"))
5419 (match_operand:SI 3 "const_int_operand" "n")))
5420 (clobber (reg:SI T_REG))]
5421 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
5423 [(set (attr "length")
5424 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5426 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5428 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5430 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
5432 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
5434 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
5436 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
5437 (const_string "16")]
5438 (const_string "18")))
5439 (set_attr "type" "arith")])
5442 [(set (match_operand:SI 0 "register_operand" "=z")
5443 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5444 (match_operand:SI 2 "const_int_operand" "n"))
5445 (match_operand:SI 3 "const_int_operand" "n")))
5446 (clobber (reg:SI T_REG))]
5447 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
5449 [(set (attr "length")
5450 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5452 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5454 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5456 (const_string "10")))
5457 (set_attr "type" "arith")])
5459 ;; shift left / and combination with a scratch register: The combine pass
5460 ;; does not accept the individual instructions, even though they are
5461 ;; cheap. But it needs a precise description so that it is usable after
5463 (define_insn "and_shl_scratch"
5464 [(set (match_operand:SI 0 "register_operand" "=r,&r")
5468 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5469 (match_operand:SI 2 "const_int_operand" "N,n"))
5470 (match_operand:SI 3 "" "0,r"))
5471 (match_operand:SI 4 "const_int_operand" "n,n"))
5472 (match_operand:SI 5 "const_int_operand" "n,n")))
5473 (clobber (reg:SI T_REG))]
5476 [(set (attr "length")
5477 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5479 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5481 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5483 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5484 (const_string "10")]
5485 (const_string "12")))
5486 (set_attr "type" "arith")])
5489 [(set (match_operand:SI 0 "register_operand" "")
5493 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5494 (match_operand:SI 2 "const_int_operand" ""))
5495 (match_operand:SI 3 "register_operand" ""))
5496 (match_operand:SI 4 "const_int_operand" ""))
5497 (match_operand:SI 5 "const_int_operand" "")))
5498 (clobber (reg:SI T_REG))]
5500 [(use (reg:SI R0_REG))]
5502 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5504 if (INTVAL (operands[2]))
5506 gen_shifty_op (LSHIFTRT, operands);
5508 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5509 operands[2] = operands[4];
5510 gen_shifty_op (ASHIFT, operands);
5511 if (INTVAL (operands[5]))
5513 operands[2] = operands[5];
5514 gen_shifty_op (LSHIFTRT, operands);
5519 ;; signed left/right shift combination.
5521 [(set (match_operand:SI 0 "register_operand" "")
5523 (ashift:SI (match_operand:SI 1 "register_operand" "")
5524 (match_operand:SI 2 "const_int_operand" ""))
5525 (match_operand:SI 3 "const_int_operand" "")
5527 (clobber (reg:SI T_REG))]
5529 [(use (reg:SI R0_REG))]
5531 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5536 (define_insn "shl_sext_ext"
5537 [(set (match_operand:SI 0 "register_operand" "=r")
5539 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5540 (match_operand:SI 2 "const_int_operand" "n"))
5541 (match_operand:SI 3 "const_int_operand" "n")
5543 (clobber (reg:SI T_REG))]
5544 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5546 [(set (attr "length")
5547 (cond [(match_test "shl_sext_length (insn)")
5549 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5551 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5553 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5555 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5557 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5559 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5561 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5562 (const_string "16")]
5563 (const_string "18")))
5564 (set_attr "type" "arith")])
5566 (define_insn "shl_sext_sub"
5567 [(set (match_operand:SI 0 "register_operand" "=z")
5569 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5570 (match_operand:SI 2 "const_int_operand" "n"))
5571 (match_operand:SI 3 "const_int_operand" "n")
5573 (clobber (reg:SI T_REG))]
5574 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5576 [(set (attr "length")
5577 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5579 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5581 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5583 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5584 (const_string "12")]
5585 (const_string "14")))
5586 (set_attr "type" "arith")])
5588 ;; The xtrct_left and xtrct_right patterns are used in expansions of DImode
5589 ;; shifts by 16, and allow the xtrct instruction to be generated from C
5591 (define_insn "xtrct_left"
5592 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5593 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5595 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5599 [(set_attr "type" "arith")])
5601 (define_insn "xtrct_right"
5602 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5603 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5605 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5609 [(set_attr "type" "arith")])
5611 ;; -------------------------------------------------------------------------
5613 ;; -------------------------------------------------------------------------
5616 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5617 (neg:SI (plus:SI (reg:SI T_REG)
5618 (match_operand:SI 1 "arith_reg_operand" "r"))))
5620 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5624 [(set_attr "type" "arith")])
5626 ;; A simplified version of the negc insn, where the exact value of the
5627 ;; T bit doesn't matter. This is easier for combine to pick up.
5628 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5629 ;; extra patterns for this case.
5630 (define_insn "*negc"
5631 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5632 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5633 (match_operand:SI 2 "t_reg_operand" "")))
5634 (clobber (reg:SI T_REG))]
5637 [(set_attr "type" "arith")])
5639 (define_insn "*negdi_media"
5640 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5641 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5644 [(set_attr "type" "arith_media")])
5646 ;; Don't split into individual negc insns immediately so that neg:DI (abs:DI)
5648 (define_expand "negdi2"
5649 [(parallel [(set (match_operand:DI 0 "arith_reg_dest")
5650 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5651 (clobber (reg:SI T_REG))])]
5654 (define_insn_and_split "*negdi2"
5655 [(set (match_operand:DI 0 "arith_reg_dest")
5656 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5657 (clobber (reg:SI T_REG))]
5660 "&& can_create_pseudo_p ()"
5663 emit_insn (gen_clrt ());
5664 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5665 gen_lowpart (SImode, operands[1])));
5666 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5667 gen_highpart (SImode, operands[1])));
5671 (define_insn "negsi2"
5672 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5673 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5676 [(set_attr "type" "arith")])
5678 (define_insn_and_split "one_cmplsi2"
5679 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5680 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5683 "&& can_create_pseudo_p ()"
5684 [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
5685 (set (match_dup 0) (reg:SI T_REG))]
5688 If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
5691 (set (reg0) (not:SI (reg0) (reg1)))
5692 (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
5693 (clobber (reg:SI T_REG))])
5695 ... match and combine the sequence manually in the split pass after the
5696 combine pass. Notice that combine does try the target pattern of this
5697 split, but if the pattern is added it interferes with other patterns, in
5698 particular with the div0s comparisons.
5699 This could also be done with a peephole but doing it here before register
5700 allocation can save one temporary.
5701 When we're here, the not:SI pattern obviously has been matched already
5702 and we only have to see whether the following insn is the left shift. */
5704 rtx i = next_nonnote_insn_bb (curr_insn);
5705 if (i == NULL_RTX || !NONJUMP_INSN_P (i))
5708 rtx p = PATTERN (i);
5709 if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
5712 rtx p0 = XVECEXP (p, 0, 0);
5713 rtx p1 = XVECEXP (p, 0, 1);
5715 if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
5716 GET_CODE (p0) == SET
5717 && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
5718 && REG_P (XEXP (XEXP (p0, 1), 0))
5719 && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
5720 && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
5721 && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
5723 /* (clobber (reg:SI T_REG)) */
5724 && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
5725 && REGNO (XEXP (p1, 0)) == T_REG)
5727 operands[0] = XEXP (p0, 0);
5728 set_insn_deleted (i);
5733 [(set_attr "type" "arith")])
5735 (define_expand "one_cmpldi2"
5736 [(set (match_operand:DI 0 "arith_reg_dest" "")
5737 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
5739 "TARGET_SHMEDIA" "")
5741 (define_expand "abs<mode>2"
5742 [(parallel [(set (match_operand:SIDI 0 "arith_reg_dest")
5743 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5744 (clobber (reg:SI T_REG))])]
5747 (define_insn_and_split "*abs<mode>2"
5748 [(set (match_operand:SIDI 0 "arith_reg_dest")
5749 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5750 (clobber (reg:SI T_REG))]
5753 "&& can_create_pseudo_p ()"
5756 if (<MODE>mode == SImode)
5757 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5760 rtx high_src = gen_highpart (SImode, operands[1]);
5761 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5764 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5769 (define_insn_and_split "*negabs<mode>2"
5770 [(set (match_operand:SIDI 0 "arith_reg_dest")
5771 (neg:SIDI (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand"))))
5772 (clobber (reg:SI T_REG))]
5775 "&& can_create_pseudo_p ()"
5778 if (<MODE>mode == SImode)
5779 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5782 rtx high_src = gen_highpart (SImode, operands[1]);
5783 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5786 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5791 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
5792 ;; This can be used as some kind of conditional execution, which is useful
5794 ;; Actually the instruction scheduling should decide whether to use a
5795 ;; zero-offset branch or not for any generic case involving a single
5796 ;; instruction on SH4 202.
5797 (define_insn_and_split "negsi_cond"
5798 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5800 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand" "M,N"))
5801 (match_operand:SI 1 "arith_reg_operand" "0,0")
5802 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
5803 "TARGET_SH1 && TARGET_ZDCBRANCH"
5805 static const char* alt[] =
5815 return alt[which_alternative];
5817 "TARGET_SH1 && ! TARGET_ZDCBRANCH"
5820 rtx skip_neg_label = gen_label_rtx ();
5822 emit_move_insn (operands[0], operands[1]);
5824 emit_jump_insn (INTVAL (operands[3])
5825 ? gen_branch_true (skip_neg_label)
5826 : gen_branch_false (skip_neg_label));
5828 emit_label_after (skip_neg_label,
5829 emit_insn (gen_negsi2 (operands[0], operands[1])));
5832 [(set_attr "type" "arith") ;; poor approximation
5833 (set_attr "length" "4")])
5835 (define_insn_and_split "negdi_cond"
5836 [(set (match_operand:DI 0 "arith_reg_dest")
5838 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand"))
5839 (match_operand:DI 1 "arith_reg_operand")
5840 (neg:DI (match_operand:DI 2 "arith_reg_operand"))))
5841 (clobber (reg:SI T_REG))]
5844 "&& can_create_pseudo_p ()"
5847 rtx skip_neg_label = gen_label_rtx ();
5849 emit_move_insn (operands[0], operands[1]);
5851 emit_jump_insn (INTVAL (operands[3])
5852 ? gen_branch_true (skip_neg_label)
5853 : gen_branch_false (skip_neg_label));
5855 if (!INTVAL (operands[3]))
5856 emit_insn (gen_clrt ());
5858 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5859 gen_lowpart (SImode, operands[1])));
5860 emit_label_after (skip_neg_label,
5861 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5862 gen_highpart (SImode, operands[1]))));
5866 (define_expand "bswapsi2"
5867 [(set (match_operand:SI 0 "arith_reg_dest" "")
5868 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
5871 if (! can_create_pseudo_p ())
5875 rtx tmp0 = gen_reg_rtx (SImode);
5876 rtx tmp1 = gen_reg_rtx (SImode);
5878 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
5879 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
5880 emit_insn (gen_swapbsi2 (operands[0], tmp1));
5885 (define_insn "swapbsi2"
5886 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5887 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
5888 (const_int 4294901760))
5889 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5891 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5892 (const_int 255)))))]
5895 [(set_attr "type" "arith")])
5897 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
5898 ;; partial byte swap expressions such as...
5899 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
5900 ;; ...which are currently not handled by the tree optimizers.
5901 ;; The combine pass will not initially try to combine the full expression,
5902 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
5903 ;; pattern acts as an intermediate pattern that will eventually lead combine
5904 ;; to the swapbsi2 pattern above.
5905 ;; As a side effect this also improves code that does (x & 0xFF) << 8
5906 ;; or (x << 8) & 0xFF00.
5907 (define_insn_and_split "*swapbisi2_and_shl8"
5908 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5909 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5912 (match_operand:SI 2 "arith_reg_operand" "r")))]
5913 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5915 "&& can_create_pseudo_p ()"
5918 rtx tmp0 = gen_reg_rtx (SImode);
5919 rtx tmp1 = gen_reg_rtx (SImode);
5921 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
5922 emit_insn (gen_swapbsi2 (tmp1, tmp0));
5923 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
5927 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
5928 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
5929 (define_insn_and_split "*swapbhisi2"
5930 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5931 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5934 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
5935 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5937 "&& can_create_pseudo_p ()"
5940 rtx tmp = gen_reg_rtx (SImode);
5942 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
5943 emit_insn (gen_swapbsi2 (operands[0], tmp));
5947 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
5951 ;; which can be simplified to...
5954 [(set (match_operand:SI 0 "arith_reg_dest" "")
5955 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5956 (const_int 4294901760))
5957 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5959 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5961 (set (match_operand:SI 2 "arith_reg_dest" "")
5963 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
5965 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5966 (const_int 4294901760))
5967 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5969 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5970 (const_int 255)))))])
5972 ;; -------------------------------------------------------------------------
5973 ;; Zero extension instructions
5974 ;; -------------------------------------------------------------------------
5976 (define_insn "zero_extendsidi2"
5977 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5978 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
5980 "addz.l %1, r63, %0"
5981 [(set_attr "type" "arith_media")
5982 (set_attr "highpart" "extend")])
5984 (define_insn "zero_extendhidi2"
5985 [(set (match_operand:DI 0 "register_operand" "=r,r")
5986 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5991 [(set_attr "type" "*,load_media")
5992 (set (attr "highpart")
5993 (cond [(match_test "sh_contains_memref_p (insn)")
5994 (const_string "user")]
5995 (const_string "ignore")))])
5998 [(set (match_operand:DI 0 "register_operand" "")
5999 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
6000 "TARGET_SHMEDIA && reload_completed"
6001 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
6002 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6004 if (GET_CODE (operands[1]) == TRUNCATE)
6005 operands[1] = XEXP (operands[1], 0);
6008 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
6009 ;; reload the entire truncate expression.
6010 (define_insn_and_split "*loaddi_trunc"
6011 [(set (match_operand 0 "any_register_operand" "=r")
6012 (truncate (match_operand:DI 1 "memory_operand" "m")))]
6013 "TARGET_SHMEDIA && reload_completed"
6015 "TARGET_SHMEDIA && reload_completed"
6016 [(set (match_dup 0) (match_dup 1))]
6018 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6021 (define_insn "zero_extendqidi2"
6022 [(set (match_operand:DI 0 "register_operand" "=r,r")
6023 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6028 [(set_attr "type" "arith_media,load_media")
6029 (set (attr "highpart")
6030 (cond [(match_test "sh_contains_memref_p (insn)")
6031 (const_string "user")]
6032 (const_string "ignore")))])
6034 (define_expand "zero_extend<mode>si2"
6035 [(set (match_operand:SI 0 "arith_reg_dest")
6036 (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
6038 (define_insn_and_split "*zero_extend<mode>si2_compact"
6039 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6040 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6043 "&& can_create_pseudo_p ()"
6044 [(set (match_dup 0) (match_dup 2))]
6046 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6047 reg with a following zero extension. In the split pass after combine,
6048 try to figure out how the extended reg was set. If it originated from
6049 the T bit we can replace the zero extension with a reg move, which will
6050 be eliminated. Notice that this also helps the *cbranch_t splitter when
6051 it tries to post-combine tests and conditional branches, as it does not
6052 check for zero extensions. */
6053 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6054 if (operands[2] == NULL_RTX)
6057 [(set_attr "type" "arith")])
6059 (define_insn "*zero_extendhisi2_media"
6060 [(set (match_operand:SI 0 "register_operand" "=r,r")
6061 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6066 [(set_attr "type" "arith_media,load_media")
6067 (set (attr "highpart")
6068 (cond [(match_test "sh_contains_memref_p (insn)")
6069 (const_string "user")]
6070 (const_string "ignore")))])
6073 [(set (match_operand:SI 0 "register_operand" "")
6074 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6075 "TARGET_SHMEDIA && reload_completed"
6076 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6077 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
6079 rtx op1 = operands[1];
6081 if (GET_CODE (op1) == TRUNCATE)
6082 op1 = XEXP (op1, 0);
6084 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6085 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6088 (define_insn "*zero_extendqisi2_media"
6089 [(set (match_operand:SI 0 "register_operand" "=r,r")
6090 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6095 [(set_attr "type" "arith_media,load_media")
6096 (set (attr "highpart")
6097 (cond [(match_test "sh_contains_memref_p (insn)")
6098 (const_string "user")]
6099 (const_string "ignore")))])
6101 (define_insn "zero_extendqihi2"
6102 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6103 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6106 [(set_attr "type" "arith")])
6108 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
6109 ;; They could also be used for simple memory addresses like @Rn by setting
6110 ;; the displacement value to zero. However, doing so too early results in
6111 ;; missed opportunities for other optimizations such as post-inc or index
6112 ;; addressing loads.
6113 ;; Although the 'zero_extend_movu_operand' predicate does not allow simple
6114 ;; register addresses (an address without a displacement, index, post-inc),
6115 ;; zero-displacement addresses might be generated during reload, wich are
6116 ;; simplified to simple register addresses in turn. Thus, we have to
6117 ;; provide the Sdd and Sra alternatives in the patterns.
6118 (define_insn "*zero_extend<mode>si2_disp_mem"
6119 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
6121 (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
6125 movu.<bw> @(0,%t1),%0"
6126 [(set_attr "type" "load")
6127 (set_attr "length" "4")])
6129 ;; Convert the zero extending loads in sequences such as:
6130 ;; movu.b @(1,r5),r0 movu.w @(2,r5),r0
6131 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6133 ;; back to sign extending loads like:
6134 ;; mov.b @(1,r5),r0 mov.w @(2,r5),r0
6135 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6137 ;; if the extension type is irrelevant. The sign extending mov.{b|w} insn
6138 ;; is only 2 bytes in size if the displacement is {K04|K05}.
6139 ;; If the displacement is greater it doesn't matter, so we convert anyways.
6141 [(set (match_operand:SI 0 "arith_reg_dest" "")
6142 (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
6143 (set (match_operand 2 "nonimmediate_operand" "")
6144 (match_operand 3 "arith_reg_operand" ""))]
6146 && REGNO (operands[0]) == REGNO (operands[3])
6147 && peep2_reg_dead_p (2, operands[0])
6148 && GET_MODE_SIZE (GET_MODE (operands[2]))
6149 <= GET_MODE_SIZE (GET_MODE (operands[1]))"
6150 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
6151 (set (match_dup 2) (match_dup 3))])
6153 ;; Fold sequences such as
6157 ;; movu.b @(0,r3),r7
6158 ;; This does not reduce the code size but the number of instructions is
6159 ;; halved, which results in faster code.
6161 [(set (match_operand:SI 0 "arith_reg_dest" "")
6162 (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
6163 (set (match_operand:SI 2 "arith_reg_dest" "")
6164 (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
6166 && GET_MODE (operands[1]) == GET_MODE (operands[3])
6167 && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
6168 && REGNO (operands[0]) == REGNO (operands[3])
6169 && (REGNO (operands[2]) == REGNO (operands[0])
6170 || peep2_reg_dead_p (2, operands[0]))"
6171 [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
6174 = replace_equiv_address (operands[1],
6175 gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
6179 ;; -------------------------------------------------------------------------
6180 ;; Sign extension instructions
6181 ;; -------------------------------------------------------------------------
6183 ;; ??? This should be a define expand.
6184 ;; ??? Or perhaps it should be dropped?
6186 ;; convert_move generates good code for SH[1-4].
6187 (define_insn "extendsidi2"
6188 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6189 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
6195 [(set_attr "type" "arith_media,load_media,fpconv_media")
6196 (set (attr "highpart")
6197 (cond [(match_test "sh_contains_memref_p (insn)")
6198 (const_string "user")]
6199 (const_string "extend")))])
6201 (define_insn "extendhidi2"
6202 [(set (match_operand:DI 0 "register_operand" "=r,r")
6203 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6208 [(set_attr "type" "*,load_media")
6209 (set (attr "highpart")
6210 (cond [(match_test "sh_contains_memref_p (insn)")
6211 (const_string "user")]
6212 (const_string "ignore")))])
6215 [(set (match_operand:DI 0 "register_operand" "")
6216 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
6217 "TARGET_SHMEDIA && reload_completed"
6218 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
6219 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6221 if (GET_CODE (operands[1]) == TRUNCATE)
6222 operands[1] = XEXP (operands[1], 0);
6225 (define_insn "extendqidi2"
6226 [(set (match_operand:DI 0 "register_operand" "=r,r")
6227 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6232 [(set_attr "type" "*,load_media")
6233 (set (attr "highpart")
6234 (cond [(match_test "sh_contains_memref_p (insn)")
6235 (const_string "user")]
6236 (const_string "ignore")))])
6239 [(set (match_operand:DI 0 "register_operand" "")
6240 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
6241 "TARGET_SHMEDIA && reload_completed"
6242 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
6243 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6245 if (GET_CODE (operands[1]) == TRUNCATE)
6246 operands[1] = XEXP (operands[1], 0);
6249 (define_expand "extend<mode>si2"
6250 [(set (match_operand:SI 0 "arith_reg_dest")
6251 (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
6253 (define_insn "*extendhisi2_media"
6254 [(set (match_operand:SI 0 "register_operand" "=r,r")
6255 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6260 [(set_attr "type" "arith_media,load_media")
6261 (set (attr "highpart")
6262 (cond [(match_test "sh_contains_memref_p (insn)")
6263 (const_string "user")]
6264 (const_string "ignore")))])
6267 [(set (match_operand:SI 0 "register_operand" "")
6268 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6269 "TARGET_SHMEDIA && reload_completed"
6270 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6271 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
6273 rtx op1 = operands[1];
6274 if (GET_CODE (op1) == TRUNCATE)
6275 op1 = XEXP (op1, 0);
6277 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6278 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6281 (define_insn_and_split "*extend<mode>si2_compact_reg"
6282 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6283 (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6286 "&& can_create_pseudo_p ()"
6287 [(set (match_dup 0) (match_dup 2))]
6289 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6290 reg with a following sign extension. In the split pass after combine,
6291 try to figure the extended reg was set. If it originated from the T
6292 bit we can replace the sign extension with a reg move, which will be
6294 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6295 if (operands[2] == NULL_RTX)
6298 [(set_attr "type" "arith")])
6300 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
6302 (define_insn "*extend<mode>si2_compact_mem_disp"
6303 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
6307 (match_operand:SI 1 "arith_reg_operand" "%r,r")
6308 (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
6309 "TARGET_SH1 && ! TARGET_SH2A
6310 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6312 mov.<bw> @(%O2,%1),%0
6314 [(set_attr "type" "load")])
6316 (define_insn "*extend<mode>si2_compact_mem_disp"
6317 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
6321 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6322 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
6323 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6325 mov.<bw> @(%O2,%1),%0
6327 mov.<bw> @(%O2,%1),%0"
6328 [(set_attr "type" "load")
6329 (set_attr "length" "2,2,4")])
6331 ;; The *_snd patterns will take care of other QImode/HImode addressing
6332 ;; modes than displacement addressing. They must be defined _after_ the
6333 ;; displacement addressing patterns. Otherwise the displacement addressing
6334 ;; patterns will not be picked.
6335 (define_insn "*extend<mode>si2_compact_snd"
6336 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6338 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
6341 [(set_attr "type" "load")])
6343 (define_insn "*extendqisi2_media"
6344 [(set (match_operand:SI 0 "register_operand" "=r,r")
6345 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6350 [(set_attr "type" "arith_media,load_media")
6351 (set (attr "highpart")
6352 (cond [(match_test "sh_contains_memref_p (insn)")
6353 (const_string "user")]
6354 (const_string "ignore")))])
6357 [(set (match_operand:SI 0 "register_operand" "")
6358 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
6359 "TARGET_SHMEDIA && reload_completed"
6360 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
6361 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
6363 rtx op1 = operands[1];
6364 if (GET_CODE (op1) == TRUNCATE)
6365 op1 = XEXP (op1, 0);
6367 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6368 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6371 (define_expand "extendqihi2"
6372 [(set (match_operand:HI 0 "arith_reg_dest" "")
6373 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
6377 (define_insn "*extendqihi2_compact_reg"
6378 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6379 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6382 [(set_attr "type" "arith")])
6384 ;; It would seem useful to combine the truncXi patterns into the movXi
6385 ;; patterns, but unary operators are ignored when matching constraints,
6386 ;; so we need separate patterns.
6387 (define_insn "truncdisi2"
6388 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
6389 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
6398 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,
6399 fpconv_media,fmove_media")
6400 (set (attr "highpart")
6401 (cond [(match_test "sh_contains_memref_p (insn)")
6402 (const_string "user")]
6403 (const_string "extend")))])
6405 (define_insn "truncdihi2"
6406 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
6407 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
6410 static const char* alt[] =
6412 "shlli %1,48,%0" "\n"
6417 return alt[which_alternative];
6419 [(set_attr "type" "arith_media,store_media")
6420 (set_attr "length" "8,4")
6421 (set (attr "highpart")
6422 (cond [(match_test "sh_contains_memref_p (insn)")
6423 (const_string "user")]
6424 (const_string "extend")))])
6426 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
6427 ; Because we use zero extension, we can't provide signed QImode compares
6428 ; using a simple compare or conditional branch insn.
6429 (define_insn "truncdiqi2"
6430 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
6431 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
6436 [(set_attr "type" "arith_media,store")
6437 (set (attr "highpart")
6438 (cond [(match_test "sh_contains_memref_p (insn)")
6439 (const_string "user")]
6440 (const_string "extend")))])
6442 ;; -------------------------------------------------------------------------
6443 ;; Move instructions
6444 ;; -------------------------------------------------------------------------
6446 ;; define push and pop so it is easy for sh.c
6447 ;; We can't use push and pop on SHcompact because the stack must always
6448 ;; be 8-byte aligned.
6449 (define_expand "push"
6450 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6451 (match_operand:SI 0 "register_operand" "r,l,x"))]
6452 "TARGET_SH1 && ! TARGET_SH5"
6455 (define_expand "pop"
6456 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6457 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6458 "TARGET_SH1 && ! TARGET_SH5"
6461 (define_expand "push_e"
6462 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6463 (match_operand:SF 0 "" ""))
6464 (use (reg:SI FPSCR_MODES_REG))
6465 (clobber (scratch:SI))])]
6466 "TARGET_SH1 && ! TARGET_SH5"
6469 (define_insn "push_fpul"
6470 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6471 "TARGET_SH2E && ! TARGET_SH5"
6473 [(set_attr "type" "fstore")
6474 (set_attr "late_fp_use" "yes")
6475 (set_attr "hit_stack" "yes")])
6477 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6479 (define_expand "push_4"
6480 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6481 (match_operand:DF 0 "" ""))
6482 (use (reg:SI FPSCR_MODES_REG))
6483 (clobber (scratch:SI))])]
6484 "TARGET_SH1 && ! TARGET_SH5"
6487 (define_expand "pop_e"
6488 [(parallel [(set (match_operand:SF 0 "" "")
6489 (mem:SF (post_inc:SI (reg:SI SP_REG))))
6490 (use (reg:SI FPSCR_MODES_REG))
6491 (clobber (scratch:SI))])]
6492 "TARGET_SH1 && ! TARGET_SH5"
6495 (define_insn "pop_fpul"
6496 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6497 "TARGET_SH2E && ! TARGET_SH5"
6499 [(set_attr "type" "load")
6500 (set_attr "hit_stack" "yes")])
6502 (define_expand "pop_4"
6503 [(parallel [(set (match_operand:DF 0 "" "")
6504 (mem:DF (post_inc:SI (reg:SI SP_REG))))
6505 (use (reg:SI FPSCR_MODES_REG))
6506 (clobber (scratch:SI))])]
6507 "TARGET_SH1 && ! TARGET_SH5"
6510 (define_expand "push_fpscr"
6517 gen_frame_mem (SImode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)))),
6518 REG_INC, stack_pointer_rtx);
6522 (define_expand "pop_fpscr"
6529 gen_frame_mem (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx)))),
6530 REG_INC, stack_pointer_rtx);
6534 ;; The clrt and sett patterns can happen as the result of optimization and
6536 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6537 ;; In this case they might not disappear completely, because the T reg is
6538 ;; a fixed hard reg.
6539 ;; When DImode operations that use the T reg as carry/borrow are split into
6540 ;; individual SImode operations, the T reg is usually cleared before the
6541 ;; first SImode insn.
6543 [(set (reg:SI T_REG) (const_int 0))]
6546 [(set_attr "type" "mt_group")])
6549 [(set (reg:SI T_REG) (const_int 1))]
6552 [(set_attr "type" "mt_group")])
6554 ;; Use the combine pass to transform sequences such as
6558 ;; mov.l @(r0,r4),r0
6564 ;; See also PR 39423.
6565 ;; Notice that these patterns have a T_REG clobber, because the shift
6566 ;; sequence that will be split out might clobber the T_REG. Ideally, the
6567 ;; clobber would be added conditionally, depending on the result of
6568 ;; sh_ashlsi_clobbers_t_reg_p. When splitting out the shifts we must go
6569 ;; through the ashlsi3 expander in order to get the right shift insn --
6570 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6571 ;; FIXME: Combine never tries this kind of patterns for DImode.
6572 (define_insn_and_split "*movsi_index_disp_load"
6573 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6574 (match_operand:SI 1 "mem_index_disp_operand" "m"))
6575 (clobber (reg:SI T_REG))]
6578 "&& can_create_pseudo_p ()"
6579 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6580 (set (match_dup 0) (match_dup 7))]
6582 rtx mem = operands[1];
6583 rtx plus0_rtx = XEXP (mem, 0);
6584 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6585 rtx mult_rtx = XEXP (plus1_rtx, 0);
6587 operands[1] = XEXP (mult_rtx, 0);
6588 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6589 operands[3] = XEXP (plus1_rtx, 1);
6590 operands[4] = XEXP (plus0_rtx, 1);
6591 operands[5] = gen_reg_rtx (SImode);
6592 operands[6] = gen_reg_rtx (SImode);
6594 replace_equiv_address (mem,
6595 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6597 emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6600 (define_insn_and_split "*movhi_index_disp_load"
6601 [(set (match_operand:SI 0 "arith_reg_dest")
6602 (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6603 (clobber (reg:SI T_REG))]
6606 "&& can_create_pseudo_p ()"
6609 rtx mem = operands[1];
6610 rtx plus0_rtx = XEXP (mem, 0);
6611 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6612 rtx mult_rtx = XEXP (plus1_rtx, 0);
6614 rtx op_1 = XEXP (mult_rtx, 0);
6615 rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6616 rtx op_3 = XEXP (plus1_rtx, 1);
6617 rtx op_4 = XEXP (plus0_rtx, 1);
6618 rtx op_5 = gen_reg_rtx (SImode);
6619 rtx op_6 = gen_reg_rtx (SImode);
6620 rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6622 emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6623 emit_insn (gen_addsi3 (op_6, op_5, op_3));
6625 if (<CODE> == SIGN_EXTEND)
6627 emit_insn (gen_extendhisi2 (operands[0], op_7));
6630 else if (<CODE> == ZERO_EXTEND)
6632 /* On SH2A the movu.w insn can be used for zero extending loads. */
6634 emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
6637 emit_insn (gen_extendhisi2 (operands[0], op_7));
6638 emit_insn (gen_zero_extendhisi2 (operands[0],
6639 gen_lowpart (HImode, operands[0])));
6647 (define_insn_and_split "*mov<mode>_index_disp_store"
6648 [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
6649 (match_operand:HISI 1 "arith_reg_operand" "r"))
6650 (clobber (reg:SI T_REG))]
6653 "&& can_create_pseudo_p ()"
6654 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6655 (set (match_dup 7) (match_dup 1))]
6657 rtx mem = operands[0];
6658 rtx plus0_rtx = XEXP (mem, 0);
6659 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6660 rtx mult_rtx = XEXP (plus1_rtx, 0);
6662 operands[0] = XEXP (mult_rtx, 0);
6663 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6664 operands[3] = XEXP (plus1_rtx, 1);
6665 operands[4] = XEXP (plus0_rtx, 1);
6666 operands[5] = gen_reg_rtx (SImode);
6667 operands[6] = gen_reg_rtx (SImode);
6669 replace_equiv_address (mem,
6670 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6672 emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
6675 ;; t/r must come after r/r, lest reload will try to reload stuff like
6676 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
6677 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
6678 (define_insn "movsi_i"
6679 [(set (match_operand:SI 0 "general_movdst_operand"
6680 "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
6681 (match_operand:SI 1 "general_movsrc_operand"
6682 "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
6686 && (register_operand (operands[0], SImode)
6687 || register_operand (operands[1], SImode))"
6703 [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,
6704 pstore,gp_mac,prset,mem_mac,pload,pcload_si")
6705 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
6707 ;; t/r must come after r/r, lest reload will try to reload stuff like
6708 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
6709 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
6710 ;; will require a reload.
6711 ;; ??? We can't include f/f because we need the proper FPSCR setting when
6712 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
6713 (define_insn "movsi_ie"
6714 [(set (match_operand:SI 0 "general_movdst_operand"
6715 "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
6716 (match_operand:SI 1 "general_movsrc_operand"
6717 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
6718 "(TARGET_SH2E || TARGET_SH2A)
6719 && ((register_operand (operands[0], SImode)
6720 && !fpscr_operand (operands[0], SImode))
6721 || (register_operand (operands[1], SImode)
6722 && !fpscr_operand (operands[1], SImode)))"
6747 ! move optimized away"
6748 [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,
6749 mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,
6750 pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
6751 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
6752 (set_attr_alternative "length"
6759 (match_test "TARGET_SH2A")
6760 (const_int 4) (const_int 2))
6764 (match_test "TARGET_SH2A")
6765 (const_int 4) (const_int 2))
6782 (define_insn "movsi_i_lowpart"
6783 [(set (strict_low_part
6784 (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
6785 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
6787 && (register_operand (operands[0], SImode)
6788 || register_operand (operands[1], SImode))"
6798 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
6800 (define_insn_and_split "load_ra"
6801 [(set (match_operand:SI 0 "general_movdst_operand" "")
6802 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
6805 "&& ! currently_expanding_to_rtl"
6806 [(set (match_dup 0) (match_dup 1))]
6808 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
6809 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
6812 ;; The '?'s in the following constraints may not reflect the time taken
6813 ;; to perform the move. They are there to discourage the use of floating-
6814 ;; point registers for storing integer values.
6815 (define_insn "*movsi_media"
6816 [(set (match_operand:SI 0 "general_movdst_operand"
6817 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
6818 (match_operand:SI 1 "general_movsrc_operand"
6819 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6821 && (register_operand (operands[0], SImode)
6822 || sh_register_operand (operands[1], SImode)
6823 || GET_CODE (operands[1]) == TRUNCATE)"
6838 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6839 fload_media,fstore_media,fload_media,fpconv_media,
6840 fmove_media,ptabs_media,gettr_media,pt_media")
6841 (set_attr "length" "4,4,8,4,4,4,4,4,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_insn "*movsi_media_nofpu"
6848 [(set (match_operand:SI 0 "general_movdst_operand"
6849 "=r,r,r,r,m,*b,r,*b")
6850 (match_operand:SI 1 "general_movsrc_operand"
6851 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
6853 && (register_operand (operands[0], SImode)
6854 || sh_register_operand (operands[1], SImode)
6855 || GET_CODE (operands[1]) == TRUNCATE)"
6865 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6866 ptabs_media,gettr_media,pt_media")
6867 (set_attr "length" "4,4,8,4,4,4,4,12")
6868 (set (attr "highpart")
6869 (cond [(match_test "sh_contains_memref_p (insn)")
6870 (const_string "user")]
6871 (const_string "ignore")))])
6873 (define_expand "movsi_const"
6874 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6875 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6876 (const_int 16)] UNSPEC_EXTRACT_S16)))
6878 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
6879 (const:SI (unspec:SI [(match_dup 1)
6880 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6881 "TARGET_SHMEDIA && reload_completed
6882 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6884 if (GET_CODE (operands[1]) == LABEL_REF
6885 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
6886 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
6887 else if (GOTOFF_P (operands[1]))
6889 rtx unspec = XEXP (operands[1], 0);
6891 if (! UNSPEC_GOTOFF_P (unspec))
6893 unspec = XEXP (unspec, 0);
6894 if (! UNSPEC_GOTOFF_P (unspec))
6897 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
6898 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
6899 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
6903 (define_expand "movsi_const_16bit"
6904 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6905 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6906 (const_int 0)] UNSPEC_EXTRACT_S16)))]
6907 "TARGET_SHMEDIA && flag_pic && reload_completed
6908 && GET_CODE (operands[1]) == SYMBOL_REF"
6912 [(set (match_operand:SI 0 "arith_reg_dest" "")
6913 (match_operand:SI 1 "immediate_operand" ""))]
6914 "TARGET_SHMEDIA && reload_completed
6915 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6918 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
6920 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6926 [(set (match_operand:SI 0 "register_operand" "")
6927 (match_operand:SI 1 "immediate_operand" ""))]
6928 "TARGET_SHMEDIA && reload_completed
6929 && ((CONST_INT_P (operands[1])
6930 && ! satisfies_constraint_I16 (operands[1]))
6931 || GET_CODE (operands[1]) == CONST_DOUBLE)"
6932 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6934 (define_expand "movsi"
6935 [(set (match_operand:SI 0 "general_movdst_operand" "")
6936 (match_operand:SI 1 "general_movsrc_operand" ""))]
6939 prepare_move_operands (operands, SImode);
6942 (define_expand "ic_invalidate_line"
6943 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
6944 (match_dup 1)] UNSPEC_ICACHE)
6945 (clobber (scratch:SI))])]
6946 "TARGET_HARD_SH4 || TARGET_SH5"
6950 emit_insn (gen_ic_invalidate_line_media (operands[0]));
6953 else if (TARGET_SHCOMPACT)
6955 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
6956 operands[1] = force_reg (Pmode, operands[1]);
6957 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
6960 else if (TARGET_SH4A || TARGET_SH4_300)
6962 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
6965 operands[0] = force_reg (Pmode, operands[0]);
6966 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
6970 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
6971 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
6972 ;; the requirement *1*00 for associative address writes. The alignment of
6973 ;; %0 implies that its least significant bit is cleared,
6974 ;; thus we clear the V bit of a matching entry if there is one.
6975 (define_insn "ic_invalidate_line_i"
6976 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
6977 (match_operand:SI 1 "register_operand" "r")]
6979 (clobber (match_scratch:SI 2 "=&r"))]
6982 return "ocbwb @%0" "\n"
6983 " extu.w %0,%2" "\n"
6987 [(set_attr "length" "8")
6988 (set_attr "type" "cwb")])
6990 (define_insn "ic_invalidate_line_sh4a"
6991 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6993 "TARGET_SH4A || TARGET_SH4_300"
6995 return "ocbwb @%0" "\n"
6999 [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
7000 (set_attr "type" "cwb")])
7002 ;; ??? could make arg 0 an offsettable memory operand to allow to save
7003 ;; an add in the code that calculates the address.
7004 (define_insn "ic_invalidate_line_media"
7005 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
7009 return "ocbwb %0,0" "\n"
7014 [(set_attr "length" "16")
7015 (set_attr "type" "invalidate_line_media")])
7017 (define_insn "ic_invalidate_line_compact"
7018 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
7019 (match_operand:SI 1 "register_operand" "r")]
7021 (clobber (reg:SI PR_REG))]
7024 [(set_attr "type" "sfunc")
7025 (set_attr "needs_delay_slot" "yes")])
7027 (define_expand "initialize_trampoline"
7028 [(match_operand:SI 0 "" "")
7029 (match_operand:SI 1 "" "")
7030 (match_operand:SI 2 "" "")]
7035 tramp = force_reg (Pmode, operands[0]);
7036 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
7038 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
7039 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
7041 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
7045 (define_insn "initialize_trampoline_compact"
7046 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
7047 (match_operand:SI 1 "register_operand" "r")
7048 (reg:SI R2_REG) (reg:SI R3_REG)]
7051 (clobber (reg:SI PR_REG))]
7054 [(set_attr "type" "sfunc")
7055 (set_attr "needs_delay_slot" "yes")])
7057 (define_expand "mov<mode>"
7058 [(set (match_operand:QIHI 0 "general_movdst_operand")
7059 (match_operand:QIHI 1 "general_movsrc_operand"))]
7062 if (can_create_pseudo_p () && CONST_INT_P (operands[1])
7063 && REG_P (operands[0]) && REGNO (operands[0]) != R0_REG)
7065 rtx reg = gen_reg_rtx(SImode);
7066 emit_move_insn (reg, operands[1]);
7067 operands[1] = gen_lowpart (<MODE>mode, reg);
7070 prepare_move_operands (operands, <MODE>mode);
7073 ;; Specifying the displacement addressing load / store patterns separately
7074 ;; before the generic movqi / movhi pattern allows controlling the order
7075 ;; in which load / store insns are selected in a more fine grained way.
7076 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
7077 ;; "enabled" attribute as it is done in other targets.
7078 (define_insn "*mov<mode>_store_mem_disp04"
7080 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
7081 (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
7082 (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
7083 "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
7085 mov.<bw> %2,@(%O1,%0)
7087 [(set_attr "type" "store")])
7089 (define_insn "*mov<mode>_store_mem_disp12"
7091 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
7092 (match_operand:SI 1 "const_int_operand" "<disp12>")))
7093 (match_operand:QIHI 2 "arith_reg_operand" "r"))]
7094 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
7095 "mov.<bw> %2,@(%O1,%0)"
7096 [(set_attr "type" "store")
7097 (set_attr "length" "4")])
7099 (define_insn "*mov<mode>_load_mem_disp04"
7100 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
7102 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
7103 (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
7104 "TARGET_SH1 && ! TARGET_SH2A
7105 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
7107 mov.<bw> @(%O2,%1),%0
7109 [(set_attr "type" "load")])
7111 (define_insn "*mov<mode>_load_mem_disp12"
7112 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
7115 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
7116 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
7117 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
7119 mov.<bw> @(%O2,%1),%0
7121 mov.<bw> @(%O2,%1),%0"
7122 [(set_attr "type" "load")
7123 (set_attr "length" "2,2,4")])
7125 ;; The order of the constraint alternatives is important here.
7126 ;; Q/r has to come first, otherwise PC relative loads might wrongly get
7127 ;; placed into delay slots. Since there is no QImode PC relative load, the
7128 ;; Q constraint and general_movsrc_operand will reject it for QImode.
7129 ;; The Snd alternatives should come before Sdd in order to avoid a preference
7130 ;; of using r0 als the register operand for addressing modes other than
7131 ;; displacement addressing.
7132 ;; The Sdd alternatives allow only r0 as register operand, even though on
7133 ;; SH2A any register could be allowed by switching to a 32 bit insn.
7134 ;; Generally sticking to the r0 is preferrable, since it generates smaller
7135 ;; code. Obvious r0 reloads can then be eliminated with a peephole on SH2A.
7136 (define_insn "*mov<mode>"
7137 [(set (match_operand:QIHI 0 "general_movdst_operand"
7138 "=r,r,r,Snd,r, Sdd,z, r,l")
7139 (match_operand:QIHI 1 "general_movsrc_operand"
7140 "Q,r,i,r, Snd,z, Sdd,l,r"))]
7142 && (arith_reg_operand (operands[0], <MODE>mode)
7143 || arith_reg_operand (operands[1], <MODE>mode))"
7154 [(set_attr "type" "pcload,move,movi8,store,load,store,load,prget,prset")
7155 (set (attr "length")
7156 (cond [(and (match_operand 0 "displacement_mem_operand")
7157 (not (match_operand 0 "short_displacement_mem_operand")))
7159 (and (match_operand 1 "displacement_mem_operand")
7160 (not (match_operand 1 "short_displacement_mem_operand")))
7164 (define_insn "*movqi_media"
7165 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
7166 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
7168 && (arith_reg_operand (operands[0], QImode)
7169 || extend_reg_or_0_operand (operands[1], QImode))"
7175 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
7176 (set (attr "highpart")
7177 (cond [(match_test "sh_contains_memref_p (insn)")
7178 (const_string "user")]
7179 (const_string "ignore")))])
7181 (define_expand "reload_inqi"
7182 [(set (match_operand:SI 2 "" "=&r")
7183 (match_operand:QI 1 "inqhi_operand" ""))
7184 (set (match_operand:QI 0 "arith_reg_operand" "=r")
7185 (truncate:QI (match_dup 3)))]
7188 rtx inner = XEXP (operands[1], 0);
7189 int regno = REGNO (inner);
7191 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7192 operands[1] = gen_rtx_REG (SImode, regno);
7193 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7196 (define_insn "*movhi_media"
7197 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
7198 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
7200 && (arith_reg_operand (operands[0], HImode)
7201 || arith_reg_or_0_operand (operands[1], HImode))"
7208 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
7209 (set (attr "highpart")
7210 (cond [(match_test "sh_contains_memref_p (insn)")
7211 (const_string "user")]
7212 (const_string "ignore")))])
7215 [(set (match_operand:HI 0 "register_operand" "")
7216 (match_operand:HI 1 "immediate_operand" ""))]
7217 "TARGET_SHMEDIA && reload_completed
7218 && ! satisfies_constraint_I16 (operands[1])"
7219 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
7221 (define_expand "reload_inhi"
7222 [(set (match_operand:SI 2 "" "=&r")
7223 (match_operand:HI 1 "inqhi_operand" ""))
7224 (set (match_operand:HI 0 "arith_reg_operand" "=r")
7225 (truncate:HI (match_dup 3)))]
7228 rtx inner = XEXP (operands[1], 0);
7229 int regno = REGNO (inner);
7231 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7232 operands[1] = gen_rtx_REG (SImode, regno);
7233 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7236 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7237 ;; compiled with -m2 -ml -O3 -funroll-loops
7238 (define_insn "*movdi_i"
7239 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7240 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7242 && (arith_reg_operand (operands[0], DImode)
7243 || arith_reg_operand (operands[1], DImode))"
7245 return output_movedouble (insn, operands, DImode);
7247 [(set_attr "length" "4")
7248 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7250 ;; If the output is a register and the input is memory or a register, we have
7251 ;; to be careful and see which word needs to be loaded first.
7253 [(set (match_operand:DI 0 "general_movdst_operand" "")
7254 (match_operand:DI 1 "general_movsrc_operand" ""))]
7255 "TARGET_SH1 && reload_completed"
7256 [(set (match_dup 2) (match_dup 3))
7257 (set (match_dup 4) (match_dup 5))]
7261 if ((MEM_P (operands[0])
7262 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7263 || (MEM_P (operands[1])
7264 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7267 switch (GET_CODE (operands[0]))
7270 regno = REGNO (operands[0]);
7273 regno = subreg_regno (operands[0]);
7283 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7285 operands[2] = operand_subword (operands[0], 0, 0, DImode);
7286 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7287 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7288 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7292 operands[2] = operand_subword (operands[0], 1, 0, DImode);
7293 operands[3] = operand_subword (operands[1], 1, 0, DImode);
7294 operands[4] = operand_subword (operands[0], 0, 0, DImode);
7295 operands[5] = operand_subword (operands[1], 0, 0, DImode);
7298 if (operands[2] == 0 || operands[3] == 0
7299 || operands[4] == 0 || operands[5] == 0)
7303 ;; The '?'s in the following constraints may not reflect the time taken
7304 ;; to perform the move. They are there to discourage the use of floating-
7305 ;; point registers for storing integer values.
7306 (define_insn "*movdi_media"
7307 [(set (match_operand:DI 0 "general_movdst_operand"
7308 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7309 (match_operand:DI 1 "general_movsrc_operand"
7310 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7312 && (register_operand (operands[0], DImode)
7313 || sh_register_operand (operands[1], DImode))"
7328 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7329 fload_media,fstore_media,fload_media,dfpconv_media,
7330 fmove_media,ptabs_media,gettr_media,pt_media")
7331 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7333 (define_insn "*movdi_media_nofpu"
7334 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7335 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7337 && (register_operand (operands[0], DImode)
7338 || sh_register_operand (operands[1], DImode))"
7348 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7349 ptabs_media,gettr_media,pt_media")
7350 (set_attr "length" "4,4,16,4,4,4,4,*")])
7352 (define_insn "*movdi_media_I16"
7353 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7354 (match_operand:DI 1 "const_int_operand" "I16"))]
7355 "TARGET_SHMEDIA && reload_completed"
7357 [(set_attr "type" "arith_media")
7358 (set_attr "length" "4")])
7361 [(set (match_operand:DI 0 "arith_reg_dest" "")
7362 (match_operand:DI 1 "immediate_operand" ""))]
7363 "TARGET_SHMEDIA && reload_completed
7364 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7365 [(set (match_dup 0) (match_dup 1))]
7369 if (TARGET_SHMEDIA64)
7370 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7372 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7374 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7379 (define_expand "movdi_const"
7380 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7381 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7382 (const_int 48)] UNSPEC_EXTRACT_S16)))
7384 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7385 (const:DI (unspec:DI [(match_dup 1)
7386 (const_int 32)] UNSPEC_EXTRACT_U16))))
7388 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7389 (const:DI (unspec:DI [(match_dup 1)
7390 (const_int 16)] UNSPEC_EXTRACT_U16))))
7392 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7393 (const:DI (unspec:DI [(match_dup 1)
7394 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7395 "TARGET_SHMEDIA64 && reload_completed
7396 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7398 sh_mark_label (operands[1], 4);
7401 (define_expand "movdi_const_32bit"
7402 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7403 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7404 (const_int 16)] UNSPEC_EXTRACT_S16)))
7406 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7407 (const:DI (unspec:DI [(match_dup 1)
7408 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7409 "TARGET_SHMEDIA32 && reload_completed
7410 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7412 sh_mark_label (operands[1], 2);
7415 (define_expand "movdi_const_16bit"
7416 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7417 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7418 (const_int 0)] UNSPEC_EXTRACT_S16)))]
7419 "TARGET_SHMEDIA && flag_pic && reload_completed
7420 && GET_CODE (operands[1]) == SYMBOL_REF"
7424 [(set (match_operand:DI 0 "ext_dest_operand" "")
7425 (match_operand:DI 1 "immediate_operand" ""))]
7426 "TARGET_SHMEDIA && reload_completed
7427 && CONST_INT_P (operands[1])
7428 && ! satisfies_constraint_I16 (operands[1])"
7429 [(set (match_dup 0) (match_dup 2))
7432 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7433 unsigned HOST_WIDE_INT low = val;
7434 unsigned HOST_WIDE_INT high = val;
7435 unsigned HOST_WIDE_INT sign;
7436 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7438 /* Zero-extend the 16 least-significant bits. */
7441 /* Arithmetic shift right the word by 16 bits. */
7443 if (GET_CODE (operands[0]) == SUBREG
7444 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7453 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7459 /* If we can't generate the constant with a two-insn movi / shori
7460 sequence, try some other strategies. */
7461 if (! CONST_OK_FOR_I16 (high))
7463 /* Try constant load / left shift. We know VAL != 0. */
7464 val2 = val ^ (val-1);
7467 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7469 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7470 || (! CONST_OK_FOR_I16 (high >> 16)
7471 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7473 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7474 operands[1] = gen_ashldi3_media (operands[0], operands[0],
7475 GEN_INT (trailing_zeroes));
7479 /* Try constant load / right shift. */
7480 val2 = (val >> 15) + 1;
7481 if (val2 == (val2 & -val2))
7483 int shift = 49 - exact_log2 (val2);
7485 val2 = trunc_int_for_mode (val << shift, DImode);
7486 if (CONST_OK_FOR_I16 (val2))
7488 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7494 val2 = val & 0xffff;
7495 if ((val >> 16 & 0xffff) == val2
7496 && (val >> 32 & 0xffff) == val2
7497 && (val >> 48 & 0xffff) == val2)
7499 val2 = (HOST_WIDE_INT) val >> 48;
7500 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7501 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7504 /* Try movi / mshflo.l */
7505 val2 = (HOST_WIDE_INT) val >> 32;
7506 if (val2 == ((unsigned HOST_WIDE_INT)
7507 trunc_int_for_mode (val, SImode)))
7509 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7513 /* Try movi / mshflo.l w/ r63. */
7514 val2 = val + ((HOST_WIDE_INT) -1 << 32);
7515 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7517 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7523 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7526 operands[2] = GEN_INT (val2);
7530 [(set (match_operand:DI 0 "ext_dest_operand" "")
7531 (match_operand:DI 1 "immediate_operand" ""))]
7532 "TARGET_SHMEDIA && reload_completed
7533 && GET_CODE (operands[1]) == CONST_DOUBLE"
7534 [(set (match_dup 0) (match_dup 2))
7536 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7538 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7539 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7540 unsigned HOST_WIDE_INT val = low;
7541 unsigned HOST_WIDE_INT sign;
7543 /* Zero-extend the 16 least-significant bits. */
7545 operands[1] = GEN_INT (val);
7547 /* Arithmetic shift right the double-word by 16 bits. */
7549 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7552 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7556 /* This will only be true if high is a sign-extension of low, i.e.,
7557 it must be either 0 or (unsigned)-1, and be zero iff the
7558 most-significant bit of low is set. */
7559 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7560 operands[2] = GEN_INT (low);
7562 operands[2] = immed_double_const (low, high, DImode);
7565 (define_insn "shori_media"
7566 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7567 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7569 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7570 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7574 [(set_attr "type" "arith_media,*")])
7576 (define_insn "*shori_media_si"
7577 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7578 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7580 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7584 (define_expand "movdi"
7585 [(set (match_operand:DI 0 "general_movdst_operand" "")
7586 (match_operand:DI 1 "general_movsrc_operand" ""))]
7589 prepare_move_operands (operands, DImode);
7592 (define_insn "movdf_media"
7593 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7594 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7596 && (register_operand (operands[0], DFmode)
7597 || sh_register_operand (operands[1], DFmode))"
7608 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,
7609 fload_media,fstore_media,load_media,store_media")])
7611 (define_insn "movdf_media_nofpu"
7612 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7613 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7615 && (register_operand (operands[0], DFmode)
7616 || sh_register_operand (operands[1], DFmode))"
7622 [(set_attr "type" "arith_media,*,load_media,store_media")])
7625 [(set (match_operand:DF 0 "arith_reg_dest" "")
7626 (match_operand:DF 1 "immediate_operand" ""))]
7627 "TARGET_SHMEDIA && reload_completed"
7628 [(set (match_dup 3) (match_dup 2))]
7630 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7632 REAL_VALUE_TYPE value;
7634 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7635 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7637 if (HOST_BITS_PER_WIDE_INT >= 64)
7638 operands[2] = immed_double_const ((unsigned long) values[endian]
7639 | ((HOST_WIDE_INT) values[1 - endian]
7643 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7644 operands[2] = immed_double_const (values[endian], values[1 - endian],
7648 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7651 ;; FIXME: This should be a define_insn_and_split.
7652 (define_insn "movdf_k"
7653 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7654 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7656 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7657 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7658 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7659 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7660 && (arith_reg_operand (operands[0], DFmode)
7661 || arith_reg_operand (operands[1], DFmode))"
7663 return output_movedouble (insn, operands, DFmode);
7665 [(set_attr "length" "4")
7666 (set_attr "type" "move,pcload,load,store")])
7668 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7669 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7670 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7671 ;; the d/m/c/X alternative, which is split later into single-precision
7672 ;; instructions. And when not optimizing, no splits are done before fixing
7673 ;; up pcloads, so we need usable length information for that.
7674 (define_insn "movdf_i4"
7675 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7676 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
7677 (use (reg:SI FPSCR_MODES_REG))
7678 (clobber (match_scratch:SI 2 "=X,X,&z,X,X,X,X,X,X,X"))]
7679 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7680 && (arith_reg_operand (operands[0], DFmode)
7681 || arith_reg_operand (operands[1], DFmode))"
7683 switch (which_alternative)
7687 return "fmov %1,%0";
7688 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7689 return "fmov %R1,%R0" "\n"
7692 return "fmov %S1,%S0" "\n"
7696 return "fmov.d %1,%0";
7701 [(set_attr_alternative "length"
7702 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7704 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7705 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7706 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7708 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7709 ;; We can't use 4-byte push/pop on SHcompact, so we have to
7710 ;; increment or decrement r15 explicitly.
7712 (match_test "TARGET_SHCOMPACT")
7713 (const_int 10) (const_int 8))
7715 (match_test "TARGET_SHCOMPACT")
7716 (const_int 10) (const_int 8))])
7717 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7718 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7719 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7720 (const_string "double")
7721 (const_string "none")))])
7723 ;; Moving DFmode between fp/general registers through memory
7724 ;; (the top of the stack) is faster than moving through fpul even for
7725 ;; little endian. Because the type of an instruction is important for its
7726 ;; scheduling, it is beneficial to split these operations, rather than
7727 ;; emitting them in one single chunk, even if this will expose a stack
7728 ;; use that will prevent scheduling of other stack accesses beyond this
7731 [(set (match_operand:DF 0 "register_operand")
7732 (match_operand:DF 1 "register_operand"))
7733 (use (reg:SI FPSCR_MODES_REG))
7734 (clobber (match_scratch:SI 2))]
7735 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7736 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7741 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7743 emit_move_insn (stack_pointer_rtx,
7744 plus_constant (Pmode, stack_pointer_rtx, -8));
7745 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7748 tos = gen_tmp_stack_mem (DFmode,
7749 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7750 insn = emit_insn (gen_movdf_i4 (tos, operands[1]));
7751 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7752 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7753 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7754 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7756 tos = gen_tmp_stack_mem (DFmode,
7757 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7758 insn = emit_insn (gen_movdf_i4 (operands[0], tos));
7759 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7760 emit_move_insn (stack_pointer_rtx,
7761 plus_constant (Pmode, stack_pointer_rtx, 8));
7763 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7767 ;; local-alloc sometimes allocates scratch registers even when not required,
7768 ;; so we must be prepared to handle these.
7770 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7772 [(set (match_operand:DF 0 "general_movdst_operand" "")
7773 (match_operand:DF 1 "general_movsrc_operand" ""))
7774 (use (reg:SI FPSCR_MODES_REG))
7775 (clobber (match_scratch:SI 2))]
7776 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7778 && true_regnum (operands[0]) < 16
7779 && true_regnum (operands[1]) < 16"
7780 [(set (match_dup 0) (match_dup 1))]
7782 /* If this was a reg <-> mem operation with base + index reg addressing,
7783 we have to handle this in a special way. */
7784 rtx mem = operands[0];
7786 if (! memory_operand (mem, DFmode))
7791 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7792 mem = SUBREG_REG (mem);
7795 rtx addr = XEXP (mem, 0);
7796 if (GET_CODE (addr) == PLUS
7797 && REG_P (XEXP (addr, 0))
7798 && REG_P (XEXP (addr, 1)))
7801 rtx reg0 = gen_rtx_REG (Pmode, 0);
7802 rtx regop = operands[store_p], word0 ,word1;
7804 if (GET_CODE (regop) == SUBREG)
7805 alter_subreg (®op, true);
7806 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7810 mem = copy_rtx (mem);
7811 PUT_MODE (mem, SImode);
7812 word0 = gen_rtx_SUBREG (SImode, regop, 0);
7813 alter_subreg (&word0, true);
7814 word1 = gen_rtx_SUBREG (SImode, regop, 4);
7815 alter_subreg (&word1, true);
7816 if (store_p || ! refers_to_regno_p (REGNO (word0),
7817 REGNO (word0) + 1, addr, 0))
7820 ? gen_movsi_ie (mem, word0)
7821 : gen_movsi_ie (word0, mem));
7822 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7823 mem = copy_rtx (mem);
7825 ? gen_movsi_ie (mem, word1)
7826 : gen_movsi_ie (word1, mem));
7827 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7831 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7832 emit_insn (gen_movsi_ie (word1, mem));
7833 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7834 mem = copy_rtx (mem);
7835 emit_insn (gen_movsi_ie (word0, mem));
7842 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7844 [(set (match_operand:DF 0 "register_operand" "")
7845 (match_operand:DF 1 "memory_operand" ""))
7846 (use (reg:SI FPSCR_MODES_REG))
7847 (clobber (reg:SI R0_REG))]
7848 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7849 [(parallel [(set (match_dup 0) (match_dup 1))
7850 (use (reg:SI FPSCR_MODES_REG))
7851 (clobber (scratch:SI))])]
7854 (define_expand "reload_indf__frn"
7855 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7856 (match_operand:DF 1 "immediate_operand" "FQ"))
7857 (use (reg:SI FPSCR_MODES_REG))
7858 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7862 (define_expand "reload_outdf__RnFRm"
7863 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7864 (match_operand:DF 1 "register_operand" "af,r"))
7865 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7869 ;; Simplify no-op moves.
7871 [(set (match_operand:SF 0 "register_operand" "")
7872 (match_operand:SF 1 "register_operand" ""))
7873 (use (reg:SI FPSCR_MODES_REG))
7874 (clobber (match_scratch:SI 2))]
7875 "TARGET_SH2E && reload_completed
7876 && true_regnum (operands[0]) == true_regnum (operands[1])"
7877 [(set (match_dup 0) (match_dup 0))]
7880 ;; fmovd substitute post-reload splits
7882 [(set (match_operand:DF 0 "register_operand" "")
7883 (match_operand:DF 1 "register_operand" ""))
7884 (use (reg:SI FPSCR_MODES_REG))
7885 (clobber (match_scratch:SI 2))]
7886 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7887 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7888 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7891 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7892 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7893 gen_rtx_REG (SFmode, src)));
7894 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7895 gen_rtx_REG (SFmode, src + 1)));
7900 [(set (match_operand:DF 0 "register_operand" "")
7901 (mem:DF (match_operand:SI 1 "register_operand" "")))
7902 (use (reg:SI FPSCR_MODES_REG))
7903 (clobber (match_scratch:SI 2))]
7904 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7905 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7906 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7909 int regno = true_regnum (operands[0]);
7911 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7913 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7914 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7915 regno + SH_REG_MSW_OFFSET),
7917 add_reg_note (insn, REG_INC, operands[1]);
7918 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7919 regno + SH_REG_LSW_OFFSET),
7920 change_address (mem, SFmode, NULL_RTX)));
7925 [(set (match_operand:DF 0 "register_operand" "")
7926 (match_operand:DF 1 "memory_operand" ""))
7927 (use (reg:SI FPSCR_MODES_REG))
7928 (clobber (match_scratch:SI 2))]
7929 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7930 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7933 int regno = true_regnum (operands[0]);
7935 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7936 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
7937 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
7939 operands[1] = copy_rtx (mem2);
7940 addr = XEXP (mem2, 0);
7942 switch (GET_CODE (addr))
7945 /* This is complicated. If the register is an arithmetic register
7946 we can just fall through to the REG+DISP case below. Otherwise
7947 we have to use a combination of POST_INC and REG addressing... */
7948 if (! arith_reg_operand (operands[1], SFmode))
7950 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7951 insn = emit_insn (gen_movsf_ie (reg0, mem2));
7952 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7954 emit_insn (gen_movsf_ie (reg1, operands[1]));
7956 /* If we have modified the stack pointer, the value that we have
7957 read with post-increment might be modified by an interrupt,
7958 so write it back. */
7959 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7960 emit_insn (gen_push_e (reg0));
7962 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0),
7969 emit_insn (gen_movsf_ie (reg0, operands[1]));
7970 operands[1] = copy_rtx (operands[1]);
7971 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7972 emit_insn (gen_movsf_ie (reg1, operands[1]));
7976 insn = emit_insn (gen_movsf_ie (reg0, operands[1]));
7977 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7979 insn = emit_insn (gen_movsf_ie (reg1, operands[1]));
7980 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7992 [(set (match_operand:DF 0 "memory_operand" "")
7993 (match_operand:DF 1 "register_operand" ""))
7994 (use (reg:SI FPSCR_MODES_REG))
7995 (clobber (match_scratch:SI 2))]
7996 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7997 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
8000 int regno = true_regnum (operands[1]);
8002 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
8003 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
8005 operands[0] = copy_rtx (operands[0]);
8006 PUT_MODE (operands[0], SFmode);
8007 addr = XEXP (operands[0], 0);
8009 switch (GET_CODE (addr))
8012 /* This is complicated. If the register is an arithmetic register
8013 we can just fall through to the REG+DISP case below. Otherwise
8014 we have to use a combination of REG and PRE_DEC addressing... */
8015 if (! arith_reg_operand (operands[0], SFmode))
8017 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
8018 emit_insn (gen_movsf_ie (operands[0], reg1));
8020 operands[0] = copy_rtx (operands[0]);
8021 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
8023 insn = emit_insn (gen_movsf_ie (operands[0], reg0));
8024 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8030 /* Since REG+DISP addressing has already been decided upon by gcc
8031 we can rely upon it having chosen an arithmetic register as the
8032 register component of the address. Just emit the lower numbered
8033 register first, to the lower address, then the higher numbered
8034 register to the higher address. */
8035 emit_insn (gen_movsf_ie (operands[0], reg0));
8037 operands[0] = copy_rtx (operands[0]);
8038 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
8040 emit_insn (gen_movsf_ie (operands[0], reg1));
8044 /* This is easy. Output the word to go to the higher address
8045 first (ie the word in the higher numbered register) then the
8046 word to go to the lower address. */
8048 insn = emit_insn (gen_movsf_ie (operands[0], reg1));
8049 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8051 insn = emit_insn (gen_movsf_ie (operands[0], reg0));
8052 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8064 ;; If the output is a register and the input is memory or a register, we have
8065 ;; to be careful and see which word needs to be loaded first.
8067 [(set (match_operand:DF 0 "general_movdst_operand" "")
8068 (match_operand:DF 1 "general_movsrc_operand" ""))]
8069 "TARGET_SH1 && reload_completed"
8070 [(set (match_dup 2) (match_dup 3))
8071 (set (match_dup 4) (match_dup 5))]
8075 if ((MEM_P (operands[0])
8076 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
8077 || (MEM_P (operands[1])
8078 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
8081 switch (GET_CODE (operands[0]))
8084 regno = REGNO (operands[0]);
8087 regno = subreg_regno (operands[0]);
8097 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8099 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
8100 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
8101 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
8102 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
8106 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
8107 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
8108 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
8109 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
8112 if (operands[2] == 0 || operands[3] == 0
8113 || operands[4] == 0 || operands[5] == 0)
8117 (define_expand "movdf"
8118 [(set (match_operand:DF 0 "general_movdst_operand" "")
8119 (match_operand:DF 1 "general_movsrc_operand" ""))]
8122 prepare_move_operands (operands, DFmode);
8125 if (TARGET_SHMEDIA_FPU)
8126 emit_insn (gen_movdf_media (operands[0], operands[1]));
8128 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
8131 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8133 emit_insn (gen_movdf_i4 (operands[0], operands[1]));
8138 ;;This is incompatible with the way gcc uses subregs.
8139 ;;(define_insn "movv2sf_i"
8140 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
8141 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
8142 ;; "TARGET_SHMEDIA_FPU
8143 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
8144 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
8148 ;; fst%M0.p %m0, %1"
8149 ;; [(set_attr "type" "*,fload_media,fstore_media")])
8150 (define_insn_and_split "movv2sf_i"
8151 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8152 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8153 "TARGET_SHMEDIA_FPU"
8155 "TARGET_SHMEDIA_FPU && reload_completed"
8156 [(set (match_dup 0) (match_dup 1))]
8158 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
8159 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
8162 (define_expand "movv2sf"
8163 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
8164 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
8165 "TARGET_SHMEDIA_FPU"
8167 prepare_move_operands (operands, V2SFmode);
8170 (define_expand "addv2sf3"
8171 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8172 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8173 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8174 "TARGET_SHMEDIA_FPU"
8176 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
8180 (define_expand "subv2sf3"
8181 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8182 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8183 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8184 "TARGET_SHMEDIA_FPU"
8186 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
8190 (define_expand "mulv2sf3"
8191 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8192 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8193 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8194 "TARGET_SHMEDIA_FPU"
8196 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
8200 (define_expand "divv2sf3"
8201 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8202 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8203 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8204 "TARGET_SHMEDIA_FPU"
8206 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
8210 (define_insn_and_split "*movv4sf_i"
8211 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8212 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8213 "TARGET_SHMEDIA_FPU"
8215 "&& reload_completed"
8218 for (int i = 0; i < 4/2; i++)
8222 if (MEM_P (operands[0]))
8223 x = adjust_address (operands[0], V2SFmode,
8224 i * GET_MODE_SIZE (V2SFmode));
8226 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
8228 if (MEM_P (operands[1]))
8229 y = adjust_address (operands[1], V2SFmode,
8230 i * GET_MODE_SIZE (V2SFmode));
8232 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8234 emit_insn (gen_movv2sf_i (x, y));
8239 [(set_attr "length" "8")])
8241 (define_expand "movv4sf"
8242 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8243 (match_operand:V4SF 1 "general_operand" ""))]
8244 "TARGET_SHMEDIA_FPU"
8246 prepare_move_operands (operands, V4SFmode);
8249 (define_insn_and_split "*movv16sf_i"
8250 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8251 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8252 "TARGET_SHMEDIA_FPU"
8254 "&& reload_completed"
8257 for (int i = 0; i < 16/2; i++)
8261 if (MEM_P (operands[0]))
8262 x = adjust_address (operands[0], V2SFmode,
8263 i * GET_MODE_SIZE (V2SFmode));
8266 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8267 alter_subreg (&x, true);
8270 if (MEM_P (operands[1]))
8271 y = adjust_address (operands[1], V2SFmode,
8272 i * GET_MODE_SIZE (V2SFmode));
8275 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8276 alter_subreg (&y, true);
8279 emit_insn (gen_movv2sf_i (x, y));
8284 [(set_attr "length" "32")])
8286 (define_expand "movv16sf"
8287 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8288 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8289 "TARGET_SHMEDIA_FPU"
8291 prepare_move_operands (operands, V16SFmode);
8294 (define_insn "movsf_media"
8295 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8296 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8298 && (register_operand (operands[0], SFmode)
8299 || sh_register_operand (operands[1], SFmode))"
8310 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8311 (set (attr "highpart")
8312 (cond [(match_test "sh_contains_memref_p (insn)")
8313 (const_string "user")]
8314 (const_string "ignore")))])
8316 (define_insn "movsf_media_nofpu"
8317 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8318 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8320 && (register_operand (operands[0], SFmode)
8321 || sh_register_operand (operands[1], SFmode))"
8327 [(set_attr "type" "arith_media,*,load_media,store_media")
8328 (set (attr "highpart")
8329 (cond [(match_test "sh_contains_memref_p (insn)")
8330 (const_string "user")]
8331 (const_string "ignore")))])
8334 [(set (match_operand:SF 0 "arith_reg_dest" "")
8335 (match_operand:SF 1 "immediate_operand" ""))]
8336 "TARGET_SHMEDIA && reload_completed
8337 && ! FP_REGISTER_P (true_regnum (operands[0]))"
8338 [(set (match_dup 3) (match_dup 2))]
8341 REAL_VALUE_TYPE value;
8343 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
8344 REAL_VALUE_TO_TARGET_SINGLE (value, values);
8345 operands[2] = GEN_INT (values);
8347 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8350 (define_insn "movsf_i"
8351 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8352 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
8355 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8356 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8357 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8358 && (arith_reg_operand (operands[0], SFmode)
8359 || arith_reg_operand (operands[1], SFmode))"
8368 [(set_attr "type" "move,move,pcload,load,store,move,move")])
8370 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8371 ;; update_flow_info would not know where to put REG_EQUAL notes
8372 ;; when the destination changes mode.
8373 (define_insn "movsf_ie"
8374 [(set (match_operand:SF 0 "general_movdst_operand"
8375 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8376 (match_operand:SF 1 "general_movsrc_operand"
8377 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8378 (use (reg:SI FPSCR_MODES_REG))
8379 (clobber (match_scratch:SI 2 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8381 && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode)
8382 || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode)
8383 || arith_reg_operand (operands[2], SImode))"
8403 ! move optimized away"
8404 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8405 store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8406 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8407 (set_attr_alternative "length"
8414 (match_test "TARGET_SH2A")
8415 (const_int 4) (const_int 2))
8417 (match_test "TARGET_SH2A")
8418 (const_int 4) (const_int 2))
8421 (match_test "TARGET_SH2A")
8422 (const_int 4) (const_int 2))
8424 (match_test "TARGET_SH2A")
8425 (const_int 4) (const_int 2))
8435 (set_attr_alternative "fp_mode"
8436 [(if_then_else (eq_attr "fmovd" "yes")
8437 (const_string "single") (const_string "none"))
8438 (const_string "none")
8439 (const_string "single")
8440 (const_string "single")
8441 (const_string "none")
8442 (if_then_else (eq_attr "fmovd" "yes")
8443 (const_string "single") (const_string "none"))
8444 (if_then_else (eq_attr "fmovd" "yes")
8445 (const_string "single") (const_string "none"))
8446 (const_string "none")
8447 (const_string "none")
8448 (const_string "none")
8449 (const_string "none")
8450 (const_string "none")
8451 (const_string "none")
8452 (const_string "none")
8453 (const_string "none")
8454 (const_string "none")
8455 (const_string "none")
8456 (const_string "none")
8457 (const_string "none")])])
8460 [(set (match_operand:SF 0 "register_operand" "")
8461 (match_operand:SF 1 "register_operand" ""))
8462 (use (reg:SI FPSCR_MODES_REG))
8463 (clobber (reg:SI FPUL_REG))]
8465 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8466 (use (reg:SI FPSCR_MODES_REG))
8467 (clobber (scratch:SI))])
8468 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8469 (use (reg:SI FPSCR_MODES_REG))
8470 (clobber (scratch:SI))])]
8473 (define_expand "movsf"
8474 [(set (match_operand:SF 0 "general_movdst_operand" "")
8475 (match_operand:SF 1 "general_movsrc_operand" ""))]
8478 prepare_move_operands (operands, SFmode);
8481 if (TARGET_SHMEDIA_FPU)
8482 emit_insn (gen_movsf_media (operands[0], operands[1]));
8484 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8489 emit_insn (gen_movsf_ie (operands[0], operands[1]));
8494 (define_insn "mov_nop"
8495 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8498 [(set_attr "length" "0")
8499 (set_attr "type" "nil")])
8501 (define_expand "reload_insf__frn"
8502 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8503 (match_operand:SF 1 "immediate_operand" "FQ"))
8504 (use (reg:SI FPSCR_MODES_REG))
8505 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8509 (define_expand "reload_insi__i_fpul"
8510 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8511 (match_operand:SI 1 "immediate_operand" "i"))
8512 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8516 (define_expand "ptabs"
8517 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8520 if (!TARGET_PT_FIXED)
8522 rtx eq = operands[1];
8524 /* ??? For canonical RTL we really should remove any CONST from EQ
8525 before wrapping it in the AND, and finally wrap the EQ into a
8526 const if is constant. However, for reload we must expose the
8527 input register or symbolic constant, and we can't have
8528 different insn structures outside of the operands for different
8529 alternatives of the same pattern. */
8530 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8533 = (gen_rtx_IF_THEN_ELSE
8536 gen_rtx_MEM (PDImode, operands[1]),
8537 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8538 PDImode, operands[1])));
8542 ;; expanded by ptabs expander.
8543 (define_insn "*extendsipdi_media"
8544 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8545 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8549 (mem:PDI (match_dup 1))
8550 (sign_extend:PDI (match_dup 1))))]
8551 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8555 [(set_attr "type" "ptabs_media,pt_media")
8556 (set_attr "length" "4,*")])
8558 (define_insn "*truncdipdi_media"
8559 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8560 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8564 (mem:PDI (match_dup 1))
8565 (truncate:PDI (match_dup 1))))]
8566 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8570 [(set_attr "type" "ptabs_media,pt_media")
8571 (set_attr "length" "4,*")])
8573 (define_insn "*movsi_y"
8574 [(set (match_operand:SI 0 "register_operand" "=y,y")
8575 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8576 (clobber (match_scratch:SI 2 "=&z,r"))]
8578 && (reload_in_progress || reload_completed)"
8580 [(set_attr "length" "4")
8581 (set_attr "type" "pcload,move")])
8584 [(set (match_operand:SI 0 "register_operand" "")
8585 (match_operand:SI 1 "immediate_operand" ""))
8586 (clobber (match_operand:SI 2 "register_operand" ""))]
8588 [(set (match_dup 2) (match_dup 1))
8589 (set (match_dup 0) (match_dup 2))]
8592 ;; ------------------------------------------------------------------------
8593 ;; Define the real conditional branch instructions.
8594 ;; ------------------------------------------------------------------------
8596 (define_expand "branch_true"
8597 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8598 (label_ref (match_operand 0))
8602 (define_expand "branch_false"
8603 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8604 (label_ref (match_operand 0))
8608 (define_insn_and_split "*cbranch_t"
8609 [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8610 (label_ref (match_operand 0))
8614 return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8619 /* Try to canonicalize the branch condition if it is not one of:
8620 (ne (reg:SI T_REG) (const_int 0))
8621 (eq (reg:SI T_REG) (const_int 0))
8623 Instead of splitting out a new insn, we modify the current insn's
8624 operands as needed. This preserves things such as REG_DEAD notes. */
8626 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
8627 && REG_P (XEXP (operands[1], 0)) && REGNO (XEXP (operands[1], 0)) == T_REG
8628 && XEXP (operands[1], 1) == const0_rtx)
8631 int branch_cond = sh_eval_treg_value (operands[1]);
8632 rtx new_cond_rtx = NULL_RTX;
8634 if (branch_cond == 0)
8635 new_cond_rtx = gen_rtx_EQ (VOIDmode, get_t_reg_rtx (), const0_rtx);
8636 else if (branch_cond == 1)
8637 new_cond_rtx = gen_rtx_NE (VOIDmode, get_t_reg_rtx (), const0_rtx);
8639 if (new_cond_rtx != NULL_RTX)
8640 validate_change (curr_insn, &XEXP (XEXP (PATTERN (curr_insn), 1), 0),
8641 new_cond_rtx, false);
8644 [(set_attr "type" "cbranch")])
8646 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8647 ;; which destination is too far away.
8648 ;; The const_int_operand is distinct for each branch target; it avoids
8649 ;; unwanted matches with redundant_insn.
8650 (define_insn "block_branch_redirect"
8651 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8654 [(set_attr "length" "0")])
8656 ;; This one has the additional purpose to record a possible scratch register
8657 ;; for the following branch.
8658 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8659 ;; because the insn then might be deemed dead and deleted. And we can't
8660 ;; make the use in the jump insn explicit because that would disable
8661 ;; delay slot scheduling from the target.
8662 (define_insn "indirect_jump_scratch"
8663 [(set (match_operand:SI 0 "register_operand" "=r")
8664 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8665 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8668 [(set_attr "length" "0")])
8670 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8671 ;; being pulled into the delay slot of a condbranch that has been made to
8672 ;; jump around the unconditional jump because it was out of range.
8673 (define_insn "stuff_delay_slot"
8675 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8676 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8679 [(set_attr "length" "0")
8680 (set_attr "cond_delay_slot" "yes")])
8682 ;; Conditional branch insns
8684 (define_expand "cbranchint4_media"
8686 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8687 [(match_operand 1 "" "")
8688 (match_operand 2 "" "")])
8689 (match_operand 3 "" "")
8693 machine_mode mode = GET_MODE (operands[1]);
8694 if (mode == VOIDmode)
8695 mode = GET_MODE (operands[2]);
8696 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8698 operands[1] = force_reg (mode, operands[1]);
8699 if (CONSTANT_P (operands[2])
8700 && (! satisfies_constraint_I06 (operands[2])))
8701 operands[2] = force_reg (mode, operands[2]);
8705 if (operands[1] != const0_rtx)
8706 operands[1] = force_reg (mode, operands[1]);
8707 if (operands[2] != const0_rtx)
8708 operands[2] = force_reg (mode, operands[2]);
8710 switch (GET_CODE (operands[0]))
8716 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8717 VOIDmode, operands[2], operands[1]);
8718 operands[1] = XEXP (operands[0], 0);
8719 operands[2] = XEXP (operands[0], 1);
8722 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8723 VOIDmode, operands[1], operands[2]);
8726 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8729 (define_expand "cbranchfp4_media"
8731 (if_then_else (match_operator 0 "sh_float_comparison_operator"
8732 [(match_operand 1 "" "")
8733 (match_operand 2 "" "")])
8734 (match_operand 3 "" "")
8738 rtx tmp = gen_reg_rtx (SImode);
8740 if (GET_CODE (operands[0]) == NE)
8741 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8743 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8744 operands[1], operands[2]);
8746 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8748 if (GET_CODE (cmp) == GET_CODE (operands[0]))
8749 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8751 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8753 operands[2] = const0_rtx;
8754 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8757 (define_insn "*beq_media_i"
8759 (if_then_else (match_operator 3 "equality_comparison_operator"
8760 [(match_operand:DI 1 "arith_reg_operand" "r,r")
8761 (match_operand:DI 2 "arith_operand" "r,I06")])
8762 (match_operand 0 "target_operand" "b,b")
8767 b%o3i%' %1, %2, %0%>"
8768 [(set_attr "type" "cbranch_media")])
8770 (define_insn "*beq_media_i32"
8772 (if_then_else (match_operator 3 "equality_comparison_operator"
8773 [(match_operand:SI 1 "arith_reg_operand" "r,r")
8774 (match_operand:SI 2 "arith_operand" "r,I06")])
8775 (match_operand 0 "target_operand" "b,b")
8780 b%o3i%' %1, %2, %0%>"
8781 [(set_attr "type" "cbranch_media")])
8783 (define_insn "*bgt_media_i"
8785 (if_then_else (match_operator 3 "greater_comparison_operator"
8786 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8787 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8788 (match_operand 0 "target_operand" "b")
8791 "b%o3%' %N1, %N2, %0%>"
8792 [(set_attr "type" "cbranch_media")])
8794 (define_insn "*bgt_media_i32"
8796 (if_then_else (match_operator 3 "greater_comparison_operator"
8797 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8798 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8799 (match_operand 0 "target_operand" "b")
8802 "b%o3%' %N1, %N2, %0%>"
8803 [(set_attr "type" "cbranch_media")])
8805 ;; These are only needed to make invert_jump() happy - otherwise, jump
8806 ;; optimization will be silently disabled.
8807 (define_insn "*blt_media_i"
8809 (if_then_else (match_operator 3 "less_comparison_operator"
8810 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8811 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8812 (match_operand 0 "target_operand" "b")
8815 "b%o3%' %N2, %N1, %0%>"
8816 [(set_attr "type" "cbranch_media")])
8818 (define_insn "*blt_media_i32"
8820 (if_then_else (match_operator 3 "less_comparison_operator"
8821 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8822 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8823 (match_operand 0 "target_operand" "b")
8826 "b%o3%' %N2, %N1, %0%>"
8827 [(set_attr "type" "cbranch_media")])
8829 ;; combiner splitter for test-and-branch on single bit in register. This
8830 ;; is endian dependent because the non-paradoxical subreg looks different
8835 (match_operator 3 "equality_comparison_operator"
8838 (subreg:DI (match_operand:SI 1 "extend_reg_operand" "") 0)
8840 (match_operand 2 "const_int_operand" "")) 0)
8842 (match_operand 0 "target_operand" "")
8844 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8845 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8846 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8847 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8849 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8850 operands[6] = (GET_CODE (operands[3]) == EQ
8851 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8852 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8855 ; operand 0 is the loop count pseudo register
8856 ; operand 1 is the label to jump to at the top of the loop
8857 (define_expand "doloop_end"
8858 [(parallel [(set (pc)
8859 (if_then_else (ne:SI (match_operand:SI 0 "" "")
8861 (label_ref (match_operand 1 "" ""))
8864 (plus:SI (match_dup 0) (const_int -1)))
8865 (clobber (reg:SI T_REG))])]
8868 if (GET_MODE (operands[0]) != SImode)
8870 emit_jump_insn (gen_doloop_end_split (operands[0], operands[1], operands[0]));
8874 (define_insn_and_split "doloop_end_split"
8876 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8878 (label_ref (match_operand 1 "" ""))
8880 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8881 (plus:SI (match_dup 2) (const_int -1)))
8882 (clobber (reg:SI T_REG))]
8886 [(parallel [(set (reg:SI T_REG)
8887 (eq:SI (match_dup 2) (const_int 1)))
8888 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8889 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8890 (label_ref (match_dup 1))
8893 [(set_attr "type" "cbranch")])
8895 ;; ------------------------------------------------------------------------
8896 ;; Jump and linkage insns
8897 ;; ------------------------------------------------------------------------
8899 (define_insn "jump_compact"
8901 (label_ref (match_operand 0 "" "")))]
8902 "TARGET_SH1 && !CROSSING_JUMP_P (insn)"
8904 /* The length is 16 if the delay slot is unfilled. */
8905 if (get_attr_length(insn) > 4)
8906 return output_far_jump(insn, operands[0]);
8910 [(set_attr "type" "jump")
8911 (set_attr "needs_delay_slot" "yes")])
8913 ;; ??? It would be much saner to explicitly use the scratch register
8914 ;; in the jump insn, and have indirect_jump_scratch only set it,
8915 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8916 ;; from the target then, as it uses simplejump_p.
8917 ;;(define_insn "jump_compact_far"
8919 ;; (label_ref (match_operand 0 "" "")))
8920 ;; (use (match_operand 1 "register_operand" "r")]
8922 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
8923 ;; [(set_attr "type" "jump")
8924 ;; (set_attr "needs_delay_slot" "yes")])
8926 (define_insn "jump_media"
8928 (match_operand 0 "target_operand" "b"))]
8931 [(set_attr "type" "jump_media")])
8933 (define_expand "jump"
8935 (label_ref (match_operand 0 "" "")))]
8939 emit_jump_insn (gen_jump_compact (operands[0]));
8940 else if (TARGET_SHMEDIA)
8942 if (reload_in_progress || reload_completed)
8944 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, operands[0])));
8949 (define_insn "force_mode_for_call"
8950 [(use (reg:SI FPSCR_MODES_REG))]
8953 [(set_attr "length" "0")
8954 (set (attr "fp_mode")
8955 (if_then_else (eq_attr "fpu_single" "yes")
8956 (const_string "single") (const_string "double")))])
8958 (define_insn "calli"
8959 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8960 (match_operand 1 "" ""))
8961 (use (reg:SI FPSCR_MODES_REG))
8962 (clobber (reg:SI PR_REG))]
8965 if (TARGET_SH2A && (dbr_sequence_length () == 0))
8970 [(set_attr "type" "call")
8971 (set (attr "fp_mode")
8972 (if_then_else (eq_attr "fpu_single" "yes")
8973 (const_string "single") (const_string "double")))
8974 (set_attr "needs_delay_slot" "yes")
8975 (set_attr "fp_set" "unknown")])
8977 ;; This is TBR relative jump instruction for SH2A architecture.
8978 ;; Its use is enabled by assigning an attribute "function_vector"
8979 ;; and the vector number to a function during its declaration.
8980 (define_insn "calli_tbr_rel"
8981 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
8982 (match_operand 1 "" ""))
8983 (use (reg:SI FPSCR_MODES_REG))
8984 (clobber (reg:SI PR_REG))]
8985 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
8987 unsigned HOST_WIDE_INT vect_num;
8988 vect_num = sh2a_get_function_vector_number (operands[0]);
8989 operands[2] = GEN_INT (vect_num * 4);
8991 return "jsr/n @@(%O2,tbr)";
8993 [(set_attr "type" "call")
8994 (set (attr "fp_mode")
8995 (if_then_else (eq_attr "fpu_single" "yes")
8996 (const_string "single") (const_string "double")))
8997 (set_attr "needs_delay_slot" "no")
8998 (set_attr "fp_set" "unknown")])
9000 ;; This is a pc-rel call, using bsrf, for use with PIC.
9001 (define_insn "calli_pcrel"
9002 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9003 (match_operand 1 "" ""))
9004 (use (reg:SI FPSCR_MODES_REG))
9005 (use (reg:SI PIC_REG))
9006 (use (match_operand 2 "" ""))
9007 (clobber (reg:SI PR_REG))]
9010 return "bsrf %0" "\n"
9013 [(set_attr "type" "call")
9014 (set (attr "fp_mode")
9015 (if_then_else (eq_attr "fpu_single" "yes")
9016 (const_string "single") (const_string "double")))
9017 (set_attr "needs_delay_slot" "yes")
9018 (set_attr "fp_set" "unknown")])
9020 (define_insn_and_split "call_pcrel"
9021 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9022 (match_operand 1 "" ""))
9023 (use (reg:SI FPSCR_MODES_REG))
9024 (use (reg:SI PIC_REG))
9025 (clobber (reg:SI PR_REG))
9026 (clobber (match_scratch:SI 2 "=r"))]
9032 rtx lab = PATTERN (gen_call_site ());
9034 if (SYMBOL_REF_LOCAL_P (operands[0]))
9035 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9037 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
9038 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
9041 [(set_attr "type" "call")
9042 (set (attr "fp_mode")
9043 (if_then_else (eq_attr "fpu_single" "yes")
9044 (const_string "single") (const_string "double")))
9045 (set_attr "needs_delay_slot" "yes")
9046 (set_attr "fp_set" "unknown")])
9048 (define_insn "call_compact"
9049 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9050 (match_operand 1 "" ""))
9051 (match_operand 2 "immediate_operand" "n")
9052 (use (reg:SI R0_REG))
9053 (use (reg:SI R1_REG))
9054 (use (reg:SI FPSCR_MODES_REG))
9055 (clobber (reg:SI PR_REG))]
9056 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9058 [(set_attr "type" "call")
9059 (set (attr "fp_mode")
9060 (if_then_else (eq_attr "fpu_single" "yes")
9061 (const_string "single") (const_string "double")))
9062 (set_attr "needs_delay_slot" "yes")])
9064 (define_insn "call_compact_rettramp"
9065 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9066 (match_operand 1 "" ""))
9067 (match_operand 2 "immediate_operand" "n")
9068 (use (reg:SI R0_REG))
9069 (use (reg:SI R1_REG))
9070 (use (reg:SI FPSCR_MODES_REG))
9071 (clobber (reg:SI R10_REG))
9072 (clobber (reg:SI PR_REG))]
9073 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9075 [(set_attr "type" "call")
9076 (set (attr "fp_mode")
9077 (if_then_else (eq_attr "fpu_single" "yes")
9078 (const_string "single") (const_string "double")))
9079 (set_attr "needs_delay_slot" "yes")])
9081 (define_insn "call_media"
9082 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
9083 (match_operand 1 "" ""))
9084 (clobber (reg:DI PR_MEDIA_REG))]
9087 [(set_attr "type" "jump_media")])
9089 (define_insn "call_valuei"
9090 [(set (match_operand 0 "" "=rf")
9091 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9092 (match_operand 2 "" "")))
9093 (use (reg:SI FPSCR_MODES_REG))
9094 (clobber (reg:SI PR_REG))]
9097 if (TARGET_SH2A && (dbr_sequence_length () == 0))
9102 [(set_attr "type" "call")
9103 (set (attr "fp_mode")
9104 (if_then_else (eq_attr "fpu_single" "yes")
9105 (const_string "single") (const_string "double")))
9106 (set_attr "needs_delay_slot" "yes")
9107 (set_attr "fp_set" "unknown")])
9109 ;; This is TBR relative jump instruction for SH2A architecture.
9110 ;; Its use is enabled by assigning an attribute "function_vector"
9111 ;; and the vector number to a function during its declaration.
9112 (define_insn "call_valuei_tbr_rel"
9113 [(set (match_operand 0 "" "=rf")
9114 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9115 (match_operand 2 "" "")))
9116 (use (reg:SI FPSCR_MODES_REG))
9117 (clobber (reg:SI PR_REG))]
9118 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
9120 unsigned HOST_WIDE_INT vect_num;
9121 vect_num = sh2a_get_function_vector_number (operands[1]);
9122 operands[3] = GEN_INT (vect_num * 4);
9124 return "jsr/n @@(%O3,tbr)";
9126 [(set_attr "type" "call")
9127 (set (attr "fp_mode")
9128 (if_then_else (eq_attr "fpu_single" "yes")
9129 (const_string "single") (const_string "double")))
9130 (set_attr "needs_delay_slot" "no")
9131 (set_attr "fp_set" "unknown")])
9133 (define_insn "call_valuei_pcrel"
9134 [(set (match_operand 0 "" "=rf")
9135 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9136 (match_operand 2 "" "")))
9137 (use (reg:SI FPSCR_MODES_REG))
9138 (use (reg:SI PIC_REG))
9139 (use (match_operand 3 "" ""))
9140 (clobber (reg:SI PR_REG))]
9143 return "bsrf %1" "\n"
9146 [(set_attr "type" "call")
9147 (set (attr "fp_mode")
9148 (if_then_else (eq_attr "fpu_single" "yes")
9149 (const_string "single") (const_string "double")))
9150 (set_attr "needs_delay_slot" "yes")
9151 (set_attr "fp_set" "unknown")])
9153 (define_insn_and_split "call_value_pcrel"
9154 [(set (match_operand 0 "" "=rf")
9155 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9156 (match_operand 2 "" "")))
9157 (use (reg:SI FPSCR_MODES_REG))
9158 (use (reg:SI PIC_REG))
9159 (clobber (reg:SI PR_REG))
9160 (clobber (match_scratch:SI 3 "=r"))]
9166 rtx lab = PATTERN (gen_call_site ());
9168 if (SYMBOL_REF_LOCAL_P (operands[1]))
9169 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9171 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
9172 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
9173 operands[2], copy_rtx (lab)));
9176 [(set_attr "type" "call")
9177 (set (attr "fp_mode")
9178 (if_then_else (eq_attr "fpu_single" "yes")
9179 (const_string "single") (const_string "double")))
9180 (set_attr "needs_delay_slot" "yes")
9181 (set_attr "fp_set" "unknown")])
9183 (define_insn "call_value_compact"
9184 [(set (match_operand 0 "" "=rf")
9185 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9186 (match_operand 2 "" "")))
9187 (match_operand 3 "immediate_operand" "n")
9188 (use (reg:SI R0_REG))
9189 (use (reg:SI R1_REG))
9190 (use (reg:SI FPSCR_MODES_REG))
9191 (clobber (reg:SI PR_REG))]
9192 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9194 [(set_attr "type" "call")
9195 (set (attr "fp_mode")
9196 (if_then_else (eq_attr "fpu_single" "yes")
9197 (const_string "single") (const_string "double")))
9198 (set_attr "needs_delay_slot" "yes")])
9200 (define_insn "call_value_compact_rettramp"
9201 [(set (match_operand 0 "" "=rf")
9202 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9203 (match_operand 2 "" "")))
9204 (match_operand 3 "immediate_operand" "n")
9205 (use (reg:SI R0_REG))
9206 (use (reg:SI R1_REG))
9207 (use (reg:SI FPSCR_MODES_REG))
9208 (clobber (reg:SI R10_REG))
9209 (clobber (reg:SI PR_REG))]
9210 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9212 [(set_attr "type" "call")
9213 (set (attr "fp_mode")
9214 (if_then_else (eq_attr "fpu_single" "yes")
9215 (const_string "single") (const_string "double")))
9216 (set_attr "needs_delay_slot" "yes")])
9218 (define_insn "call_value_media"
9219 [(set (match_operand 0 "" "=rf")
9220 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9221 (match_operand 2 "" "")))
9222 (clobber (reg:DI PR_MEDIA_REG))]
9225 [(set_attr "type" "jump_media")])
9227 (define_expand "call"
9228 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9229 (match_operand 1 "" ""))
9230 (match_operand 2 "" "")
9231 (use (reg:SI FPSCR_MODES_REG))
9232 (clobber (reg:SI PR_REG))])]
9237 operands[0] = shmedia_prepare_call_address (operands[0], 0);
9238 emit_call_insn (gen_call_media (operands[0], operands[1]));
9241 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9243 rtx cookie_rtx = operands[2];
9244 long cookie = INTVAL (cookie_rtx);
9245 rtx func = XEXP (operands[0], 0);
9250 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9252 rtx reg = gen_reg_rtx (Pmode);
9254 emit_insn (gen_symGOTPLT2reg (reg, func));
9258 func = legitimize_pic_address (func, Pmode, 0);
9261 r0 = gen_rtx_REG (SImode, R0_REG);
9262 r1 = gen_rtx_REG (SImode, R1_REG);
9264 /* Since such a call function may use all call-clobbered
9265 registers, we force a mode switch earlier, so that we don't
9266 run out of registers when adjusting fpscr for the call. */
9267 emit_insn (gen_force_mode_for_call ());
9270 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9271 operands[0] = force_reg (SImode, operands[0]);
9273 emit_move_insn (r0, func);
9274 emit_move_insn (r1, cookie_rtx);
9276 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9277 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9280 emit_call_insn (gen_call_compact (operands[0], operands[1],
9285 else if (TARGET_SHCOMPACT && flag_pic
9286 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9287 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9289 rtx reg = gen_reg_rtx (Pmode);
9291 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9292 XEXP (operands[0], 0) = reg;
9294 if (!flag_pic && TARGET_SH2A
9295 && MEM_P (operands[0])
9296 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9298 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9300 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9305 if (flag_pic && TARGET_SH2
9306 && MEM_P (operands[0])
9307 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9309 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9314 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9315 operands[1] = operands[2];
9318 emit_call_insn (gen_calli (operands[0], operands[1]));
9322 (define_insn "call_pop_compact"
9323 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9324 (match_operand 1 "" ""))
9325 (match_operand 2 "immediate_operand" "n")
9326 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9327 (match_operand 3 "immediate_operand" "n")))
9328 (use (reg:SI R0_REG))
9329 (use (reg:SI R1_REG))
9330 (use (reg:SI FPSCR_MODES_REG))
9331 (clobber (reg:SI PR_REG))]
9332 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9334 [(set_attr "type" "call")
9335 (set (attr "fp_mode")
9336 (if_then_else (eq_attr "fpu_single" "yes")
9337 (const_string "single") (const_string "double")))
9338 (set_attr "needs_delay_slot" "yes")])
9340 (define_insn "call_pop_compact_rettramp"
9341 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9342 (match_operand 1 "" ""))
9343 (match_operand 2 "immediate_operand" "n")
9344 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9345 (match_operand 3 "immediate_operand" "n")))
9346 (use (reg:SI R0_REG))
9347 (use (reg:SI R1_REG))
9348 (use (reg:SI FPSCR_MODES_REG))
9349 (clobber (reg:SI R10_REG))
9350 (clobber (reg:SI PR_REG))]
9351 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9353 [(set_attr "type" "call")
9354 (set (attr "fp_mode")
9355 (if_then_else (eq_attr "fpu_single" "yes")
9356 (const_string "single") (const_string "double")))
9357 (set_attr "needs_delay_slot" "yes")])
9359 (define_expand "call_pop"
9360 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9361 (match_operand 1 "" ""))
9362 (match_operand 2 "" "")
9363 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9364 (match_operand 3 "" "")))])]
9372 gcc_assert (operands[2] && INTVAL (operands[2]));
9373 cookie_rtx = operands[2];
9374 cookie = INTVAL (cookie_rtx);
9375 func = XEXP (operands[0], 0);
9379 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9381 rtx reg = gen_reg_rtx (Pmode);
9382 emit_insn (gen_symGOTPLT2reg (reg, func));
9386 func = legitimize_pic_address (func, Pmode, 0);
9389 r0 = gen_rtx_REG (SImode, R0_REG);
9390 r1 = gen_rtx_REG (SImode, R1_REG);
9392 /* Since such a call function may use all call-clobbered
9393 registers, we force a mode switch earlier, so that we don't
9394 run out of registers when adjusting fpscr for the call. */
9395 emit_insn (gen_force_mode_for_call ());
9397 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9399 operands[0] = force_reg (SImode, operands[0]);
9401 emit_move_insn (r0, func);
9402 emit_move_insn (r1, cookie_rtx);
9404 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9405 emit_call_insn (gen_call_pop_compact_rettramp
9406 (operands[0], operands[1], operands[2], operands[3]));
9408 emit_call_insn (gen_call_pop_compact
9409 (operands[0], operands[1], operands[2], operands[3]));
9414 (define_expand "call_value"
9415 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9416 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9417 (match_operand 2 "" "")))
9418 (match_operand 3 "" "")
9419 (use (reg:SI FPSCR_MODES_REG))
9420 (clobber (reg:SI PR_REG))])]
9425 operands[1] = shmedia_prepare_call_address (operands[1], 0);
9426 emit_call_insn (gen_call_value_media (operands[0], operands[1],
9430 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9432 rtx cookie_rtx = operands[3];
9433 long cookie = INTVAL (cookie_rtx);
9434 rtx func = XEXP (operands[1], 0);
9439 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9441 rtx reg = gen_reg_rtx (Pmode);
9443 emit_insn (gen_symGOTPLT2reg (reg, func));
9447 func = legitimize_pic_address (func, Pmode, 0);
9450 r0 = gen_rtx_REG (SImode, R0_REG);
9451 r1 = gen_rtx_REG (SImode, R1_REG);
9453 /* Since such a call function may use all call-clobbered
9454 registers, we force a mode switch earlier, so that we don't
9455 run out of registers when adjusting fpscr for the call. */
9456 emit_insn (gen_force_mode_for_call ());
9459 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9460 operands[1] = force_reg (SImode, operands[1]);
9462 emit_move_insn (r0, func);
9463 emit_move_insn (r1, cookie_rtx);
9465 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9466 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9471 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9472 operands[2], operands[3]));
9476 else if (TARGET_SHCOMPACT && flag_pic
9477 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9478 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9480 rtx reg = gen_reg_rtx (Pmode);
9482 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9483 XEXP (operands[1], 0) = reg;
9485 if (!flag_pic && TARGET_SH2A
9486 && MEM_P (operands[1])
9487 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9489 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9491 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9492 XEXP (operands[1], 0), operands[2]));
9496 if (flag_pic && TARGET_SH2
9497 && MEM_P (operands[1])
9498 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9500 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9505 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9507 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9511 (define_insn "sibcalli"
9512 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9513 (match_operand 1 "" ""))
9514 (use (reg:SI FPSCR_MODES_REG))
9518 [(set_attr "needs_delay_slot" "yes")
9519 (set (attr "fp_mode")
9520 (if_then_else (eq_attr "fpu_single" "yes")
9521 (const_string "single") (const_string "double")))
9522 (set_attr "type" "jump_ind")])
9524 (define_insn "sibcalli_pcrel"
9525 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9526 (match_operand 1 "" ""))
9527 (use (match_operand 2 "" ""))
9528 (use (reg:SI FPSCR_MODES_REG))
9532 return "braf %0" "\n"
9535 [(set_attr "needs_delay_slot" "yes")
9536 (set (attr "fp_mode")
9537 (if_then_else (eq_attr "fpu_single" "yes")
9538 (const_string "single") (const_string "double")))
9539 (set_attr "type" "jump_ind")])
9541 ;; This uses an unspec to describe that the symbol_ref is very close.
9542 (define_insn "sibcalli_thunk"
9543 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9545 (match_operand 1 "" ""))
9546 (use (reg:SI FPSCR_MODES_REG))
9550 [(set_attr "needs_delay_slot" "yes")
9551 (set (attr "fp_mode")
9552 (if_then_else (eq_attr "fpu_single" "yes")
9553 (const_string "single") (const_string "double")))
9554 (set_attr "type" "jump")
9555 (set_attr "length" "2")])
9557 (define_insn_and_split "sibcall_pcrel"
9558 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9559 (match_operand 1 "" ""))
9560 (use (reg:SI FPSCR_MODES_REG))
9561 (clobber (match_scratch:SI 2 "=k"))
9568 rtx lab = PATTERN (gen_call_site ());
9571 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9572 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9574 SIBLING_CALL_P (call_insn) = 1;
9577 [(set_attr "needs_delay_slot" "yes")
9578 (set (attr "fp_mode")
9579 (if_then_else (eq_attr "fpu_single" "yes")
9580 (const_string "single") (const_string "double")))
9581 (set_attr "type" "jump_ind")])
9583 (define_insn "sibcall_compact"
9584 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9585 (match_operand 1 "" ""))
9587 (use (match_operand:SI 2 "register_operand" "z,x"))
9588 (use (reg:SI R1_REG))
9589 (use (reg:SI FPSCR_MODES_REG))
9590 ;; We want to make sure the `x' above will only match MACH_REG
9591 ;; because sibcall_epilogue may clobber MACL_REG.
9592 (clobber (reg:SI MACL_REG))]
9595 static const char* alt[] =
9602 return alt[which_alternative];
9604 [(set_attr "needs_delay_slot" "yes,no")
9605 (set_attr "length" "2,4")
9606 (set (attr "fp_mode") (const_string "single"))
9607 (set_attr "type" "jump_ind")])
9609 (define_insn "sibcall_media"
9610 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9611 (match_operand 1 "" ""))
9612 (use (reg:SI PR_MEDIA_REG))
9616 [(set_attr "type" "jump_media")])
9618 (define_expand "sibcall"
9620 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9621 (match_operand 1 "" ""))
9622 (match_operand 2 "" "")
9623 (use (reg:SI FPSCR_MODES_REG))
9629 operands[0] = shmedia_prepare_call_address (operands[0], 1);
9630 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9633 else if (TARGET_SHCOMPACT && operands[2]
9634 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9636 rtx cookie_rtx = operands[2];
9637 long cookie = INTVAL (cookie_rtx);
9638 rtx func = XEXP (operands[0], 0);
9643 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9645 rtx reg = gen_reg_rtx (Pmode);
9647 emit_insn (gen_symGOT2reg (reg, func));
9651 func = legitimize_pic_address (func, Pmode, 0);
9654 /* FIXME: if we could tell whether all argument registers are
9655 already taken, we could decide whether to force the use of
9656 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9657 simple way to tell. We could use the CALL_COOKIE, but we
9658 can't currently tell a register used for regular argument
9659 passing from one that is unused. If we leave it up to reload
9660 to decide which register to use, it seems to always choose
9661 R0_REG, which leaves no available registers in SIBCALL_REGS
9662 to hold the address of the trampoline. */
9663 mach = gen_rtx_REG (SImode, MACH_REG);
9664 r1 = gen_rtx_REG (SImode, R1_REG);
9666 /* Since such a call function may use all call-clobbered
9667 registers, we force a mode switch earlier, so that we don't
9668 run out of registers when adjusting fpscr for the call. */
9669 emit_insn (gen_force_mode_for_call ());
9672 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9673 operands[0] = force_reg (SImode, operands[0]);
9675 /* We don't need a return trampoline, since the callee will
9676 return directly to the upper caller. */
9677 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9679 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9680 cookie_rtx = GEN_INT (cookie);
9683 emit_move_insn (mach, func);
9684 emit_move_insn (r1, cookie_rtx);
9686 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9689 else if (TARGET_SHCOMPACT && flag_pic
9690 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9691 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9693 rtx reg = gen_reg_rtx (Pmode);
9695 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9696 XEXP (operands[0], 0) = reg;
9698 if (flag_pic && TARGET_SH2
9699 && MEM_P (operands[0])
9700 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9701 /* The PLT needs the PIC register, but the epilogue would have
9702 to restore it, so we can only use PC-relative PIC calls for
9703 static functions. */
9704 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9706 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9710 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9712 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9716 (define_insn "sibcall_valuei"
9717 [(set (match_operand 0 "" "=rf")
9718 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9719 (match_operand 2 "" "")))
9720 (use (reg:SI FPSCR_MODES_REG))
9724 [(set_attr "needs_delay_slot" "yes")
9725 (set (attr "fp_mode")
9726 (if_then_else (eq_attr "fpu_single" "yes")
9727 (const_string "single") (const_string "double")))
9728 (set_attr "type" "jump_ind")])
9730 (define_insn "sibcall_valuei_pcrel"
9731 [(set (match_operand 0 "" "=rf")
9732 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9733 (match_operand 2 "" "")))
9734 (use (match_operand 3 "" ""))
9735 (use (reg:SI FPSCR_MODES_REG))
9739 return "braf %1" "\n"
9742 [(set_attr "needs_delay_slot" "yes")
9743 (set (attr "fp_mode")
9744 (if_then_else (eq_attr "fpu_single" "yes")
9745 (const_string "single") (const_string "double")))
9746 (set_attr "type" "jump_ind")])
9748 (define_insn_and_split "sibcall_value_pcrel"
9749 [(set (match_operand 0 "" "=rf")
9750 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9751 (match_operand 2 "" "")))
9752 (use (reg:SI FPSCR_MODES_REG))
9753 (clobber (match_scratch:SI 3 "=k"))
9760 rtx lab = PATTERN (gen_call_site ());
9763 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9764 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9768 SIBLING_CALL_P (call_insn) = 1;
9771 [(set_attr "needs_delay_slot" "yes")
9772 (set (attr "fp_mode")
9773 (if_then_else (eq_attr "fpu_single" "yes")
9774 (const_string "single") (const_string "double")))
9775 (set_attr "type" "jump_ind")])
9777 (define_insn "sibcall_value_compact"
9778 [(set (match_operand 0 "" "=rf,rf")
9779 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9780 (match_operand 2 "" "")))
9782 (use (match_operand:SI 3 "register_operand" "z,x"))
9783 (use (reg:SI R1_REG))
9784 (use (reg:SI FPSCR_MODES_REG))
9785 ;; We want to make sure the `x' above will only match MACH_REG
9786 ;; because sibcall_epilogue may clobber MACL_REG.
9787 (clobber (reg:SI MACL_REG))]
9790 static const char* alt[] =
9797 return alt[which_alternative];
9799 [(set_attr "needs_delay_slot" "yes,no")
9800 (set_attr "length" "2,4")
9801 (set (attr "fp_mode") (const_string "single"))
9802 (set_attr "type" "jump_ind")])
9804 (define_insn "sibcall_value_media"
9805 [(set (match_operand 0 "" "=rf")
9806 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9807 (match_operand 2 "" "")))
9808 (use (reg:SI PR_MEDIA_REG))
9812 [(set_attr "type" "jump_media")])
9814 (define_expand "sibcall_value"
9816 [(set (match_operand 0 "arith_reg_operand" "")
9817 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9818 (match_operand 2 "" "")))
9819 (match_operand 3 "" "")
9820 (use (reg:SI FPSCR_MODES_REG))
9826 operands[1] = shmedia_prepare_call_address (operands[1], 1);
9827 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9831 else if (TARGET_SHCOMPACT && operands[3]
9832 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9834 rtx cookie_rtx = operands[3];
9835 long cookie = INTVAL (cookie_rtx);
9836 rtx func = XEXP (operands[1], 0);
9841 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9843 rtx reg = gen_reg_rtx (Pmode);
9845 emit_insn (gen_symGOT2reg (reg, func));
9849 func = legitimize_pic_address (func, Pmode, 0);
9852 /* FIXME: if we could tell whether all argument registers are
9853 already taken, we could decide whether to force the use of
9854 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9855 simple way to tell. We could use the CALL_COOKIE, but we
9856 can't currently tell a register used for regular argument
9857 passing from one that is unused. If we leave it up to reload
9858 to decide which register to use, it seems to always choose
9859 R0_REG, which leaves no available registers in SIBCALL_REGS
9860 to hold the address of the trampoline. */
9861 mach = gen_rtx_REG (SImode, MACH_REG);
9862 r1 = gen_rtx_REG (SImode, R1_REG);
9864 /* Since such a call function may use all call-clobbered
9865 registers, we force a mode switch earlier, so that we don't
9866 run out of registers when adjusting fpscr for the call. */
9867 emit_insn (gen_force_mode_for_call ());
9870 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9871 operands[1] = force_reg (SImode, operands[1]);
9873 /* We don't need a return trampoline, since the callee will
9874 return directly to the upper caller. */
9875 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9877 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9878 cookie_rtx = GEN_INT (cookie);
9881 emit_move_insn (mach, func);
9882 emit_move_insn (r1, cookie_rtx);
9884 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9885 operands[2], mach));
9888 else if (TARGET_SHCOMPACT && flag_pic
9889 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9890 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9892 rtx reg = gen_reg_rtx (Pmode);
9894 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9895 XEXP (operands[1], 0) = reg;
9897 if (flag_pic && TARGET_SH2
9898 && MEM_P (operands[1])
9899 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9900 /* The PLT needs the PIC register, but the epilogue would have
9901 to restore it, so we can only use PC-relative PIC calls for
9902 static functions. */
9903 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9905 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9906 XEXP (operands[1], 0),
9911 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9913 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9917 (define_insn "call_value_pop_compact"
9918 [(set (match_operand 0 "" "=rf")
9919 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9920 (match_operand 2 "" "")))
9921 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9922 (match_operand 4 "immediate_operand" "n")))
9923 (match_operand 3 "immediate_operand" "n")
9924 (use (reg:SI R0_REG))
9925 (use (reg:SI R1_REG))
9926 (use (reg:SI FPSCR_MODES_REG))
9927 (clobber (reg:SI PR_REG))]
9928 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9930 [(set_attr "type" "call")
9931 (set (attr "fp_mode")
9932 (if_then_else (eq_attr "fpu_single" "yes")
9933 (const_string "single") (const_string "double")))
9934 (set_attr "needs_delay_slot" "yes")])
9936 (define_insn "call_value_pop_compact_rettramp"
9937 [(set (match_operand 0 "" "=rf")
9938 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9939 (match_operand 2 "" "")))
9940 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9941 (match_operand 4 "immediate_operand" "n")))
9942 (match_operand 3 "immediate_operand" "n")
9943 (use (reg:SI R0_REG))
9944 (use (reg:SI R1_REG))
9945 (use (reg:SI FPSCR_MODES_REG))
9946 (clobber (reg:SI R10_REG))
9947 (clobber (reg:SI PR_REG))]
9948 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9950 [(set_attr "type" "call")
9951 (set (attr "fp_mode")
9952 (if_then_else (eq_attr "fpu_single" "yes")
9953 (const_string "single") (const_string "double")))
9954 (set_attr "needs_delay_slot" "yes")])
9956 (define_expand "call_value_pop"
9957 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9958 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9959 (match_operand 2 "" "")))
9960 (match_operand 3 "" "")
9961 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9962 (match_operand 4 "" "")))])]
9970 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
9971 cookie_rtx = operands[3];
9972 cookie = INTVAL (cookie_rtx);
9973 func = XEXP (operands[1], 0);
9977 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9979 rtx reg = gen_reg_rtx (Pmode);
9981 emit_insn (gen_symGOTPLT2reg (reg, func));
9985 func = legitimize_pic_address (func, Pmode, 0);
9988 r0 = gen_rtx_REG (SImode, R0_REG);
9989 r1 = gen_rtx_REG (SImode, R1_REG);
9991 /* Since such a call function may use all call-clobbered
9992 registers, we force a mode switch earlier, so that we don't
9993 run out of registers when adjusting fpscr for the call. */
9994 emit_insn (gen_force_mode_for_call ());
9996 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9998 operands[1] = force_reg (SImode, operands[1]);
10000 emit_move_insn (r0, func);
10001 emit_move_insn (r1, cookie_rtx);
10003 if (cookie & CALL_COOKIE_RET_TRAMP (1))
10004 emit_call_insn (gen_call_value_pop_compact_rettramp
10005 (operands[0], operands[1], operands[2],
10006 operands[3], operands[4]));
10008 emit_call_insn (gen_call_value_pop_compact
10009 (operands[0], operands[1], operands[2],
10010 operands[3], operands[4]));
10015 (define_expand "sibcall_epilogue"
10019 sh_expand_epilogue (true);
10020 if (TARGET_SHCOMPACT)
10025 /* If epilogue clobbers r0, preserve it in macl. */
10026 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10027 if ((set = single_set (insn))
10028 && REG_P (SET_DEST (set))
10029 && REGNO (SET_DEST (set)) == R0_REG)
10031 rtx r0 = gen_rtx_REG (SImode, R0_REG);
10032 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
10034 /* We can't tell at this point whether the sibcall is a
10035 sibcall_compact and, if it is, whether it uses r0 or
10036 mach as operand 2, so let the instructions that
10037 preserve r0 be optimized away if r0 turns out to be
10039 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
10040 emit_move_insn (r0, tmp);
10047 (define_insn "indirect_jump_compact"
10049 (match_operand:SI 0 "arith_reg_operand" "r"))]
10052 [(set_attr "needs_delay_slot" "yes")
10053 (set_attr "type" "jump_ind")])
10055 (define_expand "indirect_jump"
10057 (match_operand 0 "register_operand" ""))]
10060 if (GET_MODE (operands[0]) != Pmode)
10061 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
10064 ;; The use of operand 1 / 2 helps us distinguish case table jumps
10065 ;; which can be present in structured code from indirect jumps which can not
10066 ;; be present in structured code. This allows -fprofile-arcs to work.
10068 ;; For SH1 processors.
10069 (define_insn "casesi_jump_1"
10071 (match_operand:SI 0 "register_operand" "r"))
10072 (use (label_ref (match_operand 1 "" "")))]
10075 [(set_attr "needs_delay_slot" "yes")
10076 (set_attr "type" "jump_ind")])
10078 ;; For all later processors.
10079 (define_insn "casesi_jump_2"
10080 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
10081 (label_ref (match_operand 1 "" ""))))
10082 (use (label_ref (match_operand 2 "" "")))]
10084 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
10086 [(set_attr "needs_delay_slot" "yes")
10087 (set_attr "type" "jump_ind")])
10089 (define_insn "casesi_jump_media"
10090 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
10091 (use (label_ref (match_operand 1 "" "")))]
10094 [(set_attr "type" "jump_media")])
10096 ;; Call subroutine returning any type.
10097 ;; ??? This probably doesn't work.
10098 (define_expand "untyped_call"
10099 [(parallel [(call (match_operand 0 "" "")
10101 (match_operand 1 "" "")
10102 (match_operand 2 "" "")])]
10103 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
10105 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10107 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10109 rtx set = XVECEXP (operands[2], 0, i);
10110 emit_move_insn (SET_DEST (set), SET_SRC (set));
10113 /* The optimizer does not know that the call sets the function value
10114 registers we stored in the result block. We avoid problems by
10115 claiming that all hard registers are used and clobbered at this
10117 emit_insn (gen_blockage ());
10122 ;; ------------------------------------------------------------------------
10124 ;; ------------------------------------------------------------------------
10126 (define_insn "dect"
10127 [(set (reg:SI T_REG)
10128 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
10129 (set (match_operand:SI 0 "arith_reg_dest" "=r")
10130 (plus:SI (match_dup 1) (const_int -1)))]
10133 [(set_attr "type" "arith")])
10140 ;; Load address of a label. This is only generated by the casesi expand,
10141 ;; and by machine_dependent_reorg (fixing up fp moves).
10142 ;; This must use unspec, because this only works for labels that are
10144 (define_insn "mova"
10145 [(set (reg:SI R0_REG)
10146 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
10149 [(set_attr "in_delay_slot" "no")
10150 (set_attr "type" "arith")])
10152 ;; machine_dependent_reorg will make this a `mova'.
10153 (define_insn "mova_const"
10154 [(set (reg:SI R0_REG)
10155 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
10158 [(set_attr "in_delay_slot" "no")
10159 (set_attr "type" "arith")])
10161 (define_expand "GOTaddr2picreg"
10162 [(set (reg:SI R0_REG)
10163 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
10165 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
10166 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10169 if (TARGET_VXWORKS_RTP)
10171 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
10172 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
10173 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
10177 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
10178 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10180 if (TARGET_SHMEDIA)
10182 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10183 rtx pic = operands[0];
10184 rtx lab = PATTERN (gen_call_site ());
10187 equiv = operands[1];
10188 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
10189 UNSPEC_PCREL_SYMOFF);
10190 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
10192 if (Pmode == SImode)
10194 emit_insn (gen_movsi_const (pic, operands[1]));
10195 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10199 emit_insn (gen_movdi_const (pic, operands[1]));
10200 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10203 insn = emit_move_insn (operands[0], tr);
10205 set_unique_reg_note (insn, REG_EQUAL, equiv);
10211 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10213 (define_expand "vxworks_picreg"
10214 [(set (reg:SI PIC_REG)
10215 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10216 (set (reg:SI R0_REG)
10217 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10218 (set (reg:SI PIC_REG)
10219 (mem:SI (reg:SI PIC_REG)))
10220 (set (reg:SI PIC_REG)
10221 (mem:SI (plus:SI (reg:SI PIC_REG)
10222 (reg:SI R0_REG))))]
10223 "TARGET_VXWORKS_RTP")
10225 (define_insn "*ptb"
10226 [(set (match_operand 0 "target_reg_operand" "=b")
10227 (const (unspec [(match_operand 1 "" "Csy")]
10228 UNSPEC_DATALABEL)))]
10229 "TARGET_SHMEDIA && flag_pic
10230 && satisfies_constraint_Csy (operands[1])"
10231 "ptb/u datalabel %1, %0"
10232 [(set_attr "type" "ptabs_media")
10233 (set_attr "length" "*")])
10235 (define_insn "ptrel_si"
10236 [(set (match_operand:SI 0 "target_reg_operand" "=b")
10237 (plus:SI (match_operand:SI 1 "register_operand" "r")
10239 (match_operand:SI 2 "" "")]
10241 "%O2: ptrel/u %1, %0"
10242 [(set_attr "type" "ptabs_media")])
10244 (define_insn "ptrel_di"
10245 [(set (match_operand:DI 0 "target_reg_operand" "=b")
10246 (plus:DI (match_operand:DI 1 "register_operand" "r")
10248 (match_operand:DI 2 "" "")]
10250 "%O2: ptrel/u %1, %0"
10251 [(set_attr "type" "ptabs_media")])
10253 (define_expand "builtin_setjmp_receiver"
10254 [(match_operand 0 "" "")]
10257 emit_insn (gen_GOTaddr2picreg ());
10261 (define_expand "call_site"
10262 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10265 static HOST_WIDE_INT i = 0;
10266 operands[0] = GEN_INT (i);
10270 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
10271 ;; in symGOT_load expand.
10272 (define_insn_and_split "chk_guard_add"
10273 [(set (match_operand:SI 0 "register_operand" "=&r")
10274 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10279 "TARGET_SH1 && reload_completed"
10280 [(set (match_dup 0) (reg:SI PIC_REG))
10281 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10283 [(set_attr "type" "arith")])
10285 (define_expand "sym_label2reg"
10286 [(set (match_operand:SI 0 "" "")
10287 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10288 (const (plus:SI (match_operand:SI 2 "" "")
10293 (define_expand "symGOT_load"
10294 [(set (match_dup 2) (match_operand 1 "" ""))
10295 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10296 (set (match_operand 0 "" "") (mem (match_dup 3)))]
10301 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10302 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10304 if (TARGET_SHMEDIA)
10306 rtx reg = operands[2];
10308 if (Pmode == DImode)
10311 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10313 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10318 emit_insn (gen_movsi_const (reg, operands[1]));
10320 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10324 emit_move_insn (operands[2], operands[1]);
10326 /* When stack protector inserts codes after the result is set to
10327 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
10328 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10329 when rX is a GOT address for the guard symbol. Ugly but doesn't
10330 matter because this is a rare situation. */
10331 if (!TARGET_SHMEDIA
10332 && flag_stack_protect
10333 && GET_CODE (operands[1]) == CONST
10334 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10335 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10336 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10337 "__stack_chk_guard") == 0)
10338 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10340 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10341 gen_rtx_REG (Pmode, PIC_REG)));
10343 /* N.B. This is not constant for a GOTPLT relocation. */
10344 mem = gen_rtx_MEM (Pmode, operands[3]);
10345 MEM_NOTRAP_P (mem) = 1;
10346 /* ??? Should we have a special alias set for the GOT? */
10347 emit_move_insn (operands[0], mem);
10352 (define_expand "sym2GOT"
10353 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10357 (define_expand "symGOT2reg"
10358 [(match_operand 0 "" "") (match_operand 1 "" "")]
10363 gotsym = gen_sym2GOT (operands[1]);
10364 PUT_MODE (gotsym, Pmode);
10365 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10367 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10372 (define_expand "symGOTPLT2reg"
10373 [(match_operand 0 "" "") (match_operand 1 "" "")]
10376 rtx pltsym = gen_rtx_CONST (Pmode,
10377 gen_rtx_UNSPEC (Pmode,
10378 gen_rtvec (1, operands[1]),
10380 emit_insn (gen_symGOT_load (operands[0], pltsym));
10384 (define_expand "sym2GOTOFF"
10385 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10389 (define_expand "symGOTOFF2reg"
10390 [(match_operand 0 "" "") (match_operand 1 "" "")]
10393 rtx gotoffsym, insn;
10394 rtx t = (!can_create_pseudo_p ()
10396 : gen_reg_rtx (GET_MODE (operands[0])));
10398 gotoffsym = gen_sym2GOTOFF (operands[1]);
10399 PUT_MODE (gotoffsym, Pmode);
10400 emit_move_insn (t, gotoffsym);
10401 insn = emit_move_insn (operands[0],
10402 gen_rtx_PLUS (Pmode, t,
10403 gen_rtx_REG (Pmode, PIC_REG)));
10405 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10410 (define_expand "symPLT_label2reg"
10411 [(set (match_operand:SI 0 "" "")
10414 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10415 (const:SI (plus:SI (match_operand:SI 2 "" "")
10416 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10417 ;; Even though the PIC register is not really used by the call
10418 ;; sequence in which this is expanded, the PLT code assumes the PIC
10419 ;; register is set, so we must not skip its initialization. Since
10420 ;; we only use this expand as part of calling sequences, and never
10421 ;; to take the address of a function, this is the best point to
10422 ;; insert the (use). Using the PLT to take the address of a
10423 ;; function would be wrong, not only because the PLT entry could
10424 ;; then be called from a function that doesn't initialize the PIC
10425 ;; register to the proper GOT, but also because pointers to the
10426 ;; same function might not compare equal, should they be set by
10427 ;; different shared libraries.
10428 (use (reg:SI PIC_REG))]
10432 (define_expand "sym2PIC"
10433 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10437 ;; -------------------------------------------------------------------------
10438 ;; TLS code generation.
10440 ;; FIXME: The multi-insn asm blocks should be converted to use
10441 ;; define_insn_and_split.
10442 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10443 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10446 (define_insn "tls_global_dynamic"
10447 [(set (match_operand:SI 0 "register_operand" "=&z")
10448 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10451 (use (reg:SI FPSCR_MODES_REG))
10452 (use (reg:SI PIC_REG))
10453 (clobber (reg:SI PR_REG))
10454 (clobber (scratch:SI))]
10457 return "mov.l 1f,r4" "\n"
10459 " mov.l 2f,r1" "\n"
10466 "1: .long %a1@TLSGD" "\n"
10467 "2: .long __tls_get_addr@PLT" "\n"
10470 [(set_attr "type" "tls_load")
10471 (set_attr "length" "26")])
10473 (define_insn "tls_local_dynamic"
10474 [(set (match_operand:SI 0 "register_operand" "=&z")
10475 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10478 (use (reg:SI FPSCR_MODES_REG))
10479 (use (reg:SI PIC_REG))
10480 (clobber (reg:SI PR_REG))
10481 (clobber (scratch:SI))]
10484 return "mov.l 1f,r4" "\n"
10486 " mov.l 2f,r1" "\n"
10493 "1: .long %a1@TLSLDM" "\n"
10494 "2: .long __tls_get_addr@PLT" "\n"
10497 [(set_attr "type" "tls_load")
10498 (set_attr "length" "26")])
10500 (define_expand "sym2DTPOFF"
10501 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10505 (define_expand "symDTPOFF2reg"
10506 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10510 rtx t = (!can_create_pseudo_p ()
10512 : gen_reg_rtx (GET_MODE (operands[0])));
10514 dtpoffsym = gen_sym2DTPOFF (operands[1]);
10515 PUT_MODE (dtpoffsym, Pmode);
10516 emit_move_insn (t, dtpoffsym);
10517 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10521 (define_expand "sym2GOTTPOFF"
10522 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10526 (define_insn "tls_initial_exec"
10527 [(set (match_operand:SI 0 "register_operand" "=&r")
10528 (unspec:SI [(match_operand:SI 1 "" "")]
10530 (use (reg:SI GBR_REG))
10531 (use (reg:SI PIC_REG))
10532 (clobber (reg:SI R0_REG))]
10535 return "mov.l 1f,r0" "\n"
10537 " mov.l @(r0,r12),r0" "\n"
10541 "1: .long %a1" "\n"
10544 [(set_attr "type" "tls_load")
10545 (set_attr "length" "16")])
10547 (define_expand "sym2TPOFF"
10548 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10552 (define_expand "symTPOFF2reg"
10553 [(match_operand 0 "" "") (match_operand 1 "" "")]
10558 tpoffsym = gen_sym2TPOFF (operands[1]);
10559 PUT_MODE (tpoffsym, Pmode);
10560 emit_move_insn (operands[0], tpoffsym);
10564 ;;------------------------------------------------------------------------------
10565 ;; Thread pointer getter and setter.
10567 ;; On SH the thread pointer is kept in the GBR.
10568 ;; These patterns are usually expanded from the respective built-in functions.
10569 (define_expand "get_thread_pointersi"
10570 [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10573 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10574 (define_insn "store_gbr"
10575 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10578 [(set_attr "type" "tls_load")])
10580 (define_expand "set_thread_pointersi"
10581 [(set (reg:SI GBR_REG)
10582 (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10586 (define_insn "load_gbr"
10587 [(set (reg:SI GBR_REG)
10588 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10592 [(set_attr "type" "move")])
10594 ;;------------------------------------------------------------------------------
10595 ;; Thread pointer relative memory loads and stores.
10597 ;; On SH there are GBR displacement address modes which can be utilized to
10598 ;; access memory behind the thread pointer.
10599 ;; Since we do not allow using GBR for general purpose memory accesses, these
10600 ;; GBR addressing modes are formed by the combine pass.
10601 ;; This could be done with fewer patterns than below by using a mem predicate
10602 ;; for the GBR mem, but then reload would try to reload addresses with a
10603 ;; zero displacement for some strange reason.
10605 (define_insn "*mov<mode>_gbr_load"
10606 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10607 (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10608 (match_operand:QIHISI 1 "gbr_displacement"))))]
10610 "mov.<bwl> @(%O1,gbr),%0"
10611 [(set_attr "type" "load")])
10613 (define_insn "*mov<mode>_gbr_load"
10614 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10615 (mem:QIHISI (reg:SI GBR_REG)))]
10617 "mov.<bwl> @(0,gbr),%0"
10618 [(set_attr "type" "load")])
10620 (define_insn "*mov<mode>_gbr_load"
10621 [(set (match_operand:SI 0 "register_operand" "=z")
10623 (mem:QIHI (plus:SI (reg:SI GBR_REG)
10624 (match_operand:QIHI 1 "gbr_displacement")))))]
10626 "mov.<bw> @(%O1,gbr),%0"
10627 [(set_attr "type" "load")])
10629 (define_insn "*mov<mode>_gbr_load"
10630 [(set (match_operand:SI 0 "register_operand" "=z")
10631 (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10633 "mov.<bw> @(0,gbr),%0"
10634 [(set_attr "type" "load")])
10636 (define_insn "*mov<mode>_gbr_store"
10637 [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10638 (match_operand:QIHISI 0 "gbr_displacement")))
10639 (match_operand:QIHISI 1 "register_operand" "z"))]
10641 "mov.<bwl> %1,@(%O0,gbr)"
10642 [(set_attr "type" "store")])
10644 (define_insn "*mov<mode>_gbr_store"
10645 [(set (mem:QIHISI (reg:SI GBR_REG))
10646 (match_operand:QIHISI 0 "register_operand" "z"))]
10648 "mov.<bwl> %0,@(0,gbr)"
10649 [(set_attr "type" "store")])
10651 ;; DImode memory accesses have to be split in two SImode accesses.
10652 ;; Split them before reload, so that it gets a better chance to figure out
10653 ;; how to deal with the R0 restriction for the individual SImode accesses.
10654 ;; Do not match this insn during or after reload because it can't be split
10656 (define_insn_and_split "*movdi_gbr_load"
10657 [(set (match_operand:DI 0 "register_operand")
10658 (match_operand:DI 1 "gbr_address_mem"))]
10659 "TARGET_SH1 && can_create_pseudo_p ()"
10662 [(set (match_dup 3) (match_dup 5))
10663 (set (match_dup 4) (match_dup 6))]
10665 /* Swap low/high part load order on little endian, so that the result reg
10666 of the second load can be used better. */
10667 int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10668 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10669 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10670 operands[4 - off] = gen_highpart (SImode, operands[0]);
10671 operands[6 - off] = gen_highpart (SImode, operands[1]);
10674 (define_insn_and_split "*movdi_gbr_store"
10675 [(set (match_operand:DI 0 "gbr_address_mem")
10676 (match_operand:DI 1 "register_operand"))]
10677 "TARGET_SH1 && can_create_pseudo_p ()"
10680 [(set (match_dup 3) (match_dup 5))
10681 (set (match_dup 4) (match_dup 6))]
10683 /* Swap low/high part store order on big endian, so that stores of function
10684 call results can save a reg copy. */
10685 int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10686 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10687 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10688 operands[4 - off] = gen_highpart (SImode, operands[0]);
10689 operands[6 - off] = gen_highpart (SImode, operands[1]);
10692 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10693 ;; in particular when the displacements are in the range of the regular move
10694 ;; insns. Thus, in the first split pass after the combine pass we search
10695 ;; for missed opportunities and try to fix them up ourselves.
10696 ;; If an equivalent GBR address can be determined the load / store is split
10697 ;; into one of the GBR load / store patterns.
10698 ;; All of that must happen before reload (GBR address modes use R0 as the
10699 ;; other operand) and there's no point of doing it if the GBR is not
10700 ;; referenced in a function at all.
10702 [(set (match_operand:QIHISIDI 0 "register_operand")
10703 (match_operand:QIHISIDI 1 "memory_operand"))]
10704 "TARGET_SH1 && !reload_in_progress && !reload_completed
10705 && df_regs_ever_live_p (GBR_REG)"
10706 [(set (match_dup 0) (match_dup 1))]
10708 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10709 if (gbr_mem != NULL_RTX)
10710 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10716 [(set (match_operand:SI 0 "register_operand")
10717 (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10718 "TARGET_SH1 && !reload_in_progress && !reload_completed
10719 && df_regs_ever_live_p (GBR_REG)"
10720 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10722 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10723 if (gbr_mem != NULL_RTX)
10724 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10729 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10730 ;; Split those so that a GBR load can be used.
10732 [(set (match_operand:SI 0 "register_operand")
10733 (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10734 "TARGET_SH2A && !reload_in_progress && !reload_completed
10735 && df_regs_ever_live_p (GBR_REG)"
10736 [(set (match_dup 2) (match_dup 1))
10737 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10739 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10740 if (gbr_mem != NULL_RTX)
10742 operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10743 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10750 [(set (match_operand:QIHISIDI 0 "memory_operand")
10751 (match_operand:QIHISIDI 1 "register_operand"))]
10752 "TARGET_SH1 && !reload_in_progress && !reload_completed
10753 && df_regs_ever_live_p (GBR_REG)"
10754 [(set (match_dup 0) (match_dup 1))]
10756 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10757 if (gbr_mem != NULL_RTX)
10758 operands[0] = replace_equiv_address (operands[0], gbr_mem);
10763 ;;------------------------------------------------------------------------------
10764 ;; case instruction for switch statements.
10766 ;; operand 0 is index
10767 ;; operand 1 is the minimum bound
10768 ;; operand 2 is the maximum bound - minimum bound + 1
10769 ;; operand 3 is CODE_LABEL for the table;
10770 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10771 (define_expand "casesi"
10772 [(match_operand:SI 0 "arith_reg_operand" "")
10773 (match_operand:SI 1 "arith_reg_operand" "")
10774 (match_operand:SI 2 "arith_reg_operand" "")
10775 (match_operand 3 "" "") (match_operand 4 "" "")]
10778 rtx reg = gen_reg_rtx (SImode);
10779 rtx reg2 = gen_reg_rtx (SImode);
10780 if (TARGET_SHMEDIA)
10782 rtx reg = gen_reg_rtx (DImode);
10783 rtx reg2 = gen_reg_rtx (DImode);
10784 rtx reg3 = gen_reg_rtx (Pmode);
10785 rtx reg4 = gen_reg_rtx (Pmode);
10786 rtx reg5 = gen_reg_rtx (Pmode);
10789 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10790 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10791 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10793 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10794 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0],
10796 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10797 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10798 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10799 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10800 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10801 (Pmode, operands[3])));
10802 /* Messy: can we subreg to clean this up? */
10803 if (Pmode == DImode)
10804 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10806 load = gen_casesi_load_media (reg4,
10807 gen_rtx_SUBREG (DImode, reg3, 0),
10808 reg2, operands[3]);
10809 PUT_MODE (SET_SRC (load), Pmode);
10811 /* ??? The following add could be eliminated if we used ptrel. */
10812 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10813 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10817 operands[1] = copy_to_mode_reg (SImode, operands[1]);
10818 operands[2] = copy_to_mode_reg (SImode, operands[2]);
10819 /* If optimizing, casesi_worker depends on the mode of the instruction
10820 before label it 'uses' - operands[3]. */
10821 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10823 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10825 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10827 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10828 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10829 operands[3], but to lab. We will fix this up in
10830 machine_dependent_reorg. */
10835 (define_expand "casesi_0"
10836 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10837 (set (match_dup 4) (minus:SI (match_dup 4)
10838 (match_operand:SI 1 "arith_operand" "")))
10839 (set (reg:SI T_REG)
10840 (gtu:SI (match_dup 4)
10841 (match_operand:SI 2 "arith_reg_operand" "")))
10843 (if_then_else (ne (reg:SI T_REG)
10845 (label_ref (match_operand 3 "" ""))
10850 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10851 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10852 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10853 (define_insn "casesi_worker_0"
10854 [(set (match_operand:SI 0 "register_operand" "=r,r")
10855 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10856 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10857 (clobber (match_scratch:SI 3 "=X,1"))
10858 (clobber (match_scratch:SI 4 "=&z,z"))]
10863 [(set (match_operand:SI 0 "register_operand" "")
10864 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10865 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10866 (clobber (match_scratch:SI 3 ""))
10867 (clobber (match_scratch:SI 4 ""))]
10868 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10869 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10870 (parallel [(set (match_dup 0)
10871 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10872 (label_ref (match_dup 2))] UNSPEC_CASESI))
10873 (clobber (match_dup 3))])
10874 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10876 if (GET_CODE (operands[2]) == CODE_LABEL)
10877 LABEL_NUSES (operands[2])++;
10881 [(set (match_operand:SI 0 "register_operand" "")
10882 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10883 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10884 (clobber (match_scratch:SI 3 ""))
10885 (clobber (match_scratch:SI 4 ""))]
10886 "TARGET_SH2 && reload_completed"
10887 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10888 (parallel [(set (match_dup 0)
10889 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10890 (label_ref (match_dup 2))] UNSPEC_CASESI))
10891 (clobber (match_dup 3))])]
10893 if (GET_CODE (operands[2]) == CODE_LABEL)
10894 LABEL_NUSES (operands[2])++;
10897 (define_insn "casesi_worker_1"
10898 [(set (match_operand:SI 0 "register_operand" "=r,r")
10899 (unspec:SI [(reg:SI R0_REG)
10900 (match_operand:SI 1 "register_operand" "0,r")
10901 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10902 (clobber (match_scratch:SI 3 "=X,1"))]
10905 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
10907 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10909 switch (GET_MODE (diff_vec))
10912 return "shll2 %1" "\n"
10913 " mov.l @(r0,%1),%0";
10915 return "add %1,%1" "\n"
10916 " mov.w @(r0,%1),%0";
10918 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10919 return "mov.b @(r0,%1),%0" "\n"
10922 return "mov.b @(r0,%1),%0";
10925 gcc_unreachable ();
10928 [(set_attr "length" "4")])
10930 (define_insn "casesi_worker_2"
10931 [(set (match_operand:SI 0 "register_operand" "=r,r")
10932 (unspec:SI [(reg:SI R0_REG)
10933 (match_operand:SI 1 "register_operand" "0,r")
10934 (label_ref (match_operand 2 "" ""))
10935 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
10936 (clobber (match_operand:SI 4 "" "=X,1"))]
10937 "TARGET_SH2 && reload_completed && flag_pic"
10939 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
10940 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10942 switch (GET_MODE (diff_vec))
10945 return "shll2 %1" "\n"
10947 " mova %O3,r0" "\n"
10948 " mov.l @(r0,%1),%0";
10950 return "add %1,%1" "\n"
10952 " mova %O3,r0" "\n"
10953 " mov.w @(r0,%1),%0";
10955 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10956 return "add r0,%1" "\n"
10957 " mova %O3,r0" "\n"
10958 " mov.b @(r0,%1),%0" "\n"
10961 return "add r0,%1" "\n"
10962 " mova %O3,r0" "\n"
10963 " mov.b @(r0,%1),%0";
10965 gcc_unreachable ();
10968 [(set_attr "length" "8")])
10970 (define_insn "casesi_shift_media"
10971 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10972 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
10973 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
10977 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
10979 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10981 switch (GET_MODE (diff_vec))
10984 return "shlli %1, 2, %0";
10986 return "shlli %1, 1, %0";
10988 if (rtx_equal_p (operands[0], operands[1]))
10990 return "add %1, r63, %0";
10992 gcc_unreachable ();
10995 [(set_attr "type" "arith_media")])
10997 (define_insn "casesi_load_media"
10998 [(set (match_operand 0 "any_arith_reg_dest" "=r")
10999 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
11000 (match_operand:DI 2 "arith_reg_operand" "r")
11001 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
11004 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[3])));
11006 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11008 switch (GET_MODE (diff_vec))
11011 return "ldx.l %1, %2, %0";
11014 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11015 return "ldx.uw %1, %2, %0";
11017 return "ldx.w %1, %2, %0";
11019 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11020 return "ldx.ub %1, %2, %0";
11021 return "ldx.b %1, %2, %0";
11023 gcc_unreachable ();
11026 [(set_attr "type" "load_media")])
11028 (define_expand "simple_return"
11030 "sh_can_use_simple_return_p ()")
11032 (define_expand "return"
11034 "reload_completed && epilogue_completed"
11036 if (TARGET_SHMEDIA)
11038 emit_jump_insn (gen_return_media ());
11042 if (TARGET_SHCOMPACT
11043 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
11045 emit_jump_insn (gen_shcompact_return_tramp ());
11050 (define_insn "*<code>_i"
11052 "TARGET_SH1 && ! (TARGET_SHCOMPACT
11053 && (crtl->args.info.call_cookie
11054 & CALL_COOKIE_RET_TRAMP (1)))
11055 && reload_completed
11056 && ! sh_cfun_trap_exit_p ()"
11058 if (TARGET_SH2A && (dbr_sequence_length () == 0)
11059 && !current_function_interrupt)
11064 [(set_attr "type" "return")
11065 (set_attr "needs_delay_slot" "yes")])
11067 ;; trapa has no delay slot.
11068 (define_insn "*return_trapa"
11070 "TARGET_SH1 && !TARGET_SHCOMPACT
11071 && reload_completed"
11073 [(set_attr "type" "return")])
11075 (define_expand "shcompact_return_tramp"
11078 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
11080 rtx reg = gen_rtx_REG (Pmode, R0_REG);
11082 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
11083 emit_jump_insn (gen_shcompact_return_tramp_i ());
11087 (define_insn "shcompact_return_tramp_i"
11088 [(parallel [(return) (use (reg:SI R0_REG))])]
11090 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
11092 [(set_attr "type" "jump_ind")
11093 (set_attr "needs_delay_slot" "yes")])
11095 (define_insn "return_media_i"
11096 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
11097 "TARGET_SHMEDIA && reload_completed"
11099 [(set_attr "type" "jump_media")])
11101 (define_insn "return_media_rte"
11103 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
11105 [(set_attr "type" "jump_media")])
11107 (define_expand "return_media"
11109 "TARGET_SHMEDIA && reload_completed"
11111 int tr_regno = sh_media_register_for_return ();
11114 if (current_function_interrupt)
11116 emit_jump_insn (gen_return_media_rte ());
11121 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
11123 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
11124 tr_regno = TR0_REG;
11125 tr = gen_rtx_REG (Pmode, tr_regno);
11126 emit_move_insn (tr, r18);
11129 tr = gen_rtx_REG (Pmode, tr_regno);
11131 emit_jump_insn (gen_return_media_i (tr));
11135 (define_insn "shcompact_preserve_incoming_args"
11136 [(set (match_operand:SI 0 "register_operand" "+r")
11137 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
11140 [(set_attr "length" "0")])
11142 (define_insn "shcompact_incoming_args"
11143 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
11144 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
11145 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
11146 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
11147 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
11148 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
11149 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
11150 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
11151 (set (mem:BLK (reg:SI MACL_REG))
11152 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
11153 (use (reg:SI R0_REG))
11154 (clobber (reg:SI R0_REG))
11155 (clobber (reg:SI MACL_REG))
11156 (clobber (reg:SI MACH_REG))
11157 (clobber (reg:SI PR_REG))]
11160 [(set_attr "needs_delay_slot" "yes")])
11162 (define_insn "shmedia_save_restore_regs_compact"
11163 [(set (reg:SI SP_REG)
11164 (plus:SI (reg:SI SP_REG)
11165 (match_operand:SI 0 "immediate_operand" "i")))
11166 (use (reg:SI R0_REG))
11167 (clobber (reg:SI PR_REG))]
11169 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
11170 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
11172 [(set_attr "needs_delay_slot" "yes")])
11174 (define_expand "prologue"
11178 sh_expand_prologue ();
11182 (define_expand "epilogue"
11186 sh_expand_epilogue (false);
11188 || (TARGET_SHCOMPACT
11189 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11191 emit_jump_insn (gen_return ());
11196 (define_expand "eh_return"
11197 [(use (match_operand 0 "register_operand" ""))]
11200 rtx ra = operands[0];
11202 if (TARGET_SHMEDIA64)
11203 emit_insn (gen_eh_set_ra_di (ra));
11205 emit_insn (gen_eh_set_ra_si (ra));
11210 ;; Clobber the return address on the stack. We can't expand this
11211 ;; until we know where it will be put in the stack frame.
11213 (define_insn "eh_set_ra_si"
11214 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11216 (clobber (match_scratch:SI 1 "=&r"))]
11217 "! TARGET_SHMEDIA64"
11220 (define_insn "eh_set_ra_di"
11221 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11223 (clobber (match_scratch:DI 1 "=&r"))]
11228 [(unspec_volatile [(match_operand 0 "register_operand" "")]
11230 (clobber (match_scratch 1 ""))]
11234 sh_set_return_address (operands[0], operands[1]);
11238 (define_insn "blockage"
11239 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11242 [(set_attr "length" "0")])
11244 ;; Define movml instructions for SH2A target. Currently they are
11245 ;; used to push and pop all banked registers only.
11247 (define_insn "movml_push_banked"
11248 [(set (match_operand:SI 0 "register_operand" "=r")
11249 (plus (match_dup 0) (const_int -32)))
11250 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11251 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11252 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11253 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11254 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11255 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11256 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11257 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11258 "TARGET_SH2A && REGNO (operands[0]) == 15"
11260 [(set_attr "in_delay_slot" "no")])
11262 (define_insn "movml_pop_banked"
11263 [(set (match_operand:SI 0 "register_operand" "=r")
11264 (plus (match_dup 0) (const_int 32)))
11265 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11266 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11267 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11268 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11269 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11270 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11271 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11272 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11273 "TARGET_SH2A && REGNO (operands[0]) == 15"
11275 [(set_attr "in_delay_slot" "no")])
11277 ;; ------------------------------------------------------------------------
11278 ;; Scc instructions
11279 ;; ------------------------------------------------------------------------
11281 (define_insn "movt"
11282 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11283 (match_operand:SI 1 "t_reg_operand"))]
11286 [(set_attr "type" "arith")])
11288 (define_insn "movrt"
11289 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11290 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11293 [(set_attr "type" "arith")])
11295 (define_expand "cstore4_media"
11296 [(set (match_operand:SI 0 "register_operand" "=r")
11297 (match_operator:SI 1 "sh_float_comparison_operator"
11298 [(match_operand 2 "logical_operand" "")
11299 (match_operand 3 "cmp_operand" "")]))]
11302 machine_mode mode = GET_MODE (operands[2]);
11303 enum rtx_code code = GET_CODE (operands[1]);
11305 if (mode == VOIDmode)
11306 mode = GET_MODE (operands[3]);
11307 if (operands[2] == const0_rtx)
11309 if (code == EQ || code == NE)
11310 operands[2] = operands[3], operands[3] = const0_rtx;
11313 operands[2] = force_reg (mode, operands[2]);
11314 if (operands[3] != const0_rtx)
11315 operands[3] = force_reg (mode, operands[3]);
11321 swap = invert = !FLOAT_MODE_P (mode);
11326 swap = FLOAT_MODE_P (mode), invert = !swap;
11331 swap = true, invert = false;
11338 swap = invert = false;
11342 swap = invert = true;
11346 gcc_unreachable ();
11351 rtx tem = operands[2];
11352 operands[2] = operands[3];
11354 code = swap_condition (code);
11359 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11360 code = reverse_condition (code);
11361 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11362 emit_insn (gen_cstore4_media (tem, operands[1],
11363 operands[2], operands[3]));
11366 operands[3] = const0_rtx;
11369 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11372 (define_expand "cstoresi4"
11373 [(set (match_operand:SI 0 "register_operand" "=r")
11374 (match_operator:SI 1 "comparison_operator"
11375 [(match_operand:SI 2 "cmpsi_operand" "")
11376 (match_operand:SI 3 "arith_operand" "")]))]
11377 "TARGET_SH1 || TARGET_SHMEDIA"
11379 if (TARGET_SHMEDIA)
11381 emit_insn (gen_cstore4_media (operands[0], operands[1],
11382 operands[2], operands[3]));
11386 if (sh_expand_t_scc (operands))
11389 if (! currently_expanding_to_rtl)
11392 sh_emit_compare_and_set (operands, SImode);
11396 (define_expand "cstoredi4"
11397 [(set (match_operand:SI 0 "register_operand" "=r")
11398 (match_operator:SI 1 "comparison_operator"
11399 [(match_operand:DI 2 "arith_operand" "")
11400 (match_operand:DI 3 "arith_operand" "")]))]
11401 "TARGET_SH2 || TARGET_SHMEDIA"
11403 if (TARGET_SHMEDIA)
11405 emit_insn (gen_cstore4_media (operands[0], operands[1],
11406 operands[2], operands[3]));
11410 if (sh_expand_t_scc (operands))
11413 if (! currently_expanding_to_rtl)
11416 sh_emit_compare_and_set (operands, DImode);
11420 ;; Move the complement of the T reg to a reg.
11421 ;; On SH2A the movrt insn can be used.
11422 ;; On anything else than SH2A this has to be done with multiple instructions.
11423 ;; One obvious way would be:
11428 ;; However, this puts pressure on r0 in most cases and thus the following is
11434 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11435 ;; becomes a one instruction operation. Moreover, care must be taken that
11436 ;; the insn can still be combined with inverted compare and branch code
11437 ;; around it. On the other hand, if a function returns the complement of
11438 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11439 ;; lead to better code.
11440 (define_expand "movnegt"
11441 [(set (match_operand:SI 0 "arith_reg_dest" "")
11442 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11446 emit_insn (gen_movrt (operands[0], operands[1]));
11449 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11450 emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11455 (define_insn "movrt_negc"
11456 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11457 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11458 (set (reg:SI T_REG) (const_int 1))
11459 (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11462 [(set_attr "type" "arith")])
11464 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11465 ;; pattern can be used by the combine pass. Using a scratch reg for the
11466 ;; -1 constant results in slightly better register allocations compared to
11467 ;; generating a pseudo reg before reload.
11468 (define_insn_and_split "*movrt_negc"
11469 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11470 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11471 (clobber (match_scratch:SI 2 "=r"))
11472 (clobber (reg:SI T_REG))]
11473 "TARGET_SH1 && ! TARGET_SH2A"
11475 "&& reload_completed"
11476 [(set (match_dup 2) (const_int -1))
11478 [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
11479 (set (reg:SI T_REG) (const_int 1))
11480 (use (match_dup 2))])])
11482 ;; Store the negated T bit in a reg using r0 and xor. This one doesn't
11483 ;; clobber the T bit, which is useful when storing the T bit and the
11484 ;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
11485 ;; Usually we don't want this insn to be matched, except for cases where the
11486 ;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
11487 (define_insn_and_split "movrt_xor"
11488 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11489 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11490 (use (reg:SI T_REG))]
11491 "TARGET_SH1 && !TARGET_SH2A"
11493 "&& reload_completed"
11494 [(set (match_dup 0) (reg:SI T_REG))
11495 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11497 ;; Store the T bit and the negated T bit in two regs in parallel. There is
11498 ;; no real insn to do that, but specifying this pattern will give combine
11499 ;; some opportunities.
11500 (define_insn_and_split "*movt_movrt"
11501 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11502 (match_operand:SI 1 "negt_reg_operand"))
11503 (set (match_operand:SI 2 "arith_reg_dest")
11504 (match_operand:SI 3 "t_reg_operand"))])]
11510 rtx i = TARGET_SH2A
11511 ? gen_movrt (operands[0], get_t_reg_rtx ())
11512 : gen_movrt_xor (operands[0], get_t_reg_rtx ());
11515 emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
11519 (define_insn_and_split "*movt_movrt"
11520 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11521 (match_operand:SI 1 "t_reg_operand"))
11522 (set (match_operand:SI 2 "arith_reg_dest")
11523 (match_operand:SI 3 "negt_reg_operand"))])]
11527 [(parallel [(set (match_dup 2) (match_dup 3))
11528 (set (match_dup 0) (match_dup 1))])])
11530 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11531 ;; T = 1: 0x80000000 -> reg
11532 ;; T = 0: 0x7FFFFFFF -> reg
11533 ;; This works because 0 - 0x80000000 = 0x80000000.
11535 ;; This insn must not match again after it has been split into the constant
11536 ;; load and negc. This is accomplished by the special negc insn that
11537 ;; has a use on the operand.
11538 (define_insn_and_split "*mov_t_msb_neg"
11539 [(set (match_operand:SI 0 "arith_reg_dest")
11540 (minus:SI (const_int -2147483648) ;; 0x80000000
11541 (match_operand 1 "t_reg_operand")))
11542 (clobber (reg:SI T_REG))]
11545 "&& can_create_pseudo_p ()"
11546 [(set (match_dup 2) (const_int -2147483648))
11547 (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11549 (clobber (reg:SI T_REG))
11550 (use (match_dup 2))])]
11552 operands[2] = gen_reg_rtx (SImode);
11555 (define_insn "*mov_t_msb_neg_negc"
11556 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11557 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
11558 (match_operand:SI 2 "t_reg_operand")))
11559 (clobber (reg:SI T_REG))
11560 (use (match_dup 1))]
11563 [(set_attr "type" "arith")])
11565 ;; These are essentially the same as above, but with the inverted T bit.
11566 ;; Combine recognizes the split patterns, but does not take them sometimes
11567 ;; if the T_REG clobber is specified. Instead it tries to split out the
11568 ;; T bit negation. Since these splits are supposed to be taken only by
11569 ;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
11572 [(set (match_operand:SI 0 "arith_reg_dest")
11573 (plus:SI (match_operand 1 "negt_reg_operand")
11574 (const_int 2147483647)))] ;; 0x7fffffff
11575 "TARGET_SH1 && can_create_pseudo_p ()"
11576 [(parallel [(set (match_dup 0)
11577 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11578 (clobber (reg:SI T_REG))])])
11581 [(set (match_operand:SI 0 "arith_reg_dest")
11582 (if_then_else:SI (match_operand 1 "t_reg_operand")
11583 (const_int 2147483647) ;; 0x7fffffff
11584 (const_int -2147483648)))] ;; 0x80000000
11585 "TARGET_SH1 && can_create_pseudo_p ()"
11586 [(parallel [(set (match_dup 0)
11587 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11588 (clobber (reg:SI T_REG))])])
11590 ;; The *negnegt pattern helps the combine pass to figure out how to fold
11591 ;; an explicit double T bit negation.
11592 (define_insn_and_split "*negnegt"
11593 [(set (reg:SI T_REG)
11594 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11600 ;; Store T bit as all zeros or ones in a reg.
11601 (define_insn "mov_neg_si_t"
11602 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11603 (neg:SI (match_operand 1 "t_reg_operand" "")))]
11606 [(set_attr "type" "arith")])
11608 ;; Store negated T bit as all zeros or ones in a reg.
11609 ;; Use the following sequence:
11610 ;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
11611 ;; not Rn,Rn ! Rn = 0 - Rn
11613 [(set (match_operand:SI 0 "arith_reg_dest" "")
11614 (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11616 [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11617 (set (match_dup 0) (not:SI (match_dup 0)))])
11619 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11620 (define_insn_and_split "*movtt"
11621 [(set (reg:SI T_REG)
11622 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11628 ;; Invert the T bit.
11629 ;; On SH2A we can use the nott insn. On anything else this must be done with
11630 ;; multiple insns like:
11633 ;; This requires an additional pseudo. The SH specific sh_treg_combine RTL
11634 ;; pass will look for this insn. Disallow using it if pseudos can't be
11636 (define_insn_and_split "nott"
11637 [(set (reg:SI T_REG)
11638 (xor:SI (match_operand:SI 0 "t_reg_operand") (const_int 1)))]
11639 "TARGET_SH2A || (TARGET_SH1 && can_create_pseudo_p ())"
11641 gcc_assert (TARGET_SH2A);
11644 "! TARGET_SH2A && can_create_pseudo_p ()"
11645 [(set (match_dup 0) (reg:SI T_REG))
11646 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11648 operands[0] = gen_reg_rtx (SImode);
11651 ;; Store T bit as MSB in a reg.
11652 ;; T = 0: 0x00000000 -> reg
11653 ;; T = 1: 0x80000000 -> reg
11654 (define_insn_and_split "*movt_msb"
11655 [(set (match_operand:SI 0 "arith_reg_dest")
11656 (mult:SI (match_operand:SI 1 "t_reg_operand")
11657 (const_int -2147483648))) ;; 0xffffffff80000000
11658 (clobber (reg:SI T_REG))]
11662 [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11664 ;; Store inverted T bit as MSB in a reg.
11665 ;; T = 0: 0x80000000 -> reg
11666 ;; T = 1: 0x00000000 -> reg
11667 ;; On SH2A we can get away without clobbering the T_REG using the movrt insn.
11668 ;; On non SH2A we resort to the following sequence:
11672 ;; The T bit value will be modified during the sequence, but the rotcr insn
11673 ;; will restore its original value.
11674 (define_insn_and_split "*negt_msb"
11675 [(set (match_operand:SI 0 "arith_reg_dest")
11676 (match_operand:SI 1 "negt_reg_shl31_operand"))]
11679 "&& can_create_pseudo_p ()"
11682 rtx tmp = gen_reg_rtx (SImode);
11686 emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11687 emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11691 emit_move_insn (tmp, get_t_reg_rtx ());
11692 emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11693 emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11698 ;; The *cset_zero patterns convert optimizations such as
11699 ;; "if (test) x = 0;"
11701 ;; "x &= -(test == 0);"
11702 ;; back to conditional branch sequences if zero-displacement branches
11704 ;; FIXME: These patterns can be removed when conditional execution patterns
11705 ;; are implemented, since ifcvt will not perform these optimizations if
11706 ;; conditional execution is supported.
11707 (define_insn "*cset_zero"
11708 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11709 (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11711 (match_operand:SI 2 "arith_reg_operand" "0")))]
11712 "TARGET_SH1 && TARGET_ZDCBRANCH"
11714 return "bf 0f" "\n"
11718 [(set_attr "type" "arith") ;; poor approximation
11719 (set_attr "length" "4")])
11721 (define_insn "*cset_zero"
11722 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11723 (if_then_else:SI (match_operand:SI 1 "cbranch_treg_value")
11724 (match_operand:SI 2 "arith_reg_operand" "0")
11726 "TARGET_SH1 && TARGET_ZDCBRANCH"
11728 int tval = sh_eval_treg_value (operands[1]);
11730 return "bt 0f" "\n"
11733 else if (tval == false)
11734 return "bf 0f" "\n"
11738 gcc_unreachable ();
11740 [(set_attr "type" "arith") ;; poor approximation
11741 (set_attr "length" "4")])
11743 (define_expand "cstoresf4"
11744 [(set (match_operand:SI 0 "register_operand" "=r")
11745 (match_operator:SI 1 "sh_float_comparison_operator"
11746 [(match_operand:SF 2 "arith_operand" "")
11747 (match_operand:SF 3 "arith_operand" "")]))]
11748 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11750 if (TARGET_SHMEDIA)
11752 emit_insn (gen_cstore4_media (operands[0], operands[1],
11753 operands[2], operands[3]));
11757 if (! currently_expanding_to_rtl)
11760 sh_emit_compare_and_set (operands, SFmode);
11764 (define_expand "cstoredf4"
11765 [(set (match_operand:SI 0 "register_operand" "=r")
11766 (match_operator:SI 1 "sh_float_comparison_operator"
11767 [(match_operand:DF 2 "arith_operand" "")
11768 (match_operand:DF 3 "arith_operand" "")]))]
11769 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11771 if (TARGET_SHMEDIA)
11773 emit_insn (gen_cstore4_media (operands[0], operands[1],
11774 operands[2], operands[3]));
11778 if (! currently_expanding_to_rtl)
11781 sh_emit_compare_and_set (operands, DFmode);
11785 ;; -------------------------------------------------------------------------
11786 ;; Instructions to cope with inline literal tables
11787 ;; -------------------------------------------------------------------------
11789 ;; 2 byte integer in line
11790 (define_insn "consttable_2"
11791 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11792 (match_operand 1 "" "")]
11796 if (operands[1] != const0_rtx)
11797 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11800 [(set_attr "length" "2")
11801 (set_attr "in_delay_slot" "no")])
11803 ;; 4 byte integer in line
11804 (define_insn "consttable_4"
11805 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11806 (match_operand 1 "" "")]
11810 if (operands[1] != const0_rtx)
11812 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11813 mark_symbol_refs_as_used (operands[0]);
11817 [(set_attr "length" "4")
11818 (set_attr "in_delay_slot" "no")])
11820 ;; 8 byte integer in line
11821 (define_insn "consttable_8"
11822 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11823 (match_operand 1 "" "")]
11827 if (operands[1] != const0_rtx)
11828 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11831 [(set_attr "length" "8")
11832 (set_attr "in_delay_slot" "no")])
11834 ;; 4 byte floating point
11835 (define_insn "consttable_sf"
11836 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11837 (match_operand 1 "" "")]
11841 if (operands[1] != const0_rtx)
11844 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11845 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11849 [(set_attr "length" "4")
11850 (set_attr "in_delay_slot" "no")])
11852 ;; 8 byte floating point
11853 (define_insn "consttable_df"
11854 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11855 (match_operand 1 "" "")]
11859 if (operands[1] != const0_rtx)
11862 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11863 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11867 [(set_attr "length" "8")
11868 (set_attr "in_delay_slot" "no")])
11870 ;; Alignment is needed for some constant tables; it may also be added for
11871 ;; Instructions at the start of loops, or after unconditional branches.
11872 ;; ??? We would get more accurate lengths if we did instruction
11873 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11874 ;; here is too conservative.
11876 ;; align to a two byte boundary
11877 (define_expand "align_2"
11878 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11882 ;; Align to a four byte boundary.
11883 ;; align_4 and align_log are instructions for the starts of loops, or
11884 ;; after unconditional branches, which may take up extra room.
11885 (define_expand "align_4"
11886 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11890 ;; Align to a cache line boundary.
11891 (define_insn "align_log"
11892 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11895 [(set_attr "length" "0")
11896 (set_attr "in_delay_slot" "no")])
11898 ;; Emitted at the end of the literal table, used to emit the
11899 ;; 32bit branch labels if needed.
11900 (define_insn "consttable_end"
11901 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11904 return output_jump_label_table ();
11906 [(set_attr "in_delay_slot" "no")])
11908 ;; Emitted at the end of the window in the literal table.
11909 (define_insn "consttable_window_end"
11910 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11913 [(set_attr "length" "0")
11914 (set_attr "in_delay_slot" "no")])
11916 ;; -------------------------------------------------------------------------
11917 ;; Minimum / maximum operations.
11918 ;; -------------------------------------------------------------------------
11920 ;; The SH2A clips.b and clips.w insns do a signed min-max function. If smin
11921 ;; and smax standard name patterns are defined, they will be used during
11922 ;; initial expansion and combine will then be able to form the actual min-max
11924 ;; The clips.b and clips.w set the SR.CS bit if the value in the register is
11925 ;; clipped, but there is currently no way of making use of this information.
11926 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
11927 (define_expand "<code>si3"
11928 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11929 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
11930 (match_operand 2 "const_int_operand")))
11931 (clobber (reg:SI T_REG))])]
11934 /* Force the comparison value into a register, because greater-than
11935 comparisons can work only on registers. Combine will be able to pick up
11936 the constant value from the REG_EQUAL note when trying to form a min-max
11938 operands[2] = force_reg (SImode, operands[2]);
11942 ;; smax (smin (...))
11944 ;; smin (smax (...))
11945 (define_insn_and_split "*clips"
11946 [(set (match_operand:SI 0 "arith_reg_dest")
11947 (smax:SI (smin:SI (match_operand:SI 1 "arith_reg_operand")
11948 (match_operand 2 "clips_max_const_int"))
11949 (match_operand 3 "clips_min_const_int")))]
11953 [(set (match_dup 0)
11954 (smin:SI (smax:SI (match_dup 1) (match_dup 3)) (match_dup 2)))])
11956 (define_insn "*clips"
11957 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11958 (smin:SI (smax:SI (match_operand:SI 1 "arith_reg_operand" "0")
11959 (match_operand 2 "clips_min_const_int"))
11960 (match_operand 3 "clips_max_const_int")))]
11963 if (INTVAL (operands[3]) == 127)
11964 return "clips.b %0";
11965 else if (INTVAL (operands[3]) == 32767)
11966 return "clips.w %0";
11968 gcc_unreachable ();
11970 [(set_attr "type" "arith")])
11972 ;; If the expanded smin or smax patterns were not combined, split them into
11973 ;; a compare and branch sequence, because there are no real smin or smax
11975 (define_insn_and_split "*<code>si3"
11976 [(set (match_operand:SI 0 "arith_reg_dest")
11977 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
11978 (match_operand:SI 2 "arith_reg_or_0_or_1_operand")))
11979 (clobber (reg:SI T_REG))]
11980 "TARGET_SH2A && can_create_pseudo_p ()"
11985 rtx skip_label = gen_label_rtx ();
11986 emit_move_insn (operands[0], operands[1]);
11988 rtx cmp_val = operands[2];
11989 if (satisfies_constraint_M (cmp_val))
11990 cmp_val = const0_rtx;
11992 emit_insn (gen_cmpgtsi_t (operands[0], cmp_val));
11993 emit_jump_insn (<CODE> == SMIN
11994 ? gen_branch_false (skip_label)
11995 : gen_branch_true (skip_label));
11997 emit_label_after (skip_label, emit_move_insn (operands[0], operands[2]));
12001 ;; The SH2A clipu.b and clipu.w insns can be used to implement a min function
12002 ;; with a register and a constant.
12003 ;; The clipu.b and clipu.w set the SR.CS bit if the value in the register is
12004 ;; clipped, but there is currently no way of making use of this information.
12005 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
12006 (define_expand "uminsi3"
12007 [(set (match_operand:SI 0 "arith_reg_dest")
12008 (umin:SI (match_operand:SI 1 "arith_reg_operand")
12009 (match_operand 2 "const_int_operand")))]
12012 if (INTVAL (operands[2]) == 1)
12014 emit_insn (gen_clipu_one (operands[0], operands[1]));
12017 else if (! clipu_max_const_int (operands[2], VOIDmode))
12021 (define_insn "*clipu"
12022 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12023 (umin:SI (match_operand:SI 1 "arith_reg_operand" "0")
12024 (match_operand 2 "clipu_max_const_int")))]
12027 if (INTVAL (operands[2]) == 255)
12028 return "clipu.b %0";
12029 else if (INTVAL (operands[2]) == 65535)
12030 return "clipu.w %0";
12032 gcc_unreachable ();
12034 [(set_attr "type" "arith")])
12036 (define_insn_and_split "clipu_one"
12037 [(set (match_operand:SI 0 "arith_reg_dest")
12038 (umin:SI (match_operand:SI 1 "arith_reg_operand") (const_int 1)))
12039 (clobber (reg:SI T_REG))]
12042 "&& can_create_pseudo_p ()"
12045 emit_insn (gen_cmpeqsi_t (operands[1], const0_rtx));
12046 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
12050 ;; -------------------------------------------------------------------------
12052 ;; -------------------------------------------------------------------------
12054 ;; String/block move insn.
12056 (define_expand "movmemsi"
12057 [(parallel [(set (mem:BLK (match_operand:BLK 0))
12058 (mem:BLK (match_operand:BLK 1)))
12059 (use (match_operand:SI 2 "nonmemory_operand"))
12060 (use (match_operand:SI 3 "immediate_operand"))
12061 (clobber (reg:SI PR_REG))
12062 (clobber (reg:SI R4_REG))
12063 (clobber (reg:SI R5_REG))
12064 (clobber (reg:SI R0_REG))])]
12065 "TARGET_SH1 && ! TARGET_SH5"
12067 if (expand_block_move (operands))
12073 (define_insn "block_move_real"
12074 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12075 (mem:BLK (reg:SI R5_REG)))
12076 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12077 (clobber (reg:SI PR_REG))
12078 (clobber (reg:SI R0_REG))])]
12079 "TARGET_SH1 && ! TARGET_HARD_SH4"
12081 [(set_attr "type" "sfunc")
12082 (set_attr "needs_delay_slot" "yes")])
12084 (define_insn "block_lump_real"
12085 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12086 (mem:BLK (reg:SI R5_REG)))
12087 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12088 (use (reg:SI R6_REG))
12089 (clobber (reg:SI PR_REG))
12090 (clobber (reg:SI T_REG))
12091 (clobber (reg:SI R4_REG))
12092 (clobber (reg:SI R5_REG))
12093 (clobber (reg:SI R6_REG))
12094 (clobber (reg:SI R0_REG))])]
12095 "TARGET_SH1 && ! TARGET_HARD_SH4"
12097 [(set_attr "type" "sfunc")
12098 (set_attr "needs_delay_slot" "yes")])
12100 (define_insn "block_move_real_i4"
12101 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12102 (mem:BLK (reg:SI R5_REG)))
12103 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12104 (clobber (reg:SI PR_REG))
12105 (clobber (reg:SI R0_REG))
12106 (clobber (reg:SI R1_REG))
12107 (clobber (reg:SI R2_REG))])]
12110 [(set_attr "type" "sfunc")
12111 (set_attr "needs_delay_slot" "yes")])
12113 (define_insn "block_lump_real_i4"
12114 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12115 (mem:BLK (reg:SI R5_REG)))
12116 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12117 (use (reg:SI R6_REG))
12118 (clobber (reg:SI PR_REG))
12119 (clobber (reg:SI T_REG))
12120 (clobber (reg:SI R4_REG))
12121 (clobber (reg:SI R5_REG))
12122 (clobber (reg:SI R6_REG))
12123 (clobber (reg:SI R0_REG))
12124 (clobber (reg:SI R1_REG))
12125 (clobber (reg:SI R2_REG))
12126 (clobber (reg:SI R3_REG))])]
12129 [(set_attr "type" "sfunc")
12130 (set_attr "needs_delay_slot" "yes")])
12132 ;; byte compare pattern
12134 ;; !((temp & 0xF000) && (temp & 0x0F00) && (temp & 0x00F0) && (temp & 0x000F))
12135 (define_insn "cmpstr_t"
12136 [(set (reg:SI T_REG)
12141 (xor:SI (match_operand:SI 0 "arith_reg_operand" "r")
12142 (match_operand:SI 1 "arith_reg_operand" "r"))
12143 (const_int 8) (const_int 0))
12144 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12145 (const_int 8) (const_int 8)))
12146 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12147 (const_int 8) (const_int 16)))
12148 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12149 (const_int 8) (const_int 24)))
12153 [(set_attr "type" "mt_group")])
12155 (define_expand "cmpstrsi"
12156 [(set (match_operand:SI 0 "register_operand")
12157 (compare:SI (match_operand:BLK 1 "memory_operand")
12158 (match_operand:BLK 2 "memory_operand")))
12159 (use (match_operand 3 "immediate_operand"))]
12160 "TARGET_SH1 && optimize"
12162 if (! optimize_insn_for_size_p () && sh_expand_cmpstr (operands))
12168 (define_expand "cmpstrnsi"
12169 [(set (match_operand:SI 0 "register_operand")
12170 (compare:SI (match_operand:BLK 1 "memory_operand")
12171 (match_operand:BLK 2 "memory_operand")))
12172 (use (match_operand:SI 3 "immediate_operand"))
12173 (use (match_operand:SI 4 "immediate_operand"))]
12174 "TARGET_SH1 && optimize"
12176 if (! optimize_insn_for_size_p () && sh_expand_cmpnstr (operands))
12182 (define_expand "strlensi"
12183 [(set (match_operand:SI 0 "register_operand")
12184 (unspec:SI [(match_operand:BLK 1 "memory_operand")
12185 (match_operand:SI 2 "immediate_operand")
12186 (match_operand:SI 3 "immediate_operand")]
12187 UNSPEC_BUILTIN_STRLEN))]
12188 "TARGET_SH1 && optimize"
12190 if (! optimize_insn_for_size_p () && sh_expand_strlen (operands))
12196 (define_expand "setmemqi"
12197 [(parallel [(set (match_operand:BLK 0 "memory_operand")
12198 (match_operand 2 "const_int_operand"))
12199 (use (match_operand:QI 1 "const_int_operand"))
12200 (use (match_operand:QI 3 "const_int_operand"))])]
12201 "TARGET_SH1 && optimize"
12203 if (optimize_insn_for_size_p ())
12206 sh_expand_setmem (operands);
12211 ;; -------------------------------------------------------------------------
12212 ;; Floating point instructions.
12213 ;; -------------------------------------------------------------------------
12215 ;; FIXME: For now we disallow any memory operands for fpscr loads/stores,
12216 ;; except for post-inc loads and pre-dec stores for push/pop purposes.
12217 ;; This avoids problems with reload. As a consequence, user initiated fpscr
12218 ;; stores to memory will always be ferried through a general register.
12219 ;; User initiated fpscr loads always have to undergo bit masking to preserve
12220 ;; the current fpu mode settings for the compiler generated code. Thus such
12221 ;; fpscr loads will always have to go through general registers anyways.
12222 (define_insn "lds_fpscr"
12223 [(set (reg:SI FPSCR_REG)
12224 (match_operand:SI 0 "fpscr_movsrc_operand" "r,>"))
12225 (set (reg:SI FPSCR_STAT_REG)
12226 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_STAT))
12227 (set (reg:SI FPSCR_MODES_REG)
12228 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12233 [(set_attr "type" "gp_fpscr,mem_fpscr")])
12235 ;; A move fpscr -> reg schedules like a move mac -> reg. Thus we use mac_gp
12237 (define_insn "sts_fpscr"
12238 [(set (match_operand:SI 0 "fpscr_movdst_operand" "=r,<")
12239 (reg:SI FPSCR_REG))
12240 (use (reg:SI FPSCR_STAT_REG))
12241 (use (reg:SI FPSCR_MODES_REG))]
12246 [(set_attr "type" "mac_gp,fstore")])
12248 (define_expand "set_fpscr"
12249 [(parallel [(set (reg:SI FPSCR_REG)
12250 (match_operand:SI 0 "general_operand"))
12251 (set (reg:SI FPSCR_STAT_REG)
12252 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))])]
12255 /* We have to mask out the FR, SZ and PR bits. To do that, we need to
12256 get the current FPSCR value first.
12257 (a & ~mask) | (b & mask) = a ^ ((a ^ b) & mask) */
12259 rtx mask = force_reg (SImode, GEN_INT (FPSCR_FR | FPSCR_SZ | FPSCR_PR));
12261 rtx a = force_reg (SImode, operands[0]);
12263 rtx b = gen_reg_rtx (SImode);
12264 emit_insn (gen_sts_fpscr (b));
12266 rtx a_xor_b = gen_reg_rtx (SImode);
12267 emit_insn (gen_xorsi3 (a_xor_b, a, b));
12269 rtx a_xor_b_and_mask = gen_reg_rtx (SImode);
12270 emit_insn (gen_andsi3 (a_xor_b_and_mask, a_xor_b, mask));
12272 rtx r = gen_reg_rtx (SImode);
12273 emit_insn (gen_xorsi3 (r, a_xor_b_and_mask, a));
12274 emit_insn (gen_lds_fpscr (r));
12279 ;; ??? This uses the fp unit, but has no type indicating that.
12280 ;; If we did that, this would either give a bogus latency or introduce
12281 ;; a bogus FIFO constraint.
12282 ;; Since this insn is currently only used for prologues/epilogues,
12283 ;; it is probably best to claim no function unit, which matches the
12284 ;; current setting.
12285 (define_insn "toggle_sz"
12286 [(set (reg:SI FPSCR_REG)
12287 (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_SZ)))
12288 (set (reg:SI FPSCR_MODES_REG)
12289 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12290 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12292 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
12294 ;; Toggle FPU precision PR mode.
12296 (define_insn "toggle_pr"
12297 [(set (reg:SI FPSCR_REG)
12298 (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_PR)))
12299 (set (reg:SI FPSCR_MODES_REG)
12300 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12303 [(set_attr "type" "fpscr_toggle")])
12305 (define_expand "addsf3"
12306 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12307 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand")
12308 (match_operand:SF 2 "fp_arith_reg_operand")))]
12309 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12313 emit_insn (gen_addsf3_i (operands[0], operands[1], operands[2]));
12318 (define_insn "*addsf3_media"
12319 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12320 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12321 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12322 "TARGET_SHMEDIA_FPU"
12323 "fadd.s %1, %2, %0"
12324 [(set_attr "type" "fparith_media")])
12326 (define_insn_and_split "unary_sf_op"
12327 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12332 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
12333 (match_operator:SF 2 "unary_float_operator"
12334 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12335 (parallel [(match_operand 4
12336 "const_int_operand" "n")]))]))
12337 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
12338 "TARGET_SHMEDIA_FPU"
12340 "TARGET_SHMEDIA_FPU && reload_completed"
12341 [(set (match_dup 5) (match_dup 6))]
12343 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12344 rtx op1 = gen_rtx_REG (SFmode,
12345 (true_regnum (operands[1])
12346 + (INTVAL (operands[4]) ^ endian)));
12348 operands[7] = gen_rtx_REG (SFmode,
12349 (true_regnum (operands[0])
12350 + (INTVAL (operands[3]) ^ endian)));
12351 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
12353 [(set_attr "type" "fparith_media")])
12355 (define_insn_and_split "binary_sf_op0"
12356 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12358 (match_operator:SF 3 "binary_float_operator"
12359 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12360 (parallel [(const_int 0)]))
12361 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12362 (parallel [(const_int 0)]))])
12365 (parallel [(const_int 1)]))))]
12366 "TARGET_SHMEDIA_FPU"
12368 "&& reload_completed"
12369 [(set (match_dup 4) (match_dup 5))]
12371 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12372 rtx op1 = gen_rtx_REG (SFmode,
12373 true_regnum (operands[1]) + endian);
12374 rtx op2 = gen_rtx_REG (SFmode,
12375 true_regnum (operands[2]) + endian);
12377 operands[4] = gen_rtx_REG (SFmode,
12378 true_regnum (operands[0]) + endian);
12379 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12381 [(set_attr "type" "fparith_media")])
12383 (define_insn_and_split "binary_sf_op1"
12384 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12388 (parallel [(const_int 0)]))
12389 (match_operator:SF 3 "binary_float_operator"
12390 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12391 (parallel [(const_int 1)]))
12392 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12393 (parallel [(const_int 1)]))])))]
12394 "TARGET_SHMEDIA_FPU"
12396 "&& reload_completed"
12397 [(set (match_dup 4) (match_dup 5))]
12399 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12400 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
12401 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
12403 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
12404 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12406 [(set_attr "type" "fparith_media")])
12408 (define_insn "addsf3_i"
12409 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12410 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12411 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12412 (clobber (reg:SI FPSCR_STAT_REG))
12413 (use (reg:SI FPSCR_MODES_REG))]
12416 [(set_attr "type" "fp")
12417 (set_attr "fp_mode" "single")])
12419 (define_expand "subsf3"
12420 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12421 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12422 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12423 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12427 emit_insn (gen_subsf3_i (operands[0], operands[1], operands[2]));
12432 (define_insn "*subsf3_media"
12433 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12434 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12435 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12436 "TARGET_SHMEDIA_FPU"
12437 "fsub.s %1, %2, %0"
12438 [(set_attr "type" "fparith_media")])
12440 (define_insn "subsf3_i"
12441 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12442 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12443 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12444 (clobber (reg:SI FPSCR_STAT_REG))
12445 (use (reg:SI FPSCR_MODES_REG))]
12448 [(set_attr "type" "fp")
12449 (set_attr "fp_mode" "single")])
12451 (define_expand "mulsf3"
12452 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12453 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12454 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12455 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12459 emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2]));
12464 (define_insn "*mulsf3_media"
12465 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12466 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12467 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12468 "TARGET_SHMEDIA_FPU"
12469 "fmul.s %1, %2, %0"
12470 [(set_attr "type" "fparith_media")])
12472 (define_insn "mulsf3_i"
12473 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12474 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12475 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12476 (clobber (reg:SI FPSCR_STAT_REG))
12477 (use (reg:SI FPSCR_MODES_REG))]
12480 [(set_attr "type" "fp")
12481 (set_attr "fp_mode" "single")])
12483 ;; FMA (fused multiply-add) patterns
12484 (define_expand "fmasf4"
12485 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12486 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand")
12487 (match_operand:SF 2 "fp_arith_reg_operand")
12488 (match_operand:SF 3 "fp_arith_reg_operand")))]
12489 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12493 emit_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
12499 (define_insn "fmasf4_i"
12500 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12501 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
12502 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12503 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
12504 (clobber (reg:SI FPSCR_STAT_REG))
12505 (use (reg:SI FPSCR_MODES_REG))]
12508 [(set_attr "type" "fp")
12509 (set_attr "fp_mode" "single")])
12511 (define_insn "fmasf4_media"
12512 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12513 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12514 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12515 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12516 "TARGET_SHMEDIA_FPU"
12517 "fmac.s %1, %2, %0"
12518 [(set_attr "type" "fparith_media")])
12520 ;; For some cases such as 'a * b + a' the FMA pattern is not generated by
12521 ;; previous transformations. If FMA is generally allowed, let the combine
12522 ;; pass utilize it.
12523 (define_insn_and_split "*fmasf4"
12524 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12525 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
12526 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12527 (match_operand:SF 3 "arith_reg_operand" "0")))
12528 (clobber (reg:SI FPSCR_STAT_REG))
12529 (use (reg:SI FPSCR_MODES_REG))]
12530 "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF"
12532 "&& can_create_pseudo_p ()"
12533 [(parallel [(set (match_dup 0)
12534 (fma:SF (match_dup 1) (match_dup 2) (match_dup 3)))
12535 (clobber (reg:SI FPSCR_STAT_REG))
12536 (use (reg:SI FPSCR_MODES_REG))])]
12538 /* Change 'b * a + a' into 'a * b + a'.
12539 This is better for register allocation. */
12540 if (REGNO (operands[2]) == REGNO (operands[3]))
12542 rtx tmp = operands[1];
12543 operands[1] = operands[2];
12547 [(set_attr "type" "fp")
12548 (set_attr "fp_mode" "single")])
12550 (define_insn "*fmasf4_media"
12551 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12552 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12553 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12554 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12555 "TARGET_SHMEDIA_FPU && flag_fp_contract_mode != FP_CONTRACT_OFF"
12556 "fmac.s %1, %2, %0"
12557 [(set_attr "type" "fparith_media")])
12559 (define_expand "divsf3"
12560 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12561 (div:SF (match_operand:SF 1 "fp_arith_reg_operand")
12562 (match_operand:SF 2 "fp_arith_reg_operand")))]
12563 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12567 emit_insn (gen_divsf3_i (operands[0], operands[1], operands[2]));
12572 (define_insn "*divsf3_media"
12573 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12574 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12575 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12576 "TARGET_SHMEDIA_FPU"
12577 "fdiv.s %1, %2, %0"
12578 [(set_attr "type" "fdiv_media")])
12580 (define_insn "divsf3_i"
12581 [(set (match_operand:SF 0 "fp_arith_reg_dest" "=f")
12582 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12583 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12584 (clobber (reg:SI FPSCR_STAT_REG))
12585 (use (reg:SI FPSCR_MODES_REG))]
12588 [(set_attr "type" "fdiv")
12589 (set_attr "fp_mode" "single")])
12591 (define_insn "floatdisf2"
12592 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12593 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12594 "TARGET_SHMEDIA_FPU"
12596 [(set_attr "type" "fpconv_media")])
12598 (define_expand "floatsisf2"
12599 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12600 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
12601 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12603 if (!TARGET_SHMEDIA_FPU)
12605 emit_insn (gen_floatsisf2_i4 (operands[0], operands[1]));
12610 (define_insn "*floatsisf2_media"
12611 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12612 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12613 "TARGET_SHMEDIA_FPU"
12615 [(set_attr "type" "fpconv_media")])
12617 (define_insn "floatsisf2_i4"
12618 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12619 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
12620 (clobber (reg:SI FPSCR_STAT_REG))
12621 (use (reg:SI FPSCR_MODES_REG))]
12624 [(set_attr "type" "fp")
12625 (set_attr "fp_mode" "single")])
12627 (define_insn "fix_truncsfdi2"
12628 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12629 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12630 "TARGET_SHMEDIA_FPU"
12632 [(set_attr "type" "fpconv_media")])
12634 (define_expand "fix_truncsfsi2"
12635 [(set (match_operand:SI 0 "fpul_operand" "=y")
12636 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12637 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12639 if (!TARGET_SHMEDIA_FPU)
12641 emit_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1]));
12646 (define_insn "*fix_truncsfsi2_media"
12647 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12648 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12649 "TARGET_SHMEDIA_FPU"
12651 [(set_attr "type" "fpconv_media")])
12653 (define_insn "fix_truncsfsi2_i4"
12654 [(set (match_operand:SI 0 "fpul_operand" "=y")
12655 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12656 (clobber (reg:SI FPSCR_STAT_REG))
12657 (use (reg:SI FPSCR_MODES_REG))]
12660 [(set_attr "type" "ftrc_s")
12661 (set_attr "fp_mode" "single")])
12663 (define_insn "cmpgtsf_t"
12664 [(set (reg:SI T_REG)
12665 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12666 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12667 (clobber (reg:SI FPSCR_STAT_REG))
12668 (use (reg:SI FPSCR_MODES_REG))]
12669 "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE"
12671 [(set_attr "type" "fp_cmp")
12672 (set_attr "fp_mode" "single")])
12674 (define_insn "cmpeqsf_t"
12675 [(set (reg:SI T_REG)
12676 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12677 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12678 (clobber (reg:SI FPSCR_STAT_REG))
12679 (use (reg:SI FPSCR_MODES_REG))]
12680 "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE"
12682 [(set_attr "type" "fp_cmp")
12683 (set_attr "fp_mode" "single")])
12685 (define_insn "ieee_ccmpeqsf_t"
12686 [(set (reg:SI T_REG)
12687 (ior:SI (reg:SI T_REG)
12688 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12689 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12690 (clobber (reg:SI FPSCR_STAT_REG))
12691 (use (reg:SI FPSCR_MODES_REG))]
12692 "TARGET_IEEE && TARGET_SH2E"
12694 return output_ieee_ccmpeq (insn, operands);
12696 [(set_attr "length" "4")
12697 (set_attr "fp_mode" "single")])
12699 (define_insn "cmpeqsf_media"
12700 [(set (match_operand:SI 0 "register_operand" "=r")
12701 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12702 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12703 "TARGET_SHMEDIA_FPU"
12704 "fcmpeq.s %1, %2, %0"
12705 [(set_attr "type" "fcmp_media")])
12707 (define_insn "cmpgtsf_media"
12708 [(set (match_operand:SI 0 "register_operand" "=r")
12709 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12710 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12711 "TARGET_SHMEDIA_FPU"
12712 "fcmpgt.s %1, %2, %0"
12713 [(set_attr "type" "fcmp_media")])
12715 (define_insn "cmpgesf_media"
12716 [(set (match_operand:SI 0 "register_operand" "=r")
12717 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12718 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12719 "TARGET_SHMEDIA_FPU"
12720 "fcmpge.s %1, %2, %0"
12721 [(set_attr "type" "fcmp_media")])
12723 (define_insn "cmpunsf_media"
12724 [(set (match_operand:SI 0 "register_operand" "=r")
12725 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12726 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12727 "TARGET_SHMEDIA_FPU"
12728 "fcmpun.s %1, %2, %0"
12729 [(set_attr "type" "fcmp_media")])
12731 (define_expand "cbranchsf4"
12733 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12734 [(match_operand:SF 1 "arith_operand" "")
12735 (match_operand:SF 2 "arith_operand" "")])
12736 (match_operand 3 "" "")
12738 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12740 if (TARGET_SHMEDIA)
12741 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12744 sh_emit_compare_and_branch (operands, SFmode);
12748 (define_expand "negsf2"
12749 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12750 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand")))]
12751 "TARGET_SH2E || TARGET_SHMEDIA_FPU")
12753 (define_insn "*negsf2_media"
12754 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12755 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12756 "TARGET_SHMEDIA_FPU"
12758 [(set_attr "type" "fmove_media")])
12760 (define_insn "*negsf2_i"
12761 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12762 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))]
12765 [(set_attr "type" "fmove")])
12767 (define_expand "sqrtsf2"
12768 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12769 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12770 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12774 emit_insn (gen_sqrtsf2_i (operands[0], operands[1]));
12779 (define_insn "*sqrtsf2_media"
12780 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12781 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12782 "TARGET_SHMEDIA_FPU"
12784 [(set_attr "type" "fdiv_media")])
12786 (define_insn "sqrtsf2_i"
12787 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12788 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12789 (clobber (reg:SI FPSCR_STAT_REG))
12790 (use (reg:SI FPSCR_MODES_REG))]
12793 [(set_attr "type" "fdiv")
12794 (set_attr "fp_mode" "single")])
12796 (define_insn "rsqrtsf2"
12797 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12798 (div:SF (match_operand:SF 1 "immediate_operand" "i")
12799 (sqrt:SF (match_operand:SF 2 "fp_arith_reg_operand" "0"))))
12800 (clobber (reg:SI FPSCR_STAT_REG))
12801 (use (reg:SI FPSCR_MODES_REG))]
12802 "TARGET_FPU_ANY && TARGET_FSRRA
12803 && operands[1] == CONST1_RTX (SFmode)"
12805 [(set_attr "type" "fsrra")
12806 (set_attr "fp_mode" "single")])
12808 ;; When the sincos pattern is defined, the builtin functions sin and cos
12809 ;; will be expanded to the sincos pattern and one of the output values will
12811 (define_expand "sincossf3"
12812 [(set (match_operand:SF 0 "nonimmediate_operand")
12813 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
12814 (set (match_operand:SF 1 "nonimmediate_operand")
12815 (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
12816 "TARGET_FPU_ANY && TARGET_FSCA"
12818 rtx scaled = gen_reg_rtx (SFmode);
12819 rtx truncated = gen_reg_rtx (SImode);
12820 rtx fsca = gen_reg_rtx (V2SFmode);
12821 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12823 emit_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12824 emit_insn (gen_fix_truncsfsi2 (truncated, scaled));
12825 emit_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf ()));
12827 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
12828 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
12832 (define_insn_and_split "fsca"
12833 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12835 (unspec:SF [(mult:SF
12836 (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12837 (match_operand:SF 2 "fsca_scale_factor" "i"))
12839 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12841 (clobber (reg:SI FPSCR_STAT_REG))
12842 (use (reg:SI FPSCR_MODES_REG))]
12843 "TARGET_FPU_ANY && TARGET_FSCA"
12845 "&& !fpul_operand (operands[1], SImode)"
12848 /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12849 to a simple reg, otherwise reload will have trouble reloading the
12850 pseudo into fpul. */
12851 rtx x = XEXP (operands[1], 0);
12852 while (x != NULL_RTX && !fpul_operand (x, SImode))
12854 gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12857 gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12858 emit_insn (gen_fsca (operands[0], x, operands[2]));
12861 [(set_attr "type" "fsca")
12862 (set_attr "fp_mode" "single")])
12864 (define_expand "abssf2"
12865 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12866 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand")))]
12867 "TARGET_SH2E || TARGET_SHMEDIA_FPU")
12869 (define_insn "*abssf2_media"
12870 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12871 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12872 "TARGET_SHMEDIA_FPU"
12874 [(set_attr "type" "fmove_media")])
12876 (define_insn "*abssf2_i"
12877 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12878 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))]
12881 [(set_attr "type" "fmove")])
12883 (define_expand "adddf3"
12884 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12885 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12886 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12887 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12889 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12891 emit_insn (gen_adddf3_i (operands[0], operands[1], operands[2]));
12896 (define_insn "*adddf3_media"
12897 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12898 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12899 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12900 "TARGET_SHMEDIA_FPU"
12901 "fadd.d %1, %2, %0"
12902 [(set_attr "type" "dfparith_media")])
12904 (define_insn "adddf3_i"
12905 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12906 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12907 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12908 (clobber (reg:SI FPSCR_STAT_REG))
12909 (use (reg:SI FPSCR_MODES_REG))]
12910 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12912 [(set_attr "type" "dfp_arith")
12913 (set_attr "fp_mode" "double")])
12915 (define_expand "subdf3"
12916 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12917 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12918 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12919 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12921 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12923 emit_insn (gen_subdf3_i (operands[0], operands[1], operands[2]));
12928 (define_insn "*subdf3_media"
12929 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12930 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12931 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12932 "TARGET_SHMEDIA_FPU"
12933 "fsub.d %1, %2, %0"
12934 [(set_attr "type" "dfparith_media")])
12936 (define_insn "subdf3_i"
12937 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12938 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12939 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12940 (clobber (reg:SI FPSCR_STAT_REG))
12941 (use (reg:SI FPSCR_MODES_REG))]
12942 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12944 [(set_attr "type" "dfp_arith")
12945 (set_attr "fp_mode" "double")])
12947 (define_expand "muldf3"
12948 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12949 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12950 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12951 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12953 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12955 emit_insn (gen_muldf3_i (operands[0], operands[1], operands[2]));
12960 (define_insn "*muldf3_media"
12961 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12962 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12963 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12964 "TARGET_SHMEDIA_FPU"
12965 "fmul.d %1, %2, %0"
12966 [(set_attr "type" "dfmul_media")])
12968 (define_insn "muldf3_i"
12969 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12970 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12971 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12972 (clobber (reg:SI FPSCR_STAT_REG))
12973 (use (reg:SI FPSCR_MODES_REG))]
12974 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12976 [(set_attr "type" "dfp_mul")
12977 (set_attr "fp_mode" "double")])
12979 (define_expand "divdf3"
12980 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12981 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12982 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12983 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12985 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12987 emit_insn (gen_divdf3_i (operands[0], operands[1], operands[2]));
12992 (define_insn "*divdf3_media"
12993 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12994 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12995 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12996 "TARGET_SHMEDIA_FPU"
12997 "fdiv.d %1, %2, %0"
12998 [(set_attr "type" "dfdiv_media")])
13000 (define_insn "divdf3_i"
13001 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13002 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
13003 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13004 (clobber (reg:SI FPSCR_STAT_REG))
13005 (use (reg:SI FPSCR_MODES_REG))]
13006 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13008 [(set_attr "type" "dfdiv")
13009 (set_attr "fp_mode" "double")])
13011 (define_insn "floatdidf2"
13012 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13013 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
13014 "TARGET_SHMEDIA_FPU"
13016 [(set_attr "type" "dfpconv_media")])
13018 (define_expand "floatsidf2"
13019 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13020 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
13021 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13023 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13025 emit_insn (gen_floatsidf2_i (operands[0], operands[1]));
13030 (define_insn "*floatsidf2_media"
13031 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13032 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
13033 "TARGET_SHMEDIA_FPU"
13035 [(set_attr "type" "dfpconv_media")])
13037 (define_insn "floatsidf2_i"
13038 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13039 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
13040 (clobber (reg:SI FPSCR_STAT_REG))
13041 (use (reg:SI FPSCR_MODES_REG))]
13042 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13044 [(set_attr "type" "dfp_conv")
13045 (set_attr "fp_mode" "double")])
13047 (define_insn "fix_truncdfdi2"
13048 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
13049 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13050 "TARGET_SHMEDIA_FPU"
13052 [(set_attr "type" "dfpconv_media")])
13054 (define_expand "fix_truncdfsi2"
13055 [(set (match_operand:SI 0 "fpul_operand" "")
13056 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13057 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13059 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13061 emit_insn (gen_fix_truncdfsi2_i (operands[0], operands[1]));
13066 (define_insn "*fix_truncdfsi2_media"
13067 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
13068 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13069 "TARGET_SHMEDIA_FPU"
13071 [(set_attr "type" "dfpconv_media")])
13073 (define_insn "fix_truncdfsi2_i"
13074 [(set (match_operand:SI 0 "fpul_operand" "=y")
13075 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13076 (clobber (reg:SI FPSCR_STAT_REG))
13077 (use (reg:SI FPSCR_MODES_REG))]
13078 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13080 [(set_attr "type" "dfp_conv")
13081 (set_attr "dfp_comp" "no")
13082 (set_attr "fp_mode" "double")])
13084 (define_insn "cmpgtdf_t"
13085 [(set (reg:SI T_REG)
13086 (gt:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13087 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13088 (clobber (reg:SI FPSCR_STAT_REG))
13089 (use (reg:SI FPSCR_MODES_REG))]
13090 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13092 [(set_attr "type" "dfp_cmp")
13093 (set_attr "fp_mode" "double")])
13095 (define_insn "cmpeqdf_t"
13096 [(set (reg:SI T_REG)
13097 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13098 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13099 (clobber (reg:SI FPSCR_STAT_REG))
13100 (use (reg:SI FPSCR_MODES_REG))]
13101 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13103 [(set_attr "type" "dfp_cmp")
13104 (set_attr "fp_mode" "double")])
13106 (define_insn "*ieee_ccmpeqdf_t"
13107 [(set (reg:SI T_REG)
13108 (ior:SI (reg:SI T_REG)
13109 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13110 (match_operand:DF 1 "fp_arith_reg_operand" "f"))))
13111 (clobber (reg:SI FPSCR_STAT_REG))
13112 (use (reg:SI FPSCR_MODES_REG))]
13113 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13115 return output_ieee_ccmpeq (insn, operands);
13117 [(set_attr "length" "4")
13118 (set_attr "fp_mode" "double")])
13120 (define_insn "cmpeqdf_media"
13121 [(set (match_operand:SI 0 "register_operand" "=r")
13122 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13123 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13124 "TARGET_SHMEDIA_FPU"
13125 "fcmpeq.d %1,%2,%0"
13126 [(set_attr "type" "fcmp_media")])
13128 (define_insn "cmpgtdf_media"
13129 [(set (match_operand:SI 0 "register_operand" "=r")
13130 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13131 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13132 "TARGET_SHMEDIA_FPU"
13133 "fcmpgt.d %1,%2,%0"
13134 [(set_attr "type" "fcmp_media")])
13136 (define_insn "cmpgedf_media"
13137 [(set (match_operand:SI 0 "register_operand" "=r")
13138 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13139 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13140 "TARGET_SHMEDIA_FPU"
13141 "fcmpge.d %1,%2,%0"
13142 [(set_attr "type" "fcmp_media")])
13144 (define_insn "cmpundf_media"
13145 [(set (match_operand:SI 0 "register_operand" "=r")
13146 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13147 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13148 "TARGET_SHMEDIA_FPU"
13149 "fcmpun.d %1,%2,%0"
13150 [(set_attr "type" "fcmp_media")])
13152 (define_expand "cbranchdf4"
13154 (if_then_else (match_operator 0 "sh_float_comparison_operator"
13155 [(match_operand:DF 1 "arith_operand" "")
13156 (match_operand:DF 2 "arith_operand" "")])
13157 (match_operand 3 "" "")
13159 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13161 if (TARGET_SHMEDIA)
13162 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
13165 sh_emit_compare_and_branch (operands, DFmode);
13169 (define_expand "negdf2"
13170 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13171 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13172 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU")
13174 (define_insn "*negdf2_media"
13175 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13176 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13177 "TARGET_SHMEDIA_FPU"
13179 [(set_attr "type" "fmove_media")])
13181 (define_insn "*negdf2_i"
13182 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13183 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))]
13184 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13186 [(set_attr "type" "fmove")])
13188 (define_expand "sqrtdf2"
13189 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13190 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13191 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13193 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13195 emit_insn (gen_sqrtdf2_i (operands[0], operands[1]));
13200 (define_insn "*sqrtdf2_media"
13201 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13202 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13203 "TARGET_SHMEDIA_FPU"
13205 [(set_attr "type" "dfdiv_media")])
13207 (define_insn "sqrtdf2_i"
13208 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13209 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
13210 (clobber (reg:SI FPSCR_STAT_REG))
13211 (use (reg:SI FPSCR_MODES_REG))]
13212 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13214 [(set_attr "type" "dfdiv")
13215 (set_attr "fp_mode" "double")])
13217 (define_expand "absdf2"
13218 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13219 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13220 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU")
13222 (define_insn "*absdf2_media"
13223 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13224 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13225 "TARGET_SHMEDIA_FPU"
13227 [(set_attr "type" "fmove_media")])
13229 (define_insn "*absdf2_i"
13230 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13231 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))]
13232 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13234 [(set_attr "type" "fmove")])
13236 (define_expand "extendsfdf2"
13237 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13238 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
13239 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13241 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13243 emit_insn (gen_extendsfdf2_i4 (operands[0], operands[1]));
13248 (define_insn "*extendsfdf2_media"
13249 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13250 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13251 "TARGET_SHMEDIA_FPU"
13253 [(set_attr "type" "dfpconv_media")])
13255 (define_insn "extendsfdf2_i4"
13256 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13257 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
13258 (clobber (reg:SI FPSCR_STAT_REG))
13259 (use (reg:SI FPSCR_MODES_REG))]
13260 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13262 [(set_attr "type" "fp")
13263 (set_attr "fp_mode" "double")])
13265 (define_expand "truncdfsf2"
13266 [(set (match_operand:SF 0 "fpul_operand" "")
13267 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13268 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13270 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13272 emit_insn (gen_truncdfsf2_i4 (operands[0], operands[1]));
13277 (define_insn "*truncdfsf2_media"
13278 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13279 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13280 "TARGET_SHMEDIA_FPU"
13282 [(set_attr "type" "dfpconv_media")])
13284 (define_insn "truncdfsf2_i4"
13285 [(set (match_operand:SF 0 "fpul_operand" "=y")
13286 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13287 (clobber (reg:SI FPSCR_STAT_REG))
13288 (use (reg:SI FPSCR_MODES_REG))]
13289 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13291 [(set_attr "type" "fp")
13292 (set_attr "fp_mode" "double")])
13294 ;; -------------------------------------------------------------------------
13295 ;; Bit field extract patterns.
13296 ;; -------------------------------------------------------------------------
13298 ;; These give better code for packed bitfields, because they allow
13299 ;; auto-increment addresses to be generated.
13301 (define_expand "insv"
13302 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
13303 (match_operand:SI 1 "immediate_operand" "")
13304 (match_operand:SI 2 "immediate_operand" ""))
13305 (match_operand:SI 3 "general_operand" ""))]
13306 "TARGET_SH1 && TARGET_BIG_ENDIAN"
13308 rtx addr_target, orig_address, shift_reg, qi_val;
13309 HOST_WIDE_INT bitsize, size, v = 0;
13310 rtx x = operands[3];
13312 if (TARGET_SH2A && TARGET_BITOPS
13313 && (satisfies_constraint_Sbw (operands[0])
13314 || satisfies_constraint_Sbv (operands[0]))
13315 && satisfies_constraint_M (operands[1])
13316 && satisfies_constraint_K03 (operands[2]))
13318 if (satisfies_constraint_N (operands[3]))
13320 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
13323 else if (satisfies_constraint_M (operands[3]))
13325 emit_insn (gen_bset_m2a (operands[0], operands[2]));
13328 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
13329 && satisfies_constraint_M (operands[1]))
13331 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13334 else if (REG_P (operands[3])
13335 && satisfies_constraint_M (operands[1]))
13337 emit_insn (gen_bld_reg (operands[3], const0_rtx));
13338 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13342 /* ??? expmed doesn't care for non-register predicates. */
13343 if (! memory_operand (operands[0], VOIDmode)
13344 || ! immediate_operand (operands[1], VOIDmode)
13345 || ! immediate_operand (operands[2], VOIDmode)
13346 || ! general_operand (x, VOIDmode))
13348 /* If this isn't a 16 / 24 / 32 bit field, or if
13349 it doesn't start on a byte boundary, then fail. */
13350 bitsize = INTVAL (operands[1]);
13351 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13352 || (INTVAL (operands[2]) % 8) != 0)
13355 size = bitsize / 8;
13356 orig_address = XEXP (operands[0], 0);
13357 shift_reg = gen_reg_rtx (SImode);
13358 if (CONST_INT_P (x))
13361 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13365 emit_insn (gen_movsi (shift_reg, operands[3]));
13366 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13368 addr_target = copy_addr_to_reg (plus_constant (Pmode,
13369 orig_address, size - 1));
13371 operands[0] = replace_equiv_address (operands[0], addr_target);
13372 emit_insn (gen_movqi (operands[0], qi_val));
13376 if (CONST_INT_P (x))
13378 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13381 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13382 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13384 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13385 emit_insn (gen_movqi (operands[0], qi_val));
13391 (define_insn "movua"
13392 [(set (match_operand:SI 0 "register_operand" "=z")
13393 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13397 [(set_attr "type" "movua")])
13399 ;; We shouldn't need this, but cse replaces increments with references
13400 ;; to other regs before flow has a chance to create post_inc
13401 ;; addressing modes, and only postreload's cse_move2add brings the
13402 ;; increments back to a usable form.
13404 [(set (match_operand:SI 0 "register_operand" "")
13405 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
13406 (const_int 32) (const_int 0)))
13407 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13408 "TARGET_SH4A && REGNO (operands[0]) != REGNO (operands[1])"
13409 [(set (match_operand:SI 0 "register_operand" "")
13410 (sign_extract:SI (mem:SI (post_inc:SI
13411 (match_operand:SI 1 "register_operand" "")))
13412 (const_int 32) (const_int 0)))]
13415 (define_expand "extv"
13416 [(set (match_operand:SI 0 "register_operand" "")
13417 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13418 (match_operand 2 "const_int_operand" "")
13419 (match_operand 3 "const_int_operand" "")))]
13420 "TARGET_SH4A || TARGET_SH2A"
13422 if (TARGET_SH2A && TARGET_BITOPS
13423 && (satisfies_constraint_Sbw (operands[1])
13424 || satisfies_constraint_Sbv (operands[1]))
13425 && satisfies_constraint_M (operands[2])
13426 && satisfies_constraint_K03 (operands[3]))
13428 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
13429 if (REGNO (operands[0]) != T_REG)
13430 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13434 && INTVAL (operands[2]) == 32
13435 && INTVAL (operands[3]) == 0
13436 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13438 rtx src = adjust_address (operands[1], BLKmode, 0);
13439 set_mem_size (src, 4);
13440 emit_insn (gen_movua (operands[0], src));
13447 (define_expand "extzv"
13448 [(set (match_operand:SI 0 "register_operand" "")
13449 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13450 (match_operand 2 "const_int_operand" "")
13451 (match_operand 3 "const_int_operand" "")))]
13452 "TARGET_SH4A || TARGET_SH2A"
13454 if (TARGET_SH2A && TARGET_BITOPS
13455 && (satisfies_constraint_Sbw (operands[1])
13456 || satisfies_constraint_Sbv (operands[1]))
13457 && satisfies_constraint_M (operands[2])
13458 && satisfies_constraint_K03 (operands[3]))
13460 emit_insn (gen_bld_m2a (operands[1], operands[3]));
13461 if (REGNO (operands[0]) != T_REG)
13462 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13466 && INTVAL (operands[2]) == 32
13467 && INTVAL (operands[3]) == 0
13468 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13470 rtx src = adjust_address (operands[1], BLKmode, 0);
13471 set_mem_size (src, 4);
13472 emit_insn (gen_movua (operands[0], src));
13479 ;; SH2A instructions for bitwise operations.
13480 ;; FIXME: Convert multiple instruction insns to insn_and_split.
13481 ;; FIXME: Use iterators to fold at least and,xor,or insn variations.
13483 ;; Clear a bit in a memory location.
13484 (define_insn "bclr_m2a"
13485 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13487 (not:QI (ashift:QI (const_int 1)
13488 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13490 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13493 bclr.b %1,@(0,%t0)"
13494 [(set_attr "length" "4,4")])
13496 (define_insn "bclrmem_m2a"
13497 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13498 (and:QI (match_dup 0)
13499 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
13500 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
13503 bclr.b %W1,@(0,%t0)"
13504 [(set_attr "length" "4,4")])
13506 ;; Set a bit in a memory location.
13507 (define_insn "bset_m2a"
13508 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13510 (ashift:QI (const_int 1)
13511 (match_operand:QI 1 "const_int_operand" "K03,K03"))
13513 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13516 bset.b %1,@(0,%t0)"
13517 [(set_attr "length" "4,4")])
13519 (define_insn "bsetmem_m2a"
13520 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13521 (ior:QI (match_dup 0)
13522 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
13523 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
13526 bset.b %V1,@(0,%t0)"
13527 [(set_attr "length" "4,4")])
13529 ;;; Transfer the contents of the T bit to a specified bit of memory.
13530 (define_insn "bst_m2a"
13531 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
13532 (if_then_else (eq (reg:SI T_REG) (const_int 0))
13534 (not:QI (ashift:QI (const_int 1)
13535 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13538 (ashift:QI (const_int 1) (match_dup 1))
13540 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13544 [(set_attr "length" "4")])
13546 ;; Store a specified bit of memory in the T bit.
13547 (define_insn "bld_m2a"
13548 [(set (reg:SI T_REG)
13550 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13552 (match_operand 1 "const_int_operand" "K03,K03")))]
13553 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13557 [(set_attr "length" "4,4")])
13559 ;; Store a specified bit of memory in the T bit.
13560 (define_insn "bldsign_m2a"
13561 [(set (reg:SI T_REG)
13563 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13565 (match_operand 1 "const_int_operand" "K03,K03")))]
13566 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13570 [(set_attr "length" "4,4")])
13572 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13573 (define_insn "bld_reg"
13574 [(set (reg:SI T_REG)
13575 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13577 (match_operand 1 "const_int_operand" "K03")))]
13578 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13581 (define_insn "*bld_regqi"
13582 [(set (reg:SI T_REG)
13583 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13585 (match_operand 1 "const_int_operand" "K03")))]
13586 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13589 ;; Take logical and of a specified bit of memory with the T bit and
13590 ;; store its result in the T bit.
13591 (define_insn "band_m2a"
13592 [(set (reg:SI T_REG)
13593 (and:SI (reg:SI T_REG)
13595 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13597 (match_operand 1 "const_int_operand" "K03,K03"))))]
13598 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13601 band.b %1,@(0,%t0)"
13602 [(set_attr "length" "4,4")])
13604 (define_insn "bandreg_m2a"
13605 [(set (match_operand:SI 0 "register_operand" "=r,r")
13606 (and:SI (zero_extract:SI
13607 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13609 (match_operand 2 "const_int_operand" "K03,K03"))
13610 (match_operand:SI 3 "register_operand" "r,r")))]
13611 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13613 static const char* alt[] =
13615 "band.b %2,%1" "\n"
13618 "band.b %2,@(0,%t1)" "\n"
13621 return alt[which_alternative];
13623 [(set_attr "length" "6,6")])
13625 ;; Take logical or of a specified bit of memory with the T bit and
13626 ;; store its result in the T bit.
13627 (define_insn "bor_m2a"
13628 [(set (reg:SI T_REG)
13629 (ior:SI (reg:SI T_REG)
13631 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13633 (match_operand 1 "const_int_operand" "K03,K03"))))]
13634 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13638 [(set_attr "length" "4,4")])
13640 (define_insn "borreg_m2a"
13641 [(set (match_operand:SI 0 "register_operand" "=r,r")
13642 (ior:SI (zero_extract:SI
13643 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13645 (match_operand 2 "const_int_operand" "K03,K03"))
13646 (match_operand:SI 3 "register_operand" "=r,r")))]
13647 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13649 static const char* alt[] =
13654 "bor.b %2,@(0,%t1)" "\n"
13657 return alt[which_alternative];
13659 [(set_attr "length" "6,6")])
13661 ;; Take exclusive or of a specified bit of memory with the T bit and
13662 ;; store its result in the T bit.
13663 (define_insn "bxor_m2a"
13664 [(set (reg:SI T_REG)
13665 (xor:SI (reg:SI T_REG)
13667 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13669 (match_operand 1 "const_int_operand" "K03,K03"))))]
13670 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13673 bxor.b %1,@(0,%t0)"
13674 [(set_attr "length" "4,4")])
13676 (define_insn "bxorreg_m2a"
13677 [(set (match_operand:SI 0 "register_operand" "=r,r")
13678 (xor:SI (zero_extract:SI
13679 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13681 (match_operand 2 "const_int_operand" "K03,K03"))
13682 (match_operand:SI 3 "register_operand" "=r,r")))]
13683 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13685 static const char* alt[] =
13687 "bxor.b %2,%1" "\n"
13690 "bxor.b %2,@(0,%t1)" "\n"
13693 return alt[which_alternative];
13695 [(set_attr "length" "6,6")])
13697 ;; -------------------------------------------------------------------------
13699 ;; -------------------------------------------------------------------------
13700 ;; This matches cases where the bit in a memory location is set.
13702 [(set (match_operand:SI 0 "register_operand")
13703 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
13705 (ior:SI (match_dup 0)
13706 (match_operand:SI 2 "const_int_operand")))
13708 (match_operand 3 "arith_reg_operand"))]
13709 "TARGET_SH2A && TARGET_BITOPS
13710 && satisfies_constraint_Pso (operands[2])
13711 && REGNO (operands[0]) == REGNO (operands[3])"
13712 [(set (match_dup 1)
13713 (ior:QI (match_dup 1) (match_dup 2)))]
13716 ;; This matches cases where the bit in a memory location is cleared.
13718 [(set (match_operand:SI 0 "register_operand")
13719 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
13721 (and:SI (match_dup 0)
13722 (match_operand:SI 2 "const_int_operand")))
13724 (match_operand 3 "arith_reg_operand"))]
13725 "TARGET_SH2A && TARGET_BITOPS
13726 && satisfies_constraint_Psz (operands[2])
13727 && REGNO (operands[0]) == REGNO (operands[3])"
13728 [(set (match_dup 1)
13729 (and:QI (match_dup 1) (match_dup 2)))]
13732 ;; This matches cases where a stack pointer increment at the start of the
13733 ;; epilogue combines with a stack slot read loading the return value.
13735 [(set (match_operand:SI 0 "arith_reg_operand" "")
13736 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13737 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13738 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13741 ;; See the comment on the dt combiner pattern above.
13743 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13744 (plus:SI (match_dup 0)
13746 (set (reg:SI T_REG)
13747 (eq:SI (match_dup 0) (const_int 0)))]
13751 ;; The following peepholes fold load sequences for which reload was not
13752 ;; able to generate a displacement addressing move insn.
13753 ;; This can happen when reload has to transform a move insn
13754 ;; without displacement into one with displacement. Or when reload can't
13755 ;; fit a displacement into the insn's constraints. In the latter case, the
13756 ;; load destination reg remains at r0, which reload compensates by inserting
13757 ;; another mov insn.
13761 ;; mov.{b,w} @(r0,r15),r0
13764 ;; mov.{b,w} @(54,r15),r3
13767 [(set (match_operand:SI 0 "arith_reg_dest" "")
13768 (match_operand:SI 1 "const_int_operand" ""))
13769 (set (match_operand:SI 2 "arith_reg_dest" "")
13771 (mem:QI (plus:SI (match_dup 0)
13772 (match_operand:SI 3 "arith_reg_operand" "")))))
13773 (set (match_operand:QI 4 "arith_reg_dest" "")
13774 (match_operand:QI 5 "arith_reg_operand" ""))]
13776 && sh_legitimate_index_p (QImode, operands[1], true, true)
13777 && REGNO (operands[2]) == REGNO (operands[5])
13778 && peep2_reg_dead_p (3, operands[5])"
13779 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13783 [(set (match_operand:SI 0 "arith_reg_dest" "")
13784 (match_operand:SI 1 "const_int_operand" ""))
13785 (set (match_operand:SI 2 "arith_reg_dest" "")
13787 (mem:HI (plus:SI (match_dup 0)
13788 (match_operand:SI 3 "arith_reg_operand" "")))))
13789 (set (match_operand:HI 4 "arith_reg_dest" "")
13790 (match_operand:HI 5 "arith_reg_operand" ""))]
13792 && sh_legitimate_index_p (HImode, operands[1], true, true)
13793 && REGNO (operands[2]) == REGNO (operands[5])
13794 && peep2_reg_dead_p (3, operands[5])"
13795 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13800 ;; mov.{b,w} @(r0,r15),r1
13802 ;; mov.{b,w} @(54,r15),r1
13805 [(set (match_operand:SI 0 "arith_reg_dest" "")
13806 (match_operand:SI 1 "const_int_operand" ""))
13807 (set (match_operand:SI 2 "arith_reg_dest" "")
13809 (mem:QI (plus:SI (match_dup 0)
13810 (match_operand:SI 3 "arith_reg_operand" "")))))]
13812 && sh_legitimate_index_p (QImode, operands[1], true, true)
13813 && (peep2_reg_dead_p (2, operands[0])
13814 || REGNO (operands[0]) == REGNO (operands[2]))"
13815 [(set (match_dup 2)
13816 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13820 [(set (match_operand:SI 0 "arith_reg_dest" "")
13821 (match_operand:SI 1 "const_int_operand" ""))
13822 (set (match_operand:SI 2 "arith_reg_dest" "")
13824 (mem:HI (plus:SI (match_dup 0)
13825 (match_operand:SI 3 "arith_reg_operand" "")))))]
13827 && sh_legitimate_index_p (HImode, operands[1], true, true)
13828 && (peep2_reg_dead_p (2, operands[0])
13829 || REGNO (operands[0]) == REGNO (operands[2]))"
13830 [(set (match_dup 2)
13831 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13835 ;; mov.{b,w} @(r0,r15),r0
13838 ;; mov.{b,w} @(r0,r15),r3
13840 ;; This can happen when initially a displacement address is picked, where
13841 ;; the destination reg is fixed to r0, and then the address is transformed
13842 ;; into 'r0 + reg'.
13844 [(set (match_operand:SI 0 "arith_reg_dest" "")
13846 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13847 (match_operand:SI 2 "arith_reg_operand" "")))))
13848 (set (match_operand:QI 3 "arith_reg_dest" "")
13849 (match_operand:QI 4 "arith_reg_operand" ""))]
13851 && REGNO (operands[0]) == REGNO (operands[4])
13852 && peep2_reg_dead_p (2, operands[0])"
13853 [(set (match_dup 3)
13854 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13858 [(set (match_operand:SI 0 "arith_reg_dest" "")
13860 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13861 (match_operand:SI 2 "arith_reg_operand" "")))))
13862 (set (match_operand:HI 3 "arith_reg_dest" "")
13863 (match_operand:HI 4 "arith_reg_operand" ""))]
13865 && REGNO (operands[0]) == REGNO (operands[4])
13866 && peep2_reg_dead_p (2, operands[0])"
13867 [(set (match_dup 3)
13868 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13872 [(set (match_operand:SI 0 "register_operand" "=r")
13873 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13874 (set (mem:SF (match_dup 0))
13875 (match_operand:SF 2 "general_movsrc_operand" ""))]
13876 "TARGET_SH1 && REGNO (operands[0]) == 0
13877 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13878 || (GET_CODE (operands[2]) == SUBREG
13879 && REGNO (SUBREG_REG (operands[2])) < 16))
13880 && reg_unused_after (operands[0], insn)"
13881 "mov.l %2,@(%0,%1)")
13884 [(set (match_operand:SI 0 "register_operand" "=r")
13885 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13886 (set (match_operand:SF 2 "general_movdst_operand" "")
13888 (mem:SF (match_dup 0)))]
13889 "TARGET_SH1 && REGNO (operands[0]) == 0
13890 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13891 || (GET_CODE (operands[2]) == SUBREG
13892 && REGNO (SUBREG_REG (operands[2])) < 16))
13893 && reg_unused_after (operands[0], insn)"
13894 "mov.l @(%0,%1),%2")
13897 [(set (match_operand:SI 0 "register_operand" "=r")
13898 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13899 (set (mem:SF (match_dup 0))
13900 (match_operand:SF 2 "general_movsrc_operand" ""))]
13901 "TARGET_SH2E && REGNO (operands[0]) == 0
13902 && ((REG_P (operands[2])
13903 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13904 || (GET_CODE (operands[2]) == SUBREG
13905 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13906 && reg_unused_after (operands[0], insn)"
13907 "fmov{.s|} %2,@(%0,%1)")
13910 [(set (match_operand:SI 0 "register_operand" "=r")
13911 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13912 (set (match_operand:SF 2 "general_movdst_operand" "")
13914 (mem:SF (match_dup 0)))]
13915 "TARGET_SH2E && REGNO (operands[0]) == 0
13916 && ((REG_P (operands[2])
13917 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13918 || (GET_CODE (operands[2]) == SUBREG
13919 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13920 && reg_unused_after (operands[0], insn)"
13921 "fmov{.s|} @(%0,%1),%2")
13923 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13924 (define_insn "sp_switch_1"
13925 [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
13926 UNSPECV_SP_SWITCH_B))]
13929 return "mov.l r0,@-r15" "\n"
13930 " mov.l %0,r0" "\n"
13931 " mov.l @r0,r0" "\n"
13932 " mov.l r15,@-r0" "\n"
13935 [(set_attr "length" "10")])
13937 ;; Switch back to the original stack for interrupt functions with the
13938 ;; sp_switch attribute.
13939 (define_insn "sp_switch_2"
13940 [(unspec_volatile [(const_int 0)]
13941 UNSPECV_SP_SWITCH_E)]
13944 return "mov.l @r15,r15" "\n"
13947 [(set_attr "length" "4")])
13949 ;; -------------------------------------------------------------------------
13950 ;; Integer vector moves
13951 ;; -------------------------------------------------------------------------
13953 (define_expand "movv8qi"
13954 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
13955 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
13958 prepare_move_operands (operands, V8QImode);
13961 (define_insn "movv8qi_i"
13962 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
13963 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13965 && (register_operand (operands[0], V8QImode)
13966 || sh_register_operand (operands[1], V8QImode))"
13973 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13974 (set_attr "length" "4,4,16,4,4")])
13977 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
13978 (subreg:V8QI (const_int 0) 0))]
13980 [(set (match_dup 0)
13981 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
13982 (const_int 0) (const_int 0) (const_int 0)
13983 (const_int 0) (const_int 0)]))])
13986 [(set (match_operand 0 "arith_reg_dest" "")
13987 (match_operand 1 "sh_rep_vec" ""))]
13988 "TARGET_SHMEDIA && reload_completed
13989 && GET_MODE (operands[0]) == GET_MODE (operands[1])
13990 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
13991 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
13992 && (XVECEXP (operands[1], 0, 0) != const0_rtx
13993 || XVECEXP (operands[1], 0, 1) != const0_rtx)
13994 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
13995 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
13996 [(set (match_dup 0) (match_dup 1))
13999 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
14000 rtx elt1 = XVECEXP (operands[1], 0, 1);
14003 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
14007 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
14008 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
14010 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
14011 operands[1] = XVECEXP (operands[1], 0, 0);
14014 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
14016 = GEN_INT (TARGET_LITTLE_ENDIAN
14017 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
14018 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
14021 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
14023 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
14029 [(set (match_operand 0 "arith_reg_dest" "")
14030 (match_operand 1 "sh_const_vec" ""))]
14031 "TARGET_SHMEDIA && reload_completed
14032 && GET_MODE (operands[0]) == GET_MODE (operands[1])
14033 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
14034 [(set (match_dup 0) (match_dup 1))]
14036 rtx v = operands[1];
14037 machine_mode new_mode
14038 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
14040 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
14042 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
14045 (define_expand "movv2hi"
14046 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
14047 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
14050 prepare_move_operands (operands, V2HImode);
14053 (define_insn "movv2hi_i"
14054 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
14055 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14057 && (register_operand (operands[0], V2HImode)
14058 || sh_register_operand (operands[1], V2HImode))"
14065 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14066 (set_attr "length" "4,4,16,4,4")
14067 (set (attr "highpart")
14068 (cond [(match_test "sh_contains_memref_p (insn)")
14069 (const_string "user")]
14070 (const_string "ignore")))])
14072 (define_expand "movv4hi"
14073 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
14074 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
14077 prepare_move_operands (operands, V4HImode);
14080 (define_insn "movv4hi_i"
14081 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
14082 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14084 && (register_operand (operands[0], V4HImode)
14085 || sh_register_operand (operands[1], V4HImode))"
14092 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14093 (set_attr "length" "4,4,16,4,4")
14094 (set_attr "highpart" "depend")])
14096 (define_expand "movv2si"
14097 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
14098 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
14101 prepare_move_operands (operands, V2SImode);
14104 (define_insn "movv2si_i"
14105 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
14106 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14108 && (register_operand (operands[0], V2SImode)
14109 || sh_register_operand (operands[1], V2SImode))"
14116 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14117 (set_attr "length" "4,4,16,4,4")
14118 (set_attr "highpart" "depend")])
14120 ;; -------------------------------------------------------------------------
14121 ;; Multimedia Intrinsics
14122 ;; -------------------------------------------------------------------------
14124 (define_insn "absv2si2"
14125 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14126 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
14129 [(set_attr "type" "mcmp_media")
14130 (set_attr "highpart" "depend")])
14132 (define_insn "absv4hi2"
14133 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14134 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
14137 [(set_attr "type" "mcmp_media")
14138 (set_attr "highpart" "depend")])
14140 (define_insn "addv2si3"
14141 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14142 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
14143 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14145 "madd.l %1, %2, %0"
14146 [(set_attr "type" "arith_media")
14147 (set_attr "highpart" "depend")])
14149 (define_insn "addv4hi3"
14150 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14151 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
14152 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14154 "madd.w %1, %2, %0"
14155 [(set_attr "type" "arith_media")
14156 (set_attr "highpart" "depend")])
14158 (define_insn_and_split "addv2hi3"
14159 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14160 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
14161 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
14167 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14168 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14169 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14170 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14171 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14173 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
14174 emit_insn (gen_truncdisi2 (si_dst, di_dst));
14177 [(set_attr "highpart" "must_split")])
14179 (define_insn "ssaddv2si3"
14180 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14181 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
14182 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14184 "madds.l %1, %2, %0"
14185 [(set_attr "type" "mcmp_media")
14186 (set_attr "highpart" "depend")])
14188 (define_insn "usaddv8qi3"
14189 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14190 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
14191 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14193 "madds.ub %1, %2, %0"
14194 [(set_attr "type" "mcmp_media")
14195 (set_attr "highpart" "depend")])
14197 (define_insn "ssaddv4hi3"
14198 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14199 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
14200 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14202 "madds.w %1, %2, %0"
14203 [(set_attr "type" "mcmp_media")
14204 (set_attr "highpart" "depend")])
14206 (define_insn "negcmpeqv8qi"
14207 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14209 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
14210 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
14212 "mcmpeq.b %N1, %N2, %0"
14213 [(set_attr "type" "mcmp_media")
14214 (set_attr "highpart" "depend")])
14216 (define_insn "negcmpeqv2si"
14217 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14219 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
14220 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14222 "mcmpeq.l %N1, %N2, %0"
14223 [(set_attr "type" "mcmp_media")
14224 (set_attr "highpart" "depend")])
14226 (define_insn "negcmpeqv4hi"
14227 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14229 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
14230 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14232 "mcmpeq.w %N1, %N2, %0"
14233 [(set_attr "type" "mcmp_media")
14234 (set_attr "highpart" "depend")])
14236 (define_insn "negcmpgtuv8qi"
14237 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14238 (neg:V8QI (gtu:V8QI
14239 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
14240 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
14242 "mcmpgt.ub %N1, %N2, %0"
14243 [(set_attr "type" "mcmp_media")
14244 (set_attr "highpart" "depend")])
14246 (define_insn "negcmpgtv2si"
14247 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14249 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
14250 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14252 "mcmpgt.l %N1, %N2, %0"
14253 [(set_attr "type" "mcmp_media")
14254 (set_attr "highpart" "depend")])
14256 (define_insn "negcmpgtv4hi"
14257 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14259 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
14260 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14262 "mcmpgt.w %N1, %N2, %0"
14263 [(set_attr "type" "mcmp_media")
14264 (set_attr "highpart" "depend")])
14266 (define_insn "mcmv"
14267 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14268 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14269 (match_operand:DI 2 "arith_reg_operand" "r"))
14270 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
14271 (not:DI (match_dup 2)))))]
14274 [(set_attr "type" "arith_media")
14275 (set_attr "highpart" "depend")])
14277 (define_insn "mcnvs_lw"
14278 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14280 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
14282 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14284 "mcnvs.lw %N1, %N2, %0"
14285 [(set_attr "type" "mcmp_media")])
14287 (define_insn "mcnvs_wb"
14288 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14290 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14292 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14294 "mcnvs.wb %N1, %N2, %0"
14295 [(set_attr "type" "mcmp_media")])
14297 (define_insn "mcnvs_wub"
14298 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14300 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14302 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14304 "mcnvs.wub %N1, %N2, %0"
14305 [(set_attr "type" "mcmp_media")])
14307 (define_insn "mextr_rl"
14308 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14309 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14310 (match_operand:HI 3 "mextr_bit_offset" "i"))
14311 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14312 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14313 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14315 static char templ[21];
14316 sprintf (templ, "mextr%d %%N1, %%N2, %%0",
14317 (int) INTVAL (operands[3]) >> 3);
14320 [(set_attr "type" "arith_media")])
14322 (define_insn "*mextr_lr"
14323 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14324 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14325 (match_operand:HI 3 "mextr_bit_offset" "i"))
14326 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14327 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14328 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14330 static char templ[21];
14331 sprintf (templ, "mextr%d %%N2, %%N1, %%0",
14332 (int) INTVAL (operands[4]) >> 3);
14335 [(set_attr "type" "arith_media")])
14337 ; mextrN can be modelled with vec_select / vec_concat, but the selection
14338 ; vector then varies depending on endianness.
14339 (define_expand "mextr1"
14340 [(match_operand:DI 0 "arith_reg_dest" "")
14341 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14342 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14345 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14346 GEN_INT (1 * 8), GEN_INT (7 * 8)));
14350 (define_expand "mextr2"
14351 [(match_operand:DI 0 "arith_reg_dest" "")
14352 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14353 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14356 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14357 GEN_INT (2 * 8), GEN_INT (6 * 8)));
14361 (define_expand "mextr3"
14362 [(match_operand:DI 0 "arith_reg_dest" "")
14363 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14364 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14367 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14368 GEN_INT (3 * 8), GEN_INT (5 * 8)));
14372 (define_expand "mextr4"
14373 [(match_operand:DI 0 "arith_reg_dest" "")
14374 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14375 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14378 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14379 GEN_INT (4 * 8), GEN_INT (4 * 8)));
14383 (define_expand "mextr5"
14384 [(match_operand:DI 0 "arith_reg_dest" "")
14385 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14386 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14389 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14390 GEN_INT (5 * 8), GEN_INT (3 * 8)));
14394 (define_expand "mextr6"
14395 [(match_operand:DI 0 "arith_reg_dest" "")
14396 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14397 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14400 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14401 GEN_INT (6 * 8), GEN_INT (2 * 8)));
14405 (define_expand "mextr7"
14406 [(match_operand:DI 0 "arith_reg_dest" "")
14407 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14408 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14411 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14412 GEN_INT (7 * 8), GEN_INT (1 * 8)));
14416 (define_expand "mmacfx_wl"
14417 [(match_operand:V2SI 0 "arith_reg_dest" "")
14418 (match_operand:V2HI 1 "extend_reg_operand" "")
14419 (match_operand:V2HI 2 "extend_reg_operand" "")
14420 (match_operand:V2SI 3 "arith_reg_operand" "")]
14423 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
14424 operands[1], operands[2]));
14428 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
14430 (define_insn "mmacfx_wl_i"
14431 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14433 (match_operand:V2SI 1 "arith_reg_operand" "0")
14438 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14439 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14442 "mmacfx.wl %2, %3, %0"
14443 [(set_attr "type" "mac_media")
14444 (set_attr "highpart" "depend")])
14446 (define_expand "mmacnfx_wl"
14447 [(match_operand:V2SI 0 "arith_reg_dest" "")
14448 (match_operand:V2HI 1 "extend_reg_operand" "")
14449 (match_operand:V2HI 2 "extend_reg_operand" "")
14450 (match_operand:V2SI 3 "arith_reg_operand" "")]
14453 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
14454 operands[1], operands[2]));
14458 (define_insn "mmacnfx_wl_i"
14459 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14461 (match_operand:V2SI 1 "arith_reg_operand" "0")
14466 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14467 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14470 "mmacnfx.wl %2, %3, %0"
14471 [(set_attr "type" "mac_media")
14472 (set_attr "highpart" "depend")])
14474 (define_insn "mulv2si3"
14475 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14476 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14477 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14479 "mmul.l %1, %2, %0"
14480 [(set_attr "type" "d2mpy_media")
14481 (set_attr "highpart" "depend")])
14483 (define_insn "mulv4hi3"
14484 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14485 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14486 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14488 "mmul.w %1, %2, %0"
14489 [(set_attr "type" "dmpy_media")
14490 (set_attr "highpart" "depend")])
14492 (define_insn "mmulfx_l"
14493 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14497 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14498 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
14501 "mmulfx.l %1, %2, %0"
14502 [(set_attr "type" "d2mpy_media")
14503 (set_attr "highpart" "depend")])
14505 (define_insn "mmulfx_w"
14506 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14510 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14511 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14514 "mmulfx.w %1, %2, %0"
14515 [(set_attr "type" "dmpy_media")
14516 (set_attr "highpart" "depend")])
14518 (define_insn "mmulfxrp_w"
14519 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14524 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14525 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14529 "mmulfxrp.w %1, %2, %0"
14530 [(set_attr "type" "dmpy_media")
14531 (set_attr "highpart" "depend")])
14534 (define_expand "mmulhi_wl"
14535 [(match_operand:V2SI 0 "arith_reg_dest" "")
14536 (match_operand:V4HI 1 "arith_reg_operand" "")
14537 (match_operand:V4HI 2 "arith_reg_operand" "")]
14540 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
14541 (operands[0], operands[1], operands[2]));
14545 (define_expand "mmullo_wl"
14546 [(match_operand:V2SI 0 "arith_reg_dest" "")
14547 (match_operand:V4HI 1 "arith_reg_operand" "")
14548 (match_operand:V4HI 2 "arith_reg_operand" "")]
14551 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14552 (operands[0], operands[1], operands[2]));
14556 (define_insn "mmul23_wl"
14557 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14560 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14561 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14562 (parallel [(const_int 2) (const_int 3)])))]
14565 return (TARGET_LITTLE_ENDIAN
14566 ? "mmulhi.wl %1, %2, %0"
14567 : "mmullo.wl %1, %2, %0");
14569 [(set_attr "type" "dmpy_media")
14570 (set (attr "highpart")
14571 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14572 (const_string "user")))])
14574 (define_insn "mmul01_wl"
14575 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14578 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14579 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14580 (parallel [(const_int 0) (const_int 1)])))]
14583 return (TARGET_LITTLE_ENDIAN
14584 ? "mmullo.wl %1, %2, %0"
14585 : "mmulhi.wl %1, %2, %0");
14587 [(set_attr "type" "dmpy_media")
14588 (set (attr "highpart")
14589 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14590 (const_string "user")))])
14593 (define_expand "mmulsum_wq"
14594 [(match_operand:DI 0 "arith_reg_dest" "")
14595 (match_operand:V4HI 1 "arith_reg_operand" "")
14596 (match_operand:V4HI 2 "arith_reg_operand" "")
14597 (match_operand:DI 3 "arith_reg_operand" "")]
14600 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14601 operands[1], operands[2]));
14605 (define_insn "mmulsum_wq_i"
14606 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14607 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14612 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14613 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14614 (parallel [(const_int 0)]))
14615 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14616 (sign_extend:V4DI (match_dup 3)))
14617 (parallel [(const_int 1)])))
14619 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14620 (sign_extend:V4DI (match_dup 3)))
14621 (parallel [(const_int 2)]))
14622 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14623 (sign_extend:V4DI (match_dup 3)))
14624 (parallel [(const_int 3)]))))))]
14626 "mmulsum.wq %2, %3, %0"
14627 [(set_attr "type" "mac_media")])
14629 (define_expand "mperm_w"
14630 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14631 (match_operand:V4HI 1 "arith_reg_operand" "r")
14632 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14635 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14636 (operands[0], operands[1], operands[2]));
14640 ; This use of vec_select isn't exactly correct according to rtl.texi
14641 ; (because not constant), but it seems a straightforward extension.
14642 (define_insn "mperm_w_little"
14643 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14645 (match_operand:V4HI 1 "arith_reg_operand" "r")
14647 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14648 (const_int 2) (const_int 0))
14649 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14650 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14651 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14652 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14653 "mperm.w %1, %N2, %0"
14654 [(set_attr "type" "arith_media")])
14656 (define_insn "mperm_w_big"
14657 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14659 (match_operand:V4HI 1 "arith_reg_operand" "r")
14661 [(zero_extract:QI (not:QI (match_operand:QI 2
14662 "extend_reg_or_0_operand" "rZ"))
14663 (const_int 2) (const_int 0))
14664 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14665 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14666 (zero_extract:QI (not:QI (match_dup 2))
14667 (const_int 2) (const_int 6))])))]
14668 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
14669 "mperm.w %1, %N2, %0"
14670 [(set_attr "type" "arith_media")])
14672 (define_insn "mperm_w0"
14673 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14674 (vec_duplicate:V4HI (truncate:HI (match_operand 1
14675 "trunc_hi_operand" "r"))))]
14677 "mperm.w %1, r63, %0"
14678 [(set_attr "type" "arith_media")
14679 (set_attr "highpart" "ignore")])
14681 (define_expand "msad_ubq"
14682 [(match_operand:DI 0 "arith_reg_dest" "")
14683 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14684 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14685 (match_operand:DI 3 "arith_reg_operand" "")]
14688 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14689 operands[1], operands[2]));
14693 (define_insn "msad_ubq_i"
14694 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14699 (match_operand:DI 1 "arith_reg_operand" "0")
14700 (abs:DI (vec_select:DI
14703 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14705 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14706 (parallel [(const_int 0)]))))
14707 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14708 (zero_extend:V8DI (match_dup 3)))
14709 (parallel [(const_int 1)]))))
14711 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14712 (zero_extend:V8DI (match_dup 3)))
14713 (parallel [(const_int 2)])))
14714 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14715 (zero_extend:V8DI (match_dup 3)))
14716 (parallel [(const_int 3)])))))
14719 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14720 (zero_extend:V8DI (match_dup 3)))
14721 (parallel [(const_int 4)])))
14722 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14723 (zero_extend:V8DI (match_dup 3)))
14724 (parallel [(const_int 5)]))))
14726 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14727 (zero_extend:V8DI (match_dup 3)))
14728 (parallel [(const_int 6)])))
14729 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14730 (zero_extend:V8DI (match_dup 3)))
14731 (parallel [(const_int 7)])))))))]
14733 "msad.ubq %N2, %N3, %0"
14734 [(set_attr "type" "mac_media")])
14736 (define_insn "mshalds_l"
14737 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14740 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14741 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14742 (const_int 31)))))]
14744 "mshalds.l %1, %2, %0"
14745 [(set_attr "type" "mcmp_media")
14746 (set_attr "highpart" "depend")])
14748 (define_insn "mshalds_w"
14749 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14752 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14753 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14754 (const_int 15)))))]
14756 "mshalds.w %1, %2, %0"
14757 [(set_attr "type" "mcmp_media")
14758 (set_attr "highpart" "depend")])
14760 (define_insn "ashrv2si3"
14761 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14762 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14763 (match_operand:DI 2 "arith_reg_operand" "r")))]
14765 "mshard.l %1, %2, %0"
14766 [(set_attr "type" "arith_media")
14767 (set_attr "highpart" "depend")])
14769 (define_insn "ashrv4hi3"
14770 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14771 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14772 (match_operand:DI 2 "arith_reg_operand" "r")))]
14774 "mshard.w %1, %2, %0"
14775 [(set_attr "type" "arith_media")
14776 (set_attr "highpart" "depend")])
14778 (define_insn "mshards_q"
14779 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14781 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14782 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14784 "mshards.q %1, %N2, %0"
14785 [(set_attr "type" "mcmp_media")])
14787 (define_expand "mshfhi_b"
14788 [(match_operand:V8QI 0 "arith_reg_dest" "")
14789 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14790 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14793 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14794 (operands[0], operands[1], operands[2]));
14798 (define_expand "mshflo_b"
14799 [(match_operand:V8QI 0 "arith_reg_dest" "")
14800 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14801 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14804 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14805 (operands[0], operands[1], operands[2]));
14809 (define_insn "mshf4_b"
14811 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14813 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14814 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14815 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14816 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14819 return (TARGET_LITTLE_ENDIAN
14820 ? "mshfhi.b %N1, %N2, %0"
14821 : "mshflo.b %N1, %N2, %0");
14823 [(set_attr "type" "arith_media")
14824 (set (attr "highpart")
14825 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14826 (const_string "user")))])
14828 (define_insn "mshf0_b"
14830 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14832 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14833 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14834 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14835 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14838 return (TARGET_LITTLE_ENDIAN
14839 ? "mshflo.b %N1, %N2, %0"
14840 : "mshfhi.b %N1, %N2, %0");
14842 [(set_attr "type" "arith_media")
14843 (set (attr "highpart")
14844 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14845 (const_string "user")))])
14847 (define_expand "mshfhi_l"
14848 [(match_operand:V2SI 0 "arith_reg_dest" "")
14849 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14850 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14853 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14854 (operands[0], operands[1], operands[2]));
14858 (define_expand "mshflo_l"
14859 [(match_operand:V2SI 0 "arith_reg_dest" "")
14860 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14861 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14864 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14865 (operands[0], operands[1], operands[2]));
14869 (define_insn "mshf4_l"
14870 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14872 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14873 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14874 (parallel [(const_int 1) (const_int 3)])))]
14877 return (TARGET_LITTLE_ENDIAN
14878 ? "mshfhi.l %N1, %N2, %0"
14879 : "mshflo.l %N1, %N2, %0");
14881 [(set_attr "type" "arith_media")
14882 (set (attr "highpart")
14883 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14884 (const_string "user")))])
14886 (define_insn "mshf0_l"
14887 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14889 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14890 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14891 (parallel [(const_int 0) (const_int 2)])))]
14894 return (TARGET_LITTLE_ENDIAN
14895 ? "mshflo.l %N1, %N2, %0"
14896 : "mshfhi.l %N1, %N2, %0");
14898 [(set_attr "type" "arith_media")
14899 (set (attr "highpart")
14900 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14901 (const_string "user")))])
14903 (define_expand "mshfhi_w"
14904 [(match_operand:V4HI 0 "arith_reg_dest" "")
14905 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14906 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14909 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14910 (operands[0], operands[1], operands[2]));
14914 (define_expand "mshflo_w"
14915 [(match_operand:V4HI 0 "arith_reg_dest" "")
14916 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14917 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14920 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14921 (operands[0], operands[1], operands[2]));
14925 (define_insn "mshf4_w"
14926 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14928 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14929 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14930 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
14933 return (TARGET_LITTLE_ENDIAN
14934 ? "mshfhi.w %N1, %N2, %0"
14935 : "mshflo.w %N1, %N2, %0");
14937 [(set_attr "type" "arith_media")
14938 (set (attr "highpart")
14939 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14940 (const_string "user")))])
14942 (define_insn "mshf0_w"
14943 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14945 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14946 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14947 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
14950 return (TARGET_LITTLE_ENDIAN
14951 ? "mshflo.w %N1, %N2, %0"
14952 : "mshfhi.w %N1, %N2, %0");
14954 [(set_attr "type" "arith_media")
14955 (set (attr "highpart")
14956 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14957 (const_string "user")))])
14959 (define_insn "mshflo_w_x"
14960 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14962 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
14963 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
14964 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
14966 "mshflo.w %N1, %N2, %0"
14967 [(set_attr "type" "arith_media")
14968 (set_attr "highpart" "ignore")])
14970 ;; These are useful to expand ANDs and as combiner patterns.
14971 (define_insn_and_split "mshfhi_l_di"
14972 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
14973 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
14975 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
14976 (const_int -4294967296))))]
14979 mshfhi.l %N1, %N2, %0
14981 "TARGET_SHMEDIA && reload_completed
14982 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14983 [(set (match_dup 3) (match_dup 4))
14984 (set (match_dup 5) (match_dup 6))]
14986 operands[3] = gen_lowpart (SImode, operands[0]);
14987 operands[4] = gen_highpart (SImode, operands[1]);
14988 operands[5] = gen_highpart (SImode, operands[0]);
14989 operands[6] = gen_highpart (SImode, operands[2]);
14991 [(set_attr "type" "arith_media")])
14993 (define_insn "*mshfhi_l_di_rev"
14994 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14995 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14996 (const_int -4294967296))
14997 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15000 "mshfhi.l %N2, %N1, %0"
15001 [(set_attr "type" "arith_media")])
15004 [(set (match_operand:DI 0 "arith_reg_dest" "")
15005 (ior:DI (zero_extend:DI (match_operand:SI 1
15006 "extend_reg_or_0_operand" ""))
15007 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
15008 (const_int -4294967296))))
15009 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
15013 emit_insn (gen_ashldi3_media (operands[3],
15014 simplify_gen_subreg (DImode, operands[1],
15017 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
15021 (define_insn "mshflo_l_di"
15022 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15023 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15024 (const_int 4294967295))
15025 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15029 "mshflo.l %N1, %N2, %0"
15030 [(set_attr "type" "arith_media")
15031 (set_attr "highpart" "ignore")])
15033 (define_insn "*mshflo_l_di_rev"
15034 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15035 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15037 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15038 (const_int 4294967295))))]
15041 "mshflo.l %N2, %N1, %0"
15042 [(set_attr "type" "arith_media")
15043 (set_attr "highpart" "ignore")])
15045 ;; Combiner pattern for trampoline initialization.
15046 (define_insn_and_split "*double_shori"
15047 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15048 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
15050 (match_operand:DI 2 "const_int_operand" "n")))]
15052 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
15054 "rtx_equal_p (operands[0], operands[1])"
15057 HOST_WIDE_INT v = INTVAL (operands[2]);
15059 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
15060 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
15063 [(set_attr "highpart" "ignore")])
15065 (define_insn "*mshflo_l_di_x"
15066 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15067 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
15069 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15072 "mshflo.l %N1, %N2, %0"
15073 [(set_attr "type" "arith_media")
15074 (set_attr "highpart" "ignore")])
15076 (define_insn_and_split "concat_v2sf"
15077 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
15078 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
15079 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
15080 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
15083 mshflo.l %N1, %N2, %0
15086 "TARGET_SHMEDIA && reload_completed
15087 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
15088 [(set (match_dup 3) (match_dup 1))
15089 (set (match_dup 4) (match_dup 2))]
15091 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
15092 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
15094 [(set_attr "type" "arith_media")
15095 (set_attr "highpart" "ignore")])
15097 (define_insn "*mshflo_l_di_x_rev"
15098 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15099 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15102 (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
15104 "mshflo.l %N2, %N1, %0"
15105 [(set_attr "type" "arith_media")
15106 (set_attr "highpart" "ignore")])
15108 (define_insn "ashlv2si3"
15109 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15110 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15111 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15113 "mshlld.l %1, %2, %0"
15114 [(set_attr "type" "arith_media")
15115 (set_attr "highpart" "depend")])
15118 [(set (match_operand 0 "any_register_operand" "")
15119 (match_operator 3 "shift_operator"
15120 [(match_operand 1 "any_register_operand" "")
15121 (match_operand 2 "shift_count_reg_operand" "")]))]
15122 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
15123 [(set (match_dup 0) (match_dup 3))]
15125 rtx count = operands[2];
15126 machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
15128 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
15129 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
15130 || GET_CODE (count) == TRUNCATE)
15131 count = XEXP (count, 0);
15132 inner_mode = GET_MODE (count);
15133 count = simplify_gen_subreg (outer_mode, count, inner_mode,
15134 subreg_lowpart_offset (outer_mode, inner_mode));
15135 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
15136 operands[1], count);
15139 (define_insn "ashlv4hi3"
15140 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15141 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15142 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15144 "mshlld.w %1, %2, %0"
15145 [(set_attr "type" "arith_media")
15146 (set_attr "highpart" "depend")])
15148 (define_insn "lshrv2si3"
15149 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15150 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15151 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15153 "mshlrd.l %1, %2, %0"
15154 [(set_attr "type" "arith_media")
15155 (set_attr "highpart" "depend")])
15157 (define_insn "lshrv4hi3"
15158 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15159 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15160 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15162 "mshlrd.w %1, %2, %0"
15163 [(set_attr "type" "arith_media")
15164 (set_attr "highpart" "depend")])
15166 (define_insn "subv2si3"
15167 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15168 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15169 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15171 "msub.l %N1, %2, %0"
15172 [(set_attr "type" "arith_media")
15173 (set_attr "highpart" "depend")])
15175 (define_insn "subv4hi3"
15176 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15177 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15178 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15180 "msub.w %N1, %2, %0"
15181 [(set_attr "type" "arith_media")
15182 (set_attr "highpart" "depend")])
15184 (define_insn_and_split "subv2hi3"
15185 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
15186 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
15187 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
15193 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
15194 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
15195 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
15196 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
15197 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
15199 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
15200 emit_insn (gen_truncdisi2 (si_dst, di_dst));
15203 [(set_attr "highpart" "must_split")])
15205 (define_insn "sssubv2si3"
15206 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15207 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15208 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15210 "msubs.l %N1, %2, %0"
15211 [(set_attr "type" "mcmp_media")
15212 (set_attr "highpart" "depend")])
15214 (define_insn "ussubv8qi3"
15215 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15216 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15217 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
15219 "msubs.ub %N1, %2, %0"
15220 [(set_attr "type" "mcmp_media")
15221 (set_attr "highpart" "depend")])
15223 (define_insn "sssubv4hi3"
15224 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15225 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15226 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15228 "msubs.w %N1, %2, %0"
15229 [(set_attr "type" "mcmp_media")
15230 (set_attr "highpart" "depend")])
15232 ;; -------------------------------------------------------------------------
15233 ;; Floating Point Intrinsics
15234 ;; -------------------------------------------------------------------------
15236 (define_insn "fcosa_s"
15237 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15238 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
15242 [(set_attr "type" "atrans_media")])
15244 (define_insn "fsina_s"
15245 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15246 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
15250 [(set_attr "type" "atrans_media")])
15252 (define_insn "fipr"
15253 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15254 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
15255 "fp_arith_reg_operand" "f")
15256 (match_operand:V4SF 2
15257 "fp_arith_reg_operand" "f"))
15258 (parallel [(const_int 0)]))
15259 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15260 (parallel [(const_int 1)])))
15261 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15262 (parallel [(const_int 2)]))
15263 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15264 (parallel [(const_int 3)])))))]
15266 "fipr.s %1, %2, %0"
15267 [(set_attr "type" "fparith_media")])
15269 (define_insn "fsrra_s"
15270 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15271 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
15275 [(set_attr "type" "atrans_media")])
15277 (define_insn "ftrv"
15278 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
15282 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
15283 (parallel [(const_int 0) (const_int 5)
15284 (const_int 10) (const_int 15)]))
15285 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
15287 (vec_select:V4SF (match_dup 1)
15288 (parallel [(const_int 4) (const_int 9)
15289 (const_int 14) (const_int 3)]))
15290 (vec_select:V4SF (match_dup 2)
15291 (parallel [(const_int 1) (const_int 2)
15292 (const_int 3) (const_int 0)]))))
15295 (vec_select:V4SF (match_dup 1)
15296 (parallel [(const_int 8) (const_int 13)
15297 (const_int 2) (const_int 7)]))
15298 (vec_select:V4SF (match_dup 2)
15299 (parallel [(const_int 2) (const_int 3)
15300 (const_int 0) (const_int 1)])))
15302 (vec_select:V4SF (match_dup 1)
15303 (parallel [(const_int 12) (const_int 1)
15304 (const_int 6) (const_int 11)]))
15305 (vec_select:V4SF (match_dup 2)
15306 (parallel [(const_int 3) (const_int 0)
15307 (const_int 1) (const_int 2)]))))))]
15309 "ftrv.s %1, %2, %0"
15310 [(set_attr "type" "fparith_media")])
15312 (define_insn "ldhi_l"
15313 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15315 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15318 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
15322 [(set_attr "type" "load_media")])
15324 (define_insn "ldhi_q"
15325 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15327 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15330 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
15334 [(set_attr "type" "load_media")])
15336 (define_insn_and_split "*ldhi_q_comb0"
15337 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15339 (mem:DI (plus:SI (ior:SI (plus:SI
15340 (match_operand:SI 1 "register_operand" "r")
15341 (match_operand:SI 2 "ua_offset" "I06"))
15344 (plus:SI (and:SI (match_dup 1) (const_int 7))
15347 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15352 emit_insn (gen_ldhi_q (operands[0],
15353 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15357 (define_insn_and_split "*ldhi_q_comb1"
15358 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15360 (mem:DI (plus:SI (ior:SI (plus:SI
15361 (match_operand:SI 1 "register_operand" "r")
15362 (match_operand:SI 2 "ua_offset" "I06"))
15365 (plus:SI (and:SI (plus:SI (match_dup 1)
15366 (match_operand:SI 3 "ua_offset" "I06"))
15370 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15371 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15376 emit_insn (gen_ldhi_q (operands[0],
15377 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15381 (define_insn "ldlo_l"
15382 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15384 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15386 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
15387 (and:SI (match_dup 1) (const_int 3))))]
15390 [(set_attr "type" "load_media")])
15392 (define_insn "ldlo_q"
15393 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15395 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15397 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15398 (and:SI (match_dup 1) (const_int 7))))]
15401 [(set_attr "type" "load_media")])
15403 (define_insn_and_split "*ldlo_q_comb0"
15404 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15406 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15407 (match_operand:SI 2 "ua_offset" "I06"))
15409 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15410 (and:SI (match_dup 1) (const_int 7))))]
15411 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15416 emit_insn (gen_ldlo_q (operands[0],
15417 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15421 (define_insn_and_split "*ldlo_q_comb1"
15422 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15424 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15425 (match_operand:SI 2 "ua_offset" "I06"))
15427 (minus:SI (const_int 8)
15428 (and:SI (plus:SI (match_dup 1)
15429 (match_operand:SI 3 "ua_offset" "I06"))
15431 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
15432 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15433 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15438 emit_insn (gen_ldlo_q (operands[0],
15439 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15443 (define_insn "sthi_l"
15444 [(set (zero_extract:SI
15445 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15448 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
15450 (match_operand:SI 1 "arith_reg_operand" "r"))]
15453 [(set_attr "type" "ustore_media")])
15455 ;; All unaligned stores are considered to be 'narrow' because they typically
15456 ;; operate on less that a quadword, and when they operate on a full quadword,
15457 ;; the vanilla store high / store low sequence will cause a stall if not
15458 ;; scheduled apart.
15459 (define_insn "sthi_q"
15460 [(set (zero_extract:DI
15461 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15464 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15466 (match_operand:DI 1 "arith_reg_operand" "r"))]
15469 [(set_attr "type" "ustore_media")])
15471 (define_insn_and_split "*sthi_q_comb0"
15472 [(set (zero_extract:DI
15473 (mem:DI (plus:SI (ior:SI (plus:SI
15474 (match_operand:SI 0 "register_operand" "r")
15475 (match_operand:SI 1 "ua_offset" "I06"))
15478 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15480 (match_operand:DI 2 "arith_reg_operand" "r"))]
15481 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15486 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15491 (define_insn_and_split "*sthi_q_comb1"
15492 [(set (zero_extract:DI
15493 (mem:DI (plus:SI (ior:SI (plus:SI
15494 (match_operand:SI 0 "register_operand" "r")
15495 (match_operand:SI 1 "ua_offset" "I06"))
15498 (plus:SI (and:SI (plus:SI (match_dup 0)
15499 (match_operand:SI 2 "ua_offset" "I06"))
15503 (match_operand:DI 3 "arith_reg_operand" "r"))]
15504 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
15505 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15510 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15515 ;; This is highpart user because the address is used as full 64 bit.
15516 (define_insn "stlo_l"
15517 [(set (zero_extract:SI
15518 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15520 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
15521 (and:SI (match_dup 0) (const_int 3)))
15522 (match_operand:SI 1 "arith_reg_operand" "r"))]
15525 [(set_attr "type" "ustore_media")])
15527 (define_insn "stlo_q"
15528 [(set (zero_extract:DI
15529 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15531 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15532 (and:SI (match_dup 0) (const_int 7)))
15533 (match_operand:DI 1 "arith_reg_operand" "r"))]
15536 [(set_attr "type" "ustore_media")])
15538 (define_insn_and_split "*stlo_q_comb0"
15539 [(set (zero_extract:DI
15540 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15541 (match_operand:SI 1 "ua_offset" "I06"))
15543 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15544 (and:SI (match_dup 0) (const_int 7)))
15545 (match_operand:DI 2 "arith_reg_operand" "r"))]
15546 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15551 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15556 (define_insn_and_split "*stlo_q_comb1"
15557 [(set (zero_extract:DI
15558 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15559 (match_operand:SI 1 "ua_offset" "I06"))
15561 (minus:SI (const_int 8)
15562 (and:SI (plus:SI (match_dup 0)
15563 (match_operand:SI 2 "ua_offset" "I06"))
15565 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15566 (match_operand:DI 3 "arith_reg_operand" "r"))]
15567 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15572 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15577 (define_insn "ldhi_l64"
15578 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15580 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15583 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15587 [(set_attr "type" "load_media")])
15589 (define_insn "ldhi_q64"
15590 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15592 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15595 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15599 [(set_attr "type" "load_media")])
15601 (define_insn "ldlo_l64"
15602 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15604 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15606 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15607 (and:DI (match_dup 1) (const_int 3))))]
15610 [(set_attr "type" "load_media")])
15612 (define_insn "ldlo_q64"
15613 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15615 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15617 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15618 (and:DI (match_dup 1) (const_int 7))))]
15621 [(set_attr "type" "load_media")])
15623 (define_insn "sthi_l64"
15624 [(set (zero_extract:SI
15625 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15628 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15630 (match_operand:SI 1 "arith_reg_operand" "r"))]
15633 [(set_attr "type" "ustore_media")])
15635 (define_insn "sthi_q64"
15636 [(set (zero_extract:DI
15637 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15640 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15642 (match_operand:DI 1 "arith_reg_operand" "r"))]
15645 [(set_attr "type" "ustore_media")])
15647 (define_insn "stlo_l64"
15648 [(set (zero_extract:SI
15649 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15651 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15652 (and:DI (match_dup 0) (const_int 3)))
15653 (match_operand:SI 1 "arith_reg_operand" "r"))]
15656 [(set_attr "type" "ustore_media")])
15658 (define_insn "stlo_q64"
15659 [(set (zero_extract:DI
15660 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15662 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15663 (and:DI (match_dup 0) (const_int 7)))
15664 (match_operand:DI 1 "arith_reg_operand" "r"))]
15667 [(set_attr "type" "ustore_media")])
15670 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15671 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15675 [(set_attr "type" "arith_media")])
15677 (define_insn "nsbsi"
15678 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15680 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15684 [(set_attr "type" "arith_media")])
15686 (define_insn "nsbdi"
15687 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15689 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15693 [(set_attr "type" "arith_media")])
15695 (define_expand "ffsdi2"
15696 [(set (match_operand:DI 0 "arith_reg_dest" "")
15697 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15700 rtx scratch = gen_reg_rtx (DImode);
15703 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15704 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15705 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15706 emit_insn (gen_nsbdi (scratch, scratch));
15707 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15708 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15709 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15710 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15715 (define_expand "ffssi2"
15716 [(set (match_operand:SI 0 "arith_reg_dest" "")
15717 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15720 rtx scratch = gen_reg_rtx (SImode);
15721 rtx discratch = gen_reg_rtx (DImode);
15724 emit_insn (gen_adddi3 (discratch,
15725 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15727 emit_insn (gen_andcdi3 (discratch,
15728 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15730 emit_insn (gen_nsbsi (scratch, discratch));
15731 last = emit_insn (gen_subsi3 (operands[0],
15732 force_reg (SImode, GEN_INT (63)), scratch));
15733 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15738 (define_insn "byterev"
15739 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15740 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15741 (parallel [(const_int 7) (const_int 6) (const_int 5)
15742 (const_int 4) (const_int 3) (const_int 2)
15743 (const_int 1) (const_int 0)])))]
15746 [(set_attr "type" "arith_media")])
15748 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15749 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
15750 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15751 (define_expand "prefetch"
15752 [(prefetch (match_operand 0 "address_operand" "")
15753 (match_operand:SI 1 "const_int_operand" "")
15754 (match_operand:SI 2 "const_int_operand" ""))]
15755 "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15756 && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15758 (define_insn "*prefetch"
15759 [(prefetch (match_operand:SI 0 "register_operand" "r")
15760 (match_operand:SI 1 "const_int_operand" "n")
15761 (match_operand:SI 2 "const_int_operand" "n"))]
15762 "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15764 [(set_attr "type" "other")])
15766 (define_insn "*prefetch_media"
15767 [(prefetch (match_operand:QI 0 "address_operand" "p")
15768 (match_operand:SI 1 "const_int_operand" "n")
15769 (match_operand:SI 2 "const_int_operand" "n"))]
15772 operands[0] = gen_rtx_MEM (QImode, operands[0]);
15773 output_asm_insn ("ld%M0.b %m0,r63", operands);
15776 [(set_attr "type" "other")])
15778 (define_insn "alloco_i"
15779 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15780 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15785 if (GET_CODE (operands[0]) == PLUS)
15787 xops[0] = XEXP (operands[0], 0);
15788 xops[1] = XEXP (operands[0], 1);
15792 xops[0] = operands[0];
15793 xops[1] = const0_rtx;
15795 output_asm_insn ("alloco %0, %1", xops);
15798 [(set_attr "type" "other")])
15801 [(set (match_operand 0 "any_register_operand" "")
15802 (match_operand 1 "" ""))]
15803 "TARGET_SHMEDIA && reload_completed"
15804 [(set (match_dup 0) (match_dup 1))]
15806 if (!shmedia_cleanup_truncate (operands[1]))
15810 ;; -------------------------------------------------------------------------
15811 ;; Stack Protector Patterns
15812 ;; -------------------------------------------------------------------------
15814 (define_expand "stack_protect_set"
15815 [(set (match_operand 0 "memory_operand" "")
15816 (match_operand 1 "memory_operand" ""))]
15819 if (TARGET_SHMEDIA)
15821 if (TARGET_SHMEDIA64)
15822 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15824 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15827 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15832 (define_insn "stack_protect_set_si"
15833 [(set (match_operand:SI 0 "memory_operand" "=m")
15834 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15835 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15838 return "mov.l %1,%2" "\n"
15839 " mov.l %2,%0" "\n"
15842 [(set_attr "type" "other")
15843 (set_attr "length" "6")])
15845 (define_insn "stack_protect_set_si_media"
15846 [(set (match_operand:SI 0 "memory_operand" "=m")
15847 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15848 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15851 return "ld%M1.l %m1,%2" "\n"
15852 " st%M0.l %m0,%2" "\n"
15855 [(set_attr "type" "other")
15856 (set_attr "length" "12")])
15858 (define_insn "stack_protect_set_di_media"
15859 [(set (match_operand:DI 0 "memory_operand" "=m")
15860 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15861 (set (match_scratch:DI 2 "=&r") (const_int 0))]
15864 return "ld%M1.q %m1,%2" "\n"
15865 " st%M0.q %m0,%2" "\n"
15868 [(set_attr "type" "other")
15869 (set_attr "length" "12")])
15871 (define_expand "stack_protect_test"
15872 [(match_operand 0 "memory_operand" "")
15873 (match_operand 1 "memory_operand" "")
15874 (match_operand 2 "" "")]
15877 if (TARGET_SHMEDIA)
15879 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15882 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15883 if (TARGET_SHMEDIA64)
15885 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15887 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15891 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15893 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15898 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15899 emit_jump_insn (gen_branch_true (operands[2]));
15905 (define_insn "stack_protect_test_si"
15906 [(set (reg:SI T_REG)
15907 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15908 (match_operand:SI 1 "memory_operand" "m")]
15910 (set (match_scratch:SI 2 "=&r") (const_int 0))
15911 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15914 return "mov.l %0,%2" "\n"
15915 " mov.l %1,%3" "\n"
15916 " cmp/eq %2,%3" "\n"
15920 [(set_attr "type" "other")
15921 (set_attr "length" "10")])
15923 (define_insn "stack_protect_test_si_media"
15924 [(set (match_operand:SI 0 "register_operand" "=&r")
15925 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15926 (match_operand:SI 2 "memory_operand" "m")]
15928 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15931 return "ld%M1.l %m1,%0" "\n"
15932 " ld%M2.l %m2,%3" "\n"
15933 " cmpeq %0,%3,%0" "\n"
15936 [(set_attr "type" "other")
15937 (set_attr "length" "16")])
15939 (define_insn "stack_protect_test_di_media"
15940 [(set (match_operand:DI 0 "register_operand" "=&r")
15941 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
15942 (match_operand:DI 2 "memory_operand" "m")]
15944 (set (match_scratch:DI 3 "=&r") (const_int 0))]
15947 return "ld%M1.q %m1,%0" "\n"
15948 " ld%M2.q %m2,%3" "\n"
15949 " cmpeq %0,%3,%0" "\n"
15952 [(set_attr "type" "other")
15953 (set_attr "length" "16")])
15955 ;; -------------------------------------------------------------------------
15956 ;; Atomic operations
15957 ;; -------------------------------------------------------------------------
15959 (include "sync.md")