1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993-2015 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.
165 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
166 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
169 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
171 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
174 UNSPEC_BUILTIN_STRLEN
177 (define_c_enum "unspecv" [
178 ;; These are used with unspec_volatile.
195 ;; -------------------------------------------------------------------------
197 ;; -------------------------------------------------------------------------
202 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
203 (const (symbol_ref "sh_cpu_attr")))
205 (define_attr "endian" "big,little"
206 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
207 (const_string "little") (const_string "big"))))
209 ;; Indicate if the default fpu mode is single precision.
210 (define_attr "fpu_single" "yes,no"
211 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
212 (const_string "yes") (const_string "no"))))
214 (define_attr "fmovd" "yes,no"
215 (const (if_then_else (symbol_ref "TARGET_FMOVD")
216 (const_string "yes") (const_string "no"))))
218 (define_attr "pipe_model" "sh1,sh4,sh5media"
220 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
221 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
222 (const_string "sh1"))))
224 ;; cbranch conditional branch instructions
225 ;; jump unconditional jumps
226 ;; arith ordinary arithmetic
227 ;; arith3 a compound insn that behaves similarly to a sequence of
228 ;; three insns of type arith
229 ;; arith3b like above, but might end with a redirected branch
231 ;; load_si Likewise, SImode variant for general register.
232 ;; fload Likewise, but load to fp register.
234 ;; fstore floating point register to memory
235 ;; move general purpose register to register
236 ;; movi8 8-bit immediate to general purpose register
237 ;; mt_group other sh4 mt instructions
238 ;; fmove register to register, floating point
239 ;; smpy word precision integer multiply
240 ;; dmpy longword or doublelongword precision integer multiply
242 ;; pload load of pr reg, which can't be put into delay slot of rts
243 ;; prset copy register to pr reg, ditto
244 ;; pstore store of pr reg, which can't be put into delay slot of jsr
245 ;; prget copy pr to register, ditto
246 ;; pcload pc relative load of constant value
247 ;; pcfload Likewise, but load to fp register.
248 ;; pcload_si Likewise, SImode variant for general register.
249 ;; rte return from exception
250 ;; sfunc special function call with known used registers
251 ;; call function call
253 ;; fpscr_toggle toggle a bit in the fpscr
254 ;; fdiv floating point divide (or square root)
255 ;; gp_fpul move from general purpose register to fpul
256 ;; fpul_gp move from fpul to general purpose register
257 ;; mac_gp move from mac[lh] to general purpose register
258 ;; gp_mac move from general purpose register to mac[lh]
259 ;; mac_mem move from mac[lh] to memory
260 ;; mem_mac move from memory to mac[lh]
261 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
262 ;; ftrc_s fix_truncsfsi2_i4
263 ;; dfdiv double precision floating point divide (or square root)
264 ;; cwb ic_invalidate_line_i
265 ;; movua SH4a unaligned load
266 ;; fsrra square root reciprocal approximate
267 ;; fsca sine and cosine approximate
268 ;; tls_load load TLS related address
269 ;; arith_media SHmedia arithmetic, logical, and shift instructions
270 ;; cbranch_media SHmedia conditional branch instructions
271 ;; cmp_media SHmedia compare instructions
272 ;; dfdiv_media SHmedia double precision divide and square root
273 ;; dfmul_media SHmedia double precision multiply instruction
274 ;; dfparith_media SHmedia double precision floating point arithmetic
275 ;; dfpconv_media SHmedia double precision floating point conversions
276 ;; dmpy_media SHmedia longword multiply
277 ;; fcmp_media SHmedia floating point compare instructions
278 ;; fdiv_media SHmedia single precision divide and square root
279 ;; fload_media SHmedia floating point register load instructions
280 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
281 ;; fparith_media SHmedia single precision floating point arithmetic
282 ;; fpconv_media SHmedia single precision floating point conversions
283 ;; fstore_media SHmedia floating point register store instructions
284 ;; gettr_media SHmedia gettr instruction
285 ;; invalidate_line_media SHmedia invalidate_line sequence
286 ;; jump_media SHmedia unconditional branch instructions
287 ;; load_media SHmedia general register load instructions
288 ;; pt_media SHmedia pt instruction (expanded by assembler)
289 ;; ptabs_media SHmedia ptabs instruction
290 ;; store_media SHmedia general register store instructions
291 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
292 ;; mac_media SHmedia mac-style fixed point operations
293 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
294 ;; atrans_media SHmedia approximate transcendental functions
295 ;; ustore_media SHmedia unaligned stores
296 ;; nil no-op move, will be deleted.
299 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,
300 fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,
301 prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,
302 dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,
303 gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,
304 arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,
305 dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,
306 fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,
307 jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,
308 d2mpy_media,atrans_media,ustore_media,nil,other"
309 (const_string "other"))
311 ;; We define a new attribute namely "insn_class".We use
312 ;; this for the DFA based pipeline description.
314 ;; mt_group SH4 "mt" group instructions.
316 ;; ex_group SH4 "ex" group instructions.
318 ;; ls_group SH4 "ls" group instructions.
320 (define_attr "insn_class"
321 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
322 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
323 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
324 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,
325 store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
326 (eq_attr "type" "cbranch,jump") (const_string "br_group")
327 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
328 (const_string "fe_group")
329 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,
330 prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,
331 gp_mac,mac_mem,mem_mac") (const_string "co_group")]
332 (const_string "none")))
334 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
335 ;; so these do not belong in an insn group, although they are modeled
336 ;; with their own define_insn_reservations.
338 ;; Indicate what precision must be selected in fpscr for this insn, if any.
339 (define_attr "fp_mode" "single,double,none" (const_string "none"))
341 ;; Indicate if the fpu mode is set by this instruction
342 ;; "unknown" must have the value as "none" in fp_mode, and means
343 ;; that the instruction/abi has left the processor in an unknown
345 ;; "none" means that nothing has changed and no mode is set.
346 ;; This attribute is only used for the Renesas ABI.
347 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
349 ; If a conditional branch destination is within -252..258 bytes away
350 ; from the instruction it can be 2 bytes long. Something in the
351 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
352 ; branches are initially assumed to be 16 bytes long.
353 ; In machine_dependent_reorg, we split all branches that are longer than
356 ;; The maximum range used for SImode constant pool entries is 1018. A final
357 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
358 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
359 ;; instruction around the pool table, 2 bytes of alignment before the table,
360 ;; and 30 bytes of alignment after the table. That gives a maximum total
361 ;; pool size of 1058 bytes.
362 ;; Worst case code/pool content size ratio is 1:2 (using asms).
363 ;; Thus, in the worst case, there is one instruction in front of a maximum
364 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
365 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
366 ;; If we have a forward branch, the initial table will be put after the
367 ;; unconditional branch.
369 ;; ??? We could do much better by keeping track of the actual pcloads within
370 ;; the branch range and in the pcload range in front of the branch range.
372 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
374 (define_attr "short_cbranch_p" "no,yes"
375 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
379 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
381 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
383 ] (const_string "no")))
385 (define_attr "med_branch_p" "no,yes"
386 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
389 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
391 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
394 ] (const_string "no")))
396 (define_attr "med_cbranch_p" "no,yes"
397 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
400 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
402 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
405 ] (const_string "no")))
407 (define_attr "braf_branch_p" "no,yes"
408 (cond [(match_test "! TARGET_SH2")
410 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
413 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
415 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
418 ] (const_string "no")))
420 (define_attr "braf_cbranch_p" "no,yes"
421 (cond [(match_test "! TARGET_SH2")
423 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
426 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
428 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
431 ] (const_string "no")))
433 ;; An unconditional jump in the range -4092..4098 can be 2 bytes long.
434 ;; For wider ranges, we need a combination of a code and a data part.
435 ;; If we can get a scratch register for a long range jump, the code
436 ;; part can be 4 bytes long; otherwise, it must be 8 bytes long.
437 ;; If the jump is in the range -32764..32770, the data part can be 2 bytes
438 ;; long; otherwise, it must be 6 bytes long.
440 ;; All other instructions are two bytes long by default.
442 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
443 ;; but getattrtab doesn't understand this.
444 (define_attr "length" ""
445 (cond [(eq_attr "type" "cbranch")
446 (cond [(eq_attr "short_cbranch_p" "yes")
448 (eq_attr "med_cbranch_p" "yes")
450 (eq_attr "braf_cbranch_p" "yes")
452 ;; ??? using pc is not computed transitively.
453 (ne (match_dup 0) (match_dup 0))
455 (match_test "flag_pic")
458 (eq_attr "type" "jump")
459 (cond [(eq_attr "med_branch_p" "yes")
461 (and (match_test "prev_nonnote_insn (insn)")
462 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
464 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
465 (symbol_ref "code_for_indirect_jump_scratch"))))
466 (cond [(eq_attr "braf_branch_p" "yes")
468 (not (match_test "flag_pic"))
470 (match_test "TARGET_SH2")
471 (const_int 10)] (const_int 18))
472 (eq_attr "braf_branch_p" "yes")
474 ;; ??? using pc is not computed transitively.
475 (ne (match_dup 0) (match_dup 0))
477 (match_test "flag_pic")
480 (eq_attr "type" "pt_media")
481 (if_then_else (match_test "TARGET_SHMEDIA64")
482 (const_int 20) (const_int 12))
483 (and (eq_attr "type" "jump_media")
484 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
486 ] (if_then_else (match_test "TARGET_SHMEDIA")
490 ;; DFA descriptions for the pipelines
493 (include "shmedia.md")
496 (include "iterators.md")
497 (include "predicates.md")
498 (include "constraints.md")
500 ;; Definitions for filling delay slots
502 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
504 (define_attr "banked" "yes,no"
505 (cond [(match_test "sh_loads_bankedreg_p (insn)")
506 (const_string "yes")]
507 (const_string "no")))
509 ;; ??? This should be (nil) instead of (const_int 0)
510 (define_attr "hit_stack" "yes,no"
511 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
513 (const_string "yes")))
515 (define_attr "interrupt_function" "no,yes"
516 (const (symbol_ref "current_function_interrupt")))
518 (define_attr "in_delay_slot" "yes,no"
519 (cond [(eq_attr "type" "cbranch") (const_string "no")
520 (eq_attr "type" "pcload,pcload_si") (const_string "no")
521 (eq_attr "type" "fpscr_toggle") (const_string "no")
522 (eq_attr "needs_delay_slot" "yes") (const_string "no")
523 (eq_attr "length" "2") (const_string "yes")
524 ] (const_string "no")))
526 (define_attr "cond_delay_slot" "yes,no"
527 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
528 ] (const_string "no")))
530 (define_attr "is_sfunc" ""
531 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
533 (define_attr "is_mac_media" ""
534 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
536 (define_attr "branch_zero" "yes,no"
537 (cond [(eq_attr "type" "!cbranch") (const_string "no")
538 (ne (symbol_ref "(next_active_insn (insn)\
539 == (prev_active_insn\
540 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
541 && get_attr_length (next_active_insn (insn)) == 2")
543 (const_string "yes")]
544 (const_string "no")))
546 ;; SH4 Double-precision computation with double-precision result -
547 ;; the two halves are ready at different times.
548 (define_attr "dfp_comp" "yes,no"
549 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
550 (const_string "no")))
552 ;; Insns for which the latency of a preceding fp insn is decreased by one.
553 (define_attr "late_fp_use" "yes,no" (const_string "no"))
554 ;; And feeding insns for which this relevant.
555 (define_attr "any_fp_comp" "yes,no"
556 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
557 (const_string "yes")]
558 (const_string "no")))
560 (define_attr "any_int_load" "yes,no"
561 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
562 (const_string "yes")]
563 (const_string "no")))
565 (define_attr "highpart" "user, ignore, extend, depend, must_split"
566 (const_string "user"))
569 (eq_attr "needs_delay_slot" "yes")
570 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
572 ;; Since a normal return (rts) implicitly uses the PR register,
573 ;; we can't allow PR register loads in an rts delay slot.
574 ;; On the SH1* and SH2*, the rte instruction reads the return pc from the
575 ;; stack, and thus we can't put a pop instruction in its delay slot.
576 ;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
577 ;; pop instruction can go in the delay slot, unless it references a banked
578 ;; register (the register bank is switched by rte).
580 (eq_attr "type" "return")
581 [(and (eq_attr "in_delay_slot" "yes")
582 (ior (and (eq_attr "interrupt_function" "no")
583 (eq_attr "type" "!pload,prset"))
584 (and (eq_attr "interrupt_function" "yes")
585 (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
586 (eq_attr "banked" "no"))))
589 ;; Since a call implicitly uses the PR register, we can't allow
590 ;; a PR register store in a jsr delay slot.
593 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
594 [(and (eq_attr "in_delay_slot" "yes")
595 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
597 ;; Conditional branches with delay slots are available starting with SH2.
599 (and (eq_attr "type" "cbranch") (match_test "TARGET_SH2"))
600 [(eq_attr "cond_delay_slot" "yes") (nil) (nil)])
602 ;; -------------------------------------------------------------------------
603 ;; SImode signed integer comparisons
604 ;; -------------------------------------------------------------------------
606 ;; Patterns to generate the tst instruction which are usually formed by
608 ;; The canonical form here being used is (eq (and (op) (op)) 0).
609 ;; For some bit patterns, such as contiguous bits, we also must accept
610 ;; zero_extract forms. Single bit tests are also handled via zero_extract
611 ;; patterns in the 'bit field extract patterns' section. All variants
612 ;; are eventually converted to the 'tstsi_t' insn.
613 ;; As long as pseudos can be created (before RA), 'tstsi_t' will also accept
614 ;; constants that won't fit into 8 bits. After having captured the constant
615 ;; we can decide better whether/how to load it into a register and do other
616 ;; post-combine optimizations such as bypassing sign/zero extensions.
617 (define_insn_and_split "tstsi_t"
619 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "%z,r")
620 (match_operand:SI 1 "arith_or_int_operand" "K08,?r"))
623 && (can_create_pseudo_p () || arith_reg_operand (operands[1], SImode)
624 || satisfies_constraint_K08 (operands[1]))"
626 "TARGET_SH1 && can_create_pseudo_p () && CONST_INT_P (operands[1])
627 && !sh_in_recog_treg_set_expr ()"
630 gcc_assert (CONST_INT_P (operands[1]));
632 HOST_WIDE_INT op1val = INTVAL (operands[1]);
633 bool op0_dead_after_this =
634 sh_reg_dead_or_unused_after_insn (curr_insn, REGNO (operands[0]));
640 "tstsi_t: trying to optimize const_int 0x%08x\n",
643 /* See if we can convert a test with a reg and a constant into
644 something simpler, if the reg is known to be zero or sign
646 sh_extending_set_of_reg eop0 = sh_find_extending_set_of_reg (operands[0],
648 if (eop0.ext_code != UNKNOWN)
650 /* Adjust the constant, trying to eliminate bits that are not
651 contributing to the result. */
652 if (eop0.from_mode == QImode)
654 | (eop0.ext_code == SIGN_EXTEND && (op1val & 0xFFFFFF80)
656 else if (eop0.from_mode == HImode)
658 | (eop0.ext_code == SIGN_EXTEND && (op1val & 0xFFFF8000)
659 ? 0x8000 : 0)) & 0xFFFF;
662 fprintf (dump_file, "tstsi_t: using effective const_int: 0x%08x\n",
665 /* Try to bypass the sign/zero extension first if op0 dies after
667 if (op0_dead_after_this && eop0.can_use_as_unextended_reg ())
670 fprintf (dump_file, "tstsi_t: bypassing sign/zero extension\n");
672 operands[0] = eop0.use_as_unextended_reg (curr_insn);
674 else if ((eop0.from_mode == QImode && op1val == 0xFF)
675 || (eop0.from_mode == HImode && op1val == 0xFFFF))
678 fprintf (dump_file, "tstsi_t: converting to cmpeqsi_t\n");
679 emit_insn (gen_cmpeqsi_t (eop0.use_as_extended_reg (curr_insn),
683 else if (eop0.ext_code == SIGN_EXTEND
684 && ((eop0.from_mode == QImode && op1val == 0x80)
685 || (eop0.from_mode == HImode && op1val == 0x8000)))
688 fprintf (dump_file, "tstsi_t: converting to cmpgesi_t\n");
689 emit_insn (gen_cmpgesi_t (eop0.use_as_extended_reg (curr_insn),
693 else if (!CONST_OK_FOR_K08 (op1val))
696 fprintf (dump_file, "tstsi_t: converting const_int to signed "
699 /* If here we haven't done anything yet. Convert the constant
700 to a signed value to reduce the constant pool size. */
701 operands[0] = eop0.use_as_extended_reg (curr_insn);
703 if (eop0.from_mode == QImode)
704 op1val |= (op1val & 0x80) ? 0xFFFFFFFFFFFFFF00LL : 0;
705 else if (eop0.from_mode == HImode)
706 op1val |= (op1val & 0x8000) ? 0xFFFFFFFFFFFF0000LL : 0;
709 operands[0] = eop0.use_as_extended_reg (curr_insn);
714 fprintf (dump_file, "tstsi_t: using const_int 0x%08x\n",
717 /* Try to fit the constant into 8 bits by shuffling the value in the
719 Doing that usually results in smaller code as the constants in the
720 pools are avoided (32 bit constant = load + constant = 6 bytes).
721 However, if the constant load (LS insn) can be hoisted insn dependencies
722 can be avoided and chances for parallel execution increase. The common
728 FIXME: For now we do that only when optimizing for size until there is
731 FIXME: If there are multiple tst insns in the block with the same
732 constant, avoid the #imm variant to avoid R0 loads. Use the 'tst Rn,Rm'
733 variant instead and load the constant into a reg. For that we'd need
734 to do some analysis. */
736 if (CONST_OK_FOR_K08 (op1val))
740 else if ((op1val & 0xFFFF) == 0
741 && CONST_OK_FOR_K08 (op1val >> 16) && optimize_size)
743 /* Use a swap.w insn to do a shift + reg copy (to R0) in one insn. */
744 op1val = op1val >> 16;
745 rtx r = gen_reg_rtx (SImode);
746 emit_insn (gen_rotlsi3_16 (r, operands[0]));
749 else if ((op1val & 0xFF) == 0
750 && CONST_OK_FOR_K08 (op1val >> 8) && optimize_size)
752 /* Use a swap.b insn to do a shift + reg copy (to R0) in one insn. */
753 op1val = op1val >> 8;
754 rtx r = gen_reg_rtx (SImode);
755 emit_insn (gen_swapbsi2 (r, operands[0]));
758 else if ((op1val & 3) == 0
759 && CONST_OK_FOR_K08 (op1val >> 2) && optimize_size)
761 op1val = op1val >> 2;
762 rtx r = gen_reg_rtx (SImode);
763 emit_insn (gen_lshrsi3_k (r, operands[0], GEN_INT (2)));
766 else if ((op1val & 1) == 0
767 && CONST_OK_FOR_K08 (op1val >> 1) && optimize_size)
769 op1val = op1val >> 1;
770 rtx r = gen_reg_rtx (SImode);
771 emit_insn (gen_shlr (r, operands[0]));
775 operands[1] = GEN_INT (op1val);
777 if (!satisfies_constraint_K08 (operands[1]))
778 operands[1] = force_reg (SImode, operands[1]);
780 emit_insn (gen_tstsi_t (operands[0], operands[1]));
783 [(set_attr "type" "mt_group")])
785 ;; This pattern is used by combine when testing QI/HImode subregs with a
786 ;; negative constant. Ignore high bits by masking them out in the constant.
787 (define_insn_and_split "*tst<mode>_t"
790 (and:QIHI (match_operand:QIHI 0 "arith_reg_operand")
791 (match_operand 1 "const_int_operand")) 0)
793 "TARGET_SH1 && can_create_pseudo_p ()"
797 (eq:SI (and:SI (match_dup 0) (match_dup 1)) (const_int 0)))]
799 operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
800 operands[1] = GEN_INT (INTVAL (operands[1])
801 & (<MODE>mode == HImode ? 0xFFFF : 0xFF));
804 ;; This pattern might be risky because it also tests the upper bits and not
805 ;; only the subreg. We have to check whether the operands have been sign
806 ;; or zero extended. In the worst case, a zero extension has to be inserted
807 ;; to mask out the unwanted bits.
808 (define_insn_and_split "*tst<mode>_t_subregs"
812 (and:SI (match_operand:SI 0 "arith_reg_operand")
813 (match_operand:SI 1 "arith_reg_operand")) <lowpart_le>)
815 "TARGET_SH1 && TARGET_LITTLE_ENDIAN && can_create_pseudo_p ()"
817 "&& !sh_in_recog_treg_set_expr ()"
820 sh_split_tst_subregs (curr_insn, <MODE>mode, <lowpart_le>, operands);
824 (define_insn_and_split "*tst<mode>_t_subregs"
828 (and:SI (match_operand:SI 0 "arith_reg_operand")
829 (match_operand:SI 1 "arith_reg_operand")) <lowpart_be>)
831 "TARGET_SH1 && TARGET_BIG_ENDIAN && can_create_pseudo_p ()"
833 "&& !sh_in_recog_treg_set_expr ()"
836 sh_split_tst_subregs (curr_insn, <MODE>mode, <lowpart_be>, operands);
840 ;; Extract contiguous bits and compare them against zero.
841 ;; Notice that this will not be used for single bits. Special single bit
842 ;; extraction patterns are in the 'bit field extract patterns' section.
843 (define_insn_and_split "*tst<mode>_t_zero_extract"
845 (eq:SI (zero_extract:SI (match_operand:QIHISI 0 "arith_reg_operand")
846 (match_operand 1 "const_int_operand")
847 (match_operand 2 "const_int_operand"))
849 "TARGET_SH1 && can_create_pseudo_p ()"
853 (eq:SI (and:SI (match_dup 0) (match_dup 1)) (const_int 0)))]
855 operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
856 if (GET_MODE (operands[0]) != SImode)
857 operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
860 ;; Convert '(reg << shift) & mask' into 'reg & (mask >> shift)'.
861 ;; The shifted-out bits in the mask will always be zero, since the
862 ;; shifted-in bits in the reg will also be always zero.
863 (define_insn_and_split "*tstsi_t_shift_mask"
865 (eq:SI (and:SI (ashift:SI (match_operand:SI 0 "arith_reg_operand")
866 (match_operand 1 "const_int_operand"))
867 (match_operand 2 "const_int_operand"))
869 "TARGET_SH1 && can_create_pseudo_p ()"
873 (eq:SI (and:SI (match_dup 0) (match_dup 2)) (const_int 0)))]
875 operands[2] = GEN_INT (INTVAL (operands[2]) >> INTVAL (operands[1]));
878 (define_insn "cmpeqsi_t"
880 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
881 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
887 [(set_attr "type" "mt_group")])
889 ;; Sometimes combine fails to form the (eq (and (op) (op)) 0) tst insn.
890 ;; Try to fix that in the split1 pass by looking for the previous set
891 ;; of the tested op. Also see if there is a preceeding sign/zero
892 ;; extension that can be avoided.
895 (eq:SI (match_operand:SI 0 "arith_reg_operand") (const_int 0)))]
896 "TARGET_SH1 && can_create_pseudo_p () && optimize
897 && !sh_in_recog_treg_set_expr ()"
898 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
901 fprintf (dump_file, "cmpeqsi_t: trying to optimize const_int 0\n");
903 /* If the tested reg is not dead after this insn, it's probably used by
904 something else after the comparison. It's probably better to leave
906 if (find_regno_note (curr_insn, REG_DEAD, REGNO (operands[0])) == NULL_RTX)
909 /* FIXME: Maybe also search the predecessor basic blocks to catch
911 set_of_reg op = sh_find_set_of_reg (operands[0], curr_insn,
912 prev_nonnote_insn_bb);
914 if (op.set_src != NULL && GET_CODE (op.set_src) == AND
915 && !sh_insn_operands_modified_between_p (op.insn, op.insn, curr_insn))
918 fprintf (dump_file, "cmpeqsi_t: found preceeding and in insn %d\n",
921 if (!(arith_reg_operand (XEXP (op.set_src, 0), SImode)
922 && (arith_reg_operand (XEXP (op.set_src, 1), SImode)
923 || CONST_INT_P (XEXP (op.set_src, 1)))))
926 /* Assume that the operands of the andsi insn are compatible with the
927 operands of the tstsi_t insn, which is generally the case. */
929 fprintf (dump_file, "cmpeqsi_t: replacing with tstsi_t\n");
930 emit_insn (gen_tstsi_t (XEXP (op.set_src, 0), XEXP (op.set_src, 1)));
934 /* Converting HImode into tests against 0xFFFF tends to increase the code
935 size, as it will create constant pool entries. Disable it for now. */
936 const bool enable_himode = false;
938 /* FIXME: try to keep the (eq (reg) (const_int 0)). Even if the zero
939 extended reg is used after this insn, if we know that _before_ the zero
940 extension the value was loaded via sign extending mem load, we can just
941 use the value of the mem load directly. */
942 sh_extending_set_of_reg eop = sh_find_extending_set_of_reg (operands[0],
945 if (eop.ext_code != UNKNOWN
946 && (eop.from_mode == QImode || (eop.from_mode == HImode && enable_himode))
947 && eop.can_use_as_unextended_reg ()
948 && !reg_used_between_p (operands[0], eop.insn, curr_insn))
950 /* Bypass the sign/zero extension and test against the bit mask, but
951 only if it's the only use of the sign/zero extracted value.
952 Otherwise we'd be introducing new constants in the pool. */
954 fprintf (dump_file, "cmpeqsi_t: bypassing sign/zero extension in "
955 "insn %d and using tstsi_t\n", INSN_UID (op.insn));
957 emit_insn (gen_tstsi_t (
958 eop.use_as_unextended_reg (curr_insn),
959 GEN_INT (eop.from_mode == QImode ? 0xFF : 0xFFFF)));
964 fprintf (dump_file, "cmpeqsi_t: nothing optimized\n");
968 ;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
969 ;; pattern by itself. What this actually does is:
970 ;; x == 0: (1 >> 0-0) & 1 = 1
971 ;; x != 0: (1 >> 0-x) & 1 = 0
972 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
973 (define_insn_and_split "*cmpeqsi_t"
977 (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
982 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
984 (define_insn "cmpgtsi_t"
986 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
987 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
992 [(set_attr "type" "mt_group")])
994 (define_insn "cmpgesi_t"
996 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
997 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
1002 [(set_attr "type" "mt_group")])
1004 ;; Recombine a cmp/pz followed by a nott into a shll.
1005 ;; On non-SH2A recombine a cmp/pz followed by a movrt into shll-movt.
1006 ;; On SH2A cmp/pz-movrt is slightly better, as it does not mutate the input.
1008 [(set (reg:SI T_REG)
1009 (ge:SI (match_operand:SI 0 "arith_reg_operand") (const_int 0)))]
1011 "TARGET_SH1 && can_create_pseudo_p () && optimize
1012 && !sh_in_recog_treg_set_expr ()"
1016 fprintf (dump_file, "cmpgesi_t: trying to optimize for const_int 0\n");
1018 rtx_insn* i = next_nonnote_insn_bb (curr_insn);
1022 fprintf (dump_file, "cmpgesi_t: following insn is \n");
1023 print_rtl_single (dump_file, i);
1024 fprintf (dump_file, "\n");
1027 if (sh_is_nott_insn (i))
1031 "cmpgesi_t: replacing (cmp/pz, nott) with (shll)\n");
1032 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[0]));
1033 set_insn_deleted (i);
1037 /* On non-SH2A negc is used as movrt replacement, which sets T = 1.
1038 Thus we can remove it only if T is marked as dead afterwards. */
1039 if (rtx dest_reg = !TARGET_SH2A
1040 && sh_reg_dead_or_unused_after_insn (i, T_REG)
1041 ? sh_movrt_set_dest (i) : NULL)
1045 "cmpgesi_t: replacing (cmp/pz, movrt) with (shll, movt)\n");
1046 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[0]));
1047 add_reg_note (emit_insn (gen_movt (dest_reg, get_t_reg_rtx ())),
1048 REG_DEAD, get_t_reg_rtx ());
1049 set_insn_deleted (i);
1054 fprintf (dump_file, "cmpgesi_t: nothing optimized\n");
1059 ;; FIXME: This is actually wrong. There is no way to literally move a
1060 ;; general reg to t reg. Luckily, it seems that this pattern will be only
1061 ;; used when the general reg is known be either '0' or '1' during combine.
1062 ;; What we actually need is reg != 0 -> T, but we have only reg == 0 -> T.
1063 ;; Due to interactions with other patterns, combine fails to pick the latter
1064 ;; and invert the dependent logic.
1065 (define_insn "*negtstsi"
1066 [(set (reg:SI T_REG) (match_operand:SI 0 "arith_reg_operand" "r"))]
1067 "TARGET_SH1 && !sh_in_recog_treg_set_expr ()"
1069 [(set_attr "type" "mt_group")])
1071 ;; Some integer sign comparison patterns can be realized with the div0s insn.
1072 ;; div0s Rm,Rn T = (Rm >> 31) ^ (Rn >> 31)
1074 ;; The 'cmp_div0s' pattern is our canonical form, into which all the other
1075 ;; variations are converted. The negative forms will split into a trailing
1076 ;; nott sequence, which will be eliminated either by the
1077 ;; 'any_treg_expr_to_reg' pattern, or by the 'sh_treg_combine' pass.
1078 (define_insn "cmp_div0s"
1079 [(set (reg:SI T_REG)
1080 (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
1081 (match_operand:SI 1 "arith_reg_operand" "r"))
1085 [(set_attr "type" "arith")])
1087 (define_insn_and_split "*cmp_div0s_1"
1088 [(set (reg:SI T_REG)
1089 (xor:SI (ge:SI (match_operand:SI 0 "arith_reg_operand")
1091 (ge:SI (match_operand:SI 1 "arith_reg_operand")
1093 "TARGET_SH1 && can_create_pseudo_p ()"
1096 [(set (reg:SI T_REG)
1097 (lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))])
1099 (define_insn_and_split "*cmp_div0s_2"
1100 [(set (reg:SI T_REG)
1101 (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
1103 (ge:SI (match_operand:SI 1 "arith_reg_operand")
1105 "TARGET_SH1 && can_create_pseudo_p ()"
1108 [(set (reg:SI T_REG)
1109 (lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))])
1111 (define_insn_and_split "*cmp_div0s_3"
1112 [(set (reg:SI T_REG)
1113 (eq:SI (ge:SI (match_operand:SI 0 "arith_reg_operand")
1115 (ge:SI (match_operand:SI 1 "arith_reg_operand")
1117 "TARGET_SH1 && can_create_pseudo_p ()"
1120 [(set (reg:SI T_REG)
1121 (lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))
1122 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
1124 (define_insn_and_split "*cmp_div0s_4"
1125 [(set (reg:SI T_REG)
1126 (ge:SI (xor:SI (match_operand:SI 0 "arith_reg_operand")
1127 (match_operand:SI 1 "arith_reg_operand"))
1129 "TARGET_SH1 && can_create_pseudo_p ()"
1132 [(set (reg:SI T_REG)
1133 (lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))
1134 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
1136 (define_insn_and_split "*cmp_div0s_5"
1137 [(set (reg:SI T_REG)
1138 (xor:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
1140 (ge:SI (match_operand:SI 1 "arith_reg_operand")
1142 "TARGET_SH1 && can_create_pseudo_p ()"
1145 [(set (reg:SI T_REG)
1146 (lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))
1147 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
1149 (define_insn_and_split "*cmp_div0s_6"
1150 [(set (reg:SI T_REG)
1151 (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
1153 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
1155 "TARGET_SH1 && can_create_pseudo_p ()"
1158 [(set (reg:SI T_REG)
1159 (lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))
1160 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
1162 ;; -------------------------------------------------------------------------
1163 ;; SImode compare and branch
1164 ;; -------------------------------------------------------------------------
1166 (define_expand "cbranchsi4"
1168 (if_then_else (match_operator 0 "comparison_operator"
1169 [(match_operand:SI 1 "arith_operand" "")
1170 (match_operand:SI 2 "arith_operand" "")])
1171 (label_ref (match_operand 3 "" ""))
1173 (clobber (reg:SI T_REG))]
1177 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1178 operands[2], operands[3]));
1180 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
1185 ;; Combine patterns to invert compare and branch operations for which we
1186 ;; don't have actual comparison insns. These patterns are used in cases
1187 ;; which appear after the initial cbranchsi expansion, which also does
1188 ;; some condition inversion.
1191 (if_then_else (ne (match_operand:SI 0 "arith_reg_operand" "")
1192 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1193 (label_ref (match_operand 2))
1195 (clobber (reg:SI T_REG))]
1197 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (match_dup 1)))
1198 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1199 (label_ref (match_dup 2))
1202 ;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
1203 ;; and SH2A combine fails to simplify this pattern by itself.
1204 ;; What this actually does is:
1205 ;; x == 0: (1 >> 0-0) & 1 = 1
1206 ;; x != 0: (1 >> 0-x) & 1 = 0
1207 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
1211 (eq (and:SI (lshiftrt:SI
1213 (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
1216 (label_ref (match_operand 2))
1218 (clobber (reg:SI T_REG))]
1220 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
1221 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1222 (label_ref (match_dup 2))
1225 ;; FIXME: These could probably use code iterators for the compare op.
1228 (if_then_else (le (match_operand:SI 0 "arith_reg_operand" "")
1229 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1230 (label_ref (match_operand 2))
1232 (clobber (reg:SI T_REG))]
1234 [(set (reg:SI T_REG) (gt:SI (match_dup 0) (match_dup 1)))
1235 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1236 (label_ref (match_dup 2))
1241 (if_then_else (lt (match_operand:SI 0 "arith_reg_operand" "")
1242 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1243 (label_ref (match_operand 2))
1245 (clobber (reg:SI T_REG))]
1247 [(set (reg:SI T_REG) (ge:SI (match_dup 0) (match_dup 1)))
1248 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1249 (label_ref (match_dup 2))
1254 (if_then_else (leu (match_operand:SI 0 "arith_reg_operand" "")
1255 (match_operand:SI 1 "arith_reg_operand" ""))
1256 (label_ref (match_operand 2))
1258 (clobber (reg:SI T_REG))]
1260 [(set (reg:SI T_REG) (gtu:SI (match_dup 0) (match_dup 1)))
1261 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1262 (label_ref (match_dup 2))
1267 (if_then_else (ltu (match_operand:SI 0 "arith_reg_operand" "")
1268 (match_operand:SI 1 "arith_reg_operand" ""))
1269 (label_ref (match_operand 2))
1271 (clobber (reg:SI T_REG))]
1273 [(set (reg:SI T_REG) (geu:SI (match_dup 0) (match_dup 1)))
1274 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1275 (label_ref (match_dup 2))
1278 ;; -------------------------------------------------------------------------
1279 ;; SImode unsigned integer comparisons
1280 ;; -------------------------------------------------------------------------
1282 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1283 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1284 ;; might remain and we have to handle them. If the '>= 0' case wasn't
1285 ;; handled here, something else would just load a '0' into the second operand
1286 ;; and do the comparison. We can do slightly better by just setting the
1288 (define_insn_and_split "cmpgeusi_t"
1289 [(set (reg:SI T_REG)
1290 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1291 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1294 "&& satisfies_constraint_Z (operands[1])"
1295 [(set (reg:SI T_REG) (const_int 1))]
1297 [(set_attr "type" "mt_group")])
1299 (define_insn "cmpgtusi_t"
1300 [(set (reg:SI T_REG)
1301 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1302 (match_operand:SI 1 "arith_reg_operand" "r")))]
1305 [(set_attr "type" "mt_group")])
1307 ;; -------------------------------------------------------------------------
1308 ;; DImode compare and branch
1309 ;; -------------------------------------------------------------------------
1311 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1312 ;; Therefore, we aim to have a set of three branches that go straight to the
1313 ;; destination, i.e. only one of them is taken at any one time.
1314 ;; This mechanism should also be slightly better for the sh4-200.
1316 (define_expand "cbranchdi4"
1318 (if_then_else (match_operator 0 "comparison_operator"
1319 [(match_operand:DI 1 "arith_operand" "")
1320 (match_operand:DI 2 "arith_operand" "")])
1321 (label_ref (match_operand 3 "" ""))
1323 (clobber (match_dup 4))
1324 (clobber (reg:SI T_REG))]
1325 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1327 enum rtx_code comparison;
1331 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1332 operands[2], operands[3]));
1335 else if (!TARGET_CBRANCHDI4)
1337 sh_emit_compare_and_branch (operands, DImode);
1342 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1345 comparison = prepare_cbranch_operands (operands, DImode,
1346 LAST_AND_UNUSED_RTX_CODE);
1347 if (comparison != GET_CODE (operands[0]))
1349 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1350 operands[4] = gen_rtx_SCRATCH (SImode);
1354 (define_insn_and_split "cbranchdi4_i"
1356 (if_then_else (match_operator 0 "comparison_operator"
1357 [(match_operand:DI 1 "arith_operand" "r,r")
1358 (match_operand:DI 2 "arith_operand" "rN,I08")])
1359 (label_ref (match_operand 3 "" ""))
1361 (clobber (match_scratch:SI 4 "=X,&r"))
1362 (clobber (reg:SI T_REG))]
1365 "&& reload_completed"
1368 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1373 ;; -------------------------------------------------------------------------
1374 ;; DImode signed integer comparisons
1375 ;; -------------------------------------------------------------------------
1378 [(set (reg:SI T_REG)
1379 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1380 (match_operand:DI 1 "arith_operand" "r"))
1384 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1387 [(set_attr "length" "6")
1388 (set_attr "type" "arith3b")])
1390 (define_insn "cmpeqdi_t"
1391 [(set (reg:SI T_REG)
1392 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1393 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1396 static const char* alt[] =
1403 "cmp/eq %S1,%S0" "\n"
1405 " cmp/eq %R1,%R0" "\n"
1408 return alt[which_alternative];
1410 [(set_attr "length" "6")
1411 (set_attr "type" "arith3b")])
1414 [(set (reg:SI T_REG)
1415 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1416 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1417 ;; If we applied this split when not optimizing, it would only be
1418 ;; applied during the machine-dependent reorg, when no new basic blocks
1420 "TARGET_SH1 && reload_completed && optimize"
1421 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1422 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1423 (label_ref (match_dup 6))
1425 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1428 operands[2] = gen_highpart (SImode, operands[0]);
1429 operands[3] = operands[1] == const0_rtx
1431 : gen_highpart (SImode, operands[1]);
1432 operands[4] = gen_lowpart (SImode, operands[0]);
1433 operands[5] = gen_lowpart (SImode, operands[1]);
1434 operands[6] = gen_label_rtx ();
1437 (define_insn "cmpgtdi_t"
1438 [(set (reg:SI T_REG)
1439 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1440 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1443 static const char* alt[] =
1445 "cmp/eq %S1,%S0" "\n"
1447 " cmp/gt %S1,%S0" "\n"
1448 " cmp/hi %R1,%R0" "\n"
1454 " cmp/hi %S0,%R0" "\n"
1457 return alt[which_alternative];
1459 [(set_attr "length" "8")
1460 (set_attr "type" "arith3")])
1462 (define_insn "cmpgedi_t"
1463 [(set (reg:SI T_REG)
1464 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1465 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1468 static const char* alt[] =
1470 "cmp/eq %S1,%S0" "\n"
1472 " cmp/ge %S1,%S0" "\n"
1473 " cmp/hs %R1,%R0" "\n"
1478 return alt[which_alternative];
1480 [(set_attr "length" "8,2")
1481 (set_attr "type" "arith3,mt_group")])
1483 ;; -------------------------------------------------------------------------
1484 ;; DImode unsigned integer comparisons
1485 ;; -------------------------------------------------------------------------
1487 (define_insn "cmpgeudi_t"
1488 [(set (reg:SI T_REG)
1489 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1490 (match_operand:DI 1 "arith_reg_operand" "r")))]
1493 return "cmp/eq %S1,%S0" "\n"
1495 " cmp/hs %S1,%S0" "\n"
1496 " cmp/hs %R1,%R0" "\n"
1499 [(set_attr "length" "8")
1500 (set_attr "type" "arith3")])
1502 (define_insn "cmpgtudi_t"
1503 [(set (reg:SI T_REG)
1504 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1505 (match_operand:DI 1 "arith_reg_operand" "r")))]
1508 return "cmp/eq %S1,%S0" "\n"
1510 " cmp/hi %S1,%S0" "\n"
1511 " cmp/hi %R1,%R0" "\n"
1514 [(set_attr "length" "8")
1515 (set_attr "type" "arith3")])
1517 (define_insn "cmpeqsi_media"
1518 [(set (match_operand:SI 0 "register_operand" "=r")
1519 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1520 (match_operand:SI 2 "cmp_operand" "Nr")))]
1523 [(set_attr "type" "cmp_media")])
1525 (define_insn "cmpeqdi_media"
1526 [(set (match_operand:SI 0 "register_operand" "=r")
1527 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1528 (match_operand:DI 2 "cmp_operand" "Nr")))]
1531 [(set_attr "type" "cmp_media")])
1533 (define_insn "cmpgtsi_media"
1534 [(set (match_operand:SI 0 "register_operand" "=r")
1535 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1536 (match_operand:SI 2 "cmp_operand" "rN")))]
1538 "cmpgt %N1, %N2, %0"
1539 [(set_attr "type" "cmp_media")])
1541 (define_insn "cmpgtdi_media"
1542 [(set (match_operand:SI 0 "register_operand" "=r")
1543 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1544 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1546 "cmpgt %N1, %N2, %0"
1547 [(set_attr "type" "cmp_media")])
1549 (define_insn "cmpgtusi_media"
1550 [(set (match_operand:SI 0 "register_operand" "=r")
1551 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1552 (match_operand:SI 2 "cmp_operand" "rN")))]
1554 "cmpgtu %N1, %N2, %0"
1555 [(set_attr "type" "cmp_media")])
1557 (define_insn "cmpgtudi_media"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1560 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1562 "cmpgtu %N1, %N2, %0"
1563 [(set_attr "type" "cmp_media")])
1565 ; This pattern is for combine.
1566 (define_insn "*cmpne0sisi_media"
1567 [(set (match_operand:SI 0 "register_operand" "=r")
1568 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1571 [(set_attr "type" "cmp_media")])
1573 ;; -------------------------------------------------------------------------
1574 ;; Conditional move instructions
1575 ;; -------------------------------------------------------------------------
1577 ;; The insn names may seem reversed, but note that cmveq performs the move
1578 ;; if op1 == 0, and cmvne does it if op1 != 0.
1580 (define_insn "movdicc_false"
1581 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1582 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1584 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1585 (match_operand:DI 3 "arith_reg_operand" "0")))]
1588 [(set_attr "type" "arith_media")])
1590 (define_insn "movdicc_true"
1591 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1592 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1594 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1595 (match_operand:DI 3 "arith_reg_operand" "0")))]
1598 [(set_attr "type" "arith_media")])
1601 [(set (match_operand:DI 0 "arith_reg_dest" "")
1602 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1603 [(match_operand:DI 1 "arith_reg_operand" "")
1605 (match_operand:DI 2 "arith_reg_dest" "")
1607 (set (match_dup 2) (match_dup 0))]
1608 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1610 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1612 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1613 VOIDmode, operands[1], CONST0_RTX (DImode));
1617 [(set (match_operand:DI 0 "general_movdst_operand" "")
1618 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1619 (set (match_operand:DI 2 "arith_reg_dest" "")
1620 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1621 [(match_operand:DI 3 "arith_reg_operand" "")
1625 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1627 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1630 (define_expand "movdicc"
1631 [(set (match_operand:DI 0 "register_operand" "")
1632 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1633 (match_operand:DI 2 "register_operand" "")
1634 (match_operand:DI 3 "register_operand" "")))]
1637 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1638 && GET_MODE (XEXP (operands[1], 0)) == DImode
1639 && XEXP (operands[1], 1) == const0_rtx)
1643 if (!can_create_pseudo_p ())
1646 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1647 GET_CODE (operands[1]),
1648 XEXP (operands[1], 0),
1649 XEXP (operands[1], 1));
1655 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1656 ;; SImode to DImode.
1657 (define_insn "movsicc_false"
1658 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1659 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1661 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1662 (match_operand:SI 3 "arith_reg_operand" "0")))]
1665 [(set_attr "type" "arith_media")])
1667 (define_insn "movsicc_true"
1668 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1669 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1671 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1672 (match_operand:SI 3 "arith_reg_operand" "0")))]
1675 [(set_attr "type" "arith_media")])
1678 [(set (match_operand:SI 0 "arith_reg_dest" "")
1679 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1680 [(match_operand:SI 1 "arith_reg_operand" "")
1682 (match_operand:SI 2 "arith_reg_dest" "")
1684 (set (match_dup 2) (match_dup 0))]
1685 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1687 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1689 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1690 VOIDmode, operands[1], CONST0_RTX (SImode));
1694 [(set (match_operand:SI 0 "general_movdst_operand" "")
1695 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1696 (set (match_operand:SI 2 "arith_reg_dest" "")
1697 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1698 [(match_operand:SI 3 "arith_reg_operand" "")
1702 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1703 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1705 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1707 replace_rtx (operands[4], operands[0], operands[1]);
1710 ;; The register allocator is rather clumsy in handling multi-way conditional
1711 ;; moves, so allow the combiner to make them, and we split them up after
1713 (define_insn_and_split "*movsicc_umin"
1714 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1715 (umin:SI (if_then_else:SI
1716 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1718 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1719 (match_operand:SI 3 "register_operand" "0"))
1720 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1721 (clobber (match_scratch:SI 5 "=&r"))]
1722 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1724 "TARGET_SHMEDIA && reload_completed"
1727 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1729 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1730 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1735 (define_insn "*movsicc_t_false"
1736 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1737 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1738 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1739 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1740 "TARGET_PRETEND_CMOVE
1741 && (arith_reg_operand (operands[1], SImode)
1742 || (immediate_operand (operands[1], SImode)
1743 && satisfies_constraint_I08 (operands[1])))"
1749 [(set_attr "type" "mt_group,arith") ;; poor approximation
1750 (set_attr "length" "4")])
1752 (define_insn "*movsicc_t_true"
1753 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1754 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1755 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1756 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1757 "TARGET_PRETEND_CMOVE
1758 && (arith_reg_operand (operands[1], SImode)
1759 || (immediate_operand (operands[1], SImode)
1760 && satisfies_constraint_I08 (operands[1])))"
1766 [(set_attr "type" "mt_group,arith") ;; poor approximation
1767 (set_attr "length" "4")])
1769 (define_expand "movsicc"
1770 [(set (match_operand:SI 0 "arith_reg_dest" "")
1771 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1772 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1773 (match_operand:SI 3 "arith_reg_operand" "")))]
1774 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1776 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1777 && GET_MODE (XEXP (operands[1], 0)) == SImode
1779 || (REG_P (XEXP (operands[1], 0))
1780 && REGNO (XEXP (operands[1], 0)) == T_REG))
1781 && XEXP (operands[1], 1) == const0_rtx)
1784 else if (TARGET_PRETEND_CMOVE)
1786 enum rtx_code code = GET_CODE (operands[1]);
1787 enum rtx_code new_code = code;
1788 rtx op0 = XEXP (operands[1], 0);
1789 rtx op1 = XEXP (operands[1], 1);
1791 if (! currently_expanding_to_rtl)
1795 case LT: case LE: case LEU: case LTU:
1796 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1799 new_code = reverse_condition (code);
1801 case EQ: case GT: case GE: case GEU: case GTU:
1806 sh_emit_scc_to_t (new_code, op0, op1);
1807 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1808 gen_rtx_REG (SImode, T_REG), const0_rtx);
1812 if (!can_create_pseudo_p ())
1815 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1816 GET_CODE (operands[1]),
1817 XEXP (operands[1], 0),
1818 XEXP (operands[1], 1));
1824 (define_expand "movqicc"
1825 [(set (match_operand:QI 0 "register_operand" "")
1826 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1827 (match_operand:QI 2 "register_operand" "")
1828 (match_operand:QI 3 "register_operand" "")))]
1831 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1832 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1833 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1834 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1838 ;; -------------------------------------------------------------------------
1839 ;; Addition instructions
1840 ;; -------------------------------------------------------------------------
1842 (define_expand "adddi3"
1843 [(set (match_operand:DI 0 "arith_reg_operand")
1844 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1845 (match_operand:DI 2 "arith_operand")))]
1850 operands[2] = force_reg (DImode, operands[2]);
1851 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1856 (define_insn "*adddi3_media"
1857 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1858 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1859 (match_operand:DI 2 "arith_operand" "r,I10")))]
1864 [(set_attr "type" "arith_media")])
1866 (define_insn "*adddisi3_media"
1867 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1868 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1869 (match_operand:DI 2 "arith_operand" "r,I10")))]
1874 [(set_attr "type" "arith_media")
1875 (set_attr "highpart" "ignore")])
1877 (define_insn "adddi3z_media"
1878 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1880 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1881 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1883 "addz.l %1, %N2, %0"
1884 [(set_attr "type" "arith_media")
1885 (set_attr "highpart" "ignore")])
1887 (define_insn_and_split "adddi3_compact"
1888 [(set (match_operand:DI 0 "arith_reg_dest")
1889 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1890 (match_operand:DI 2 "arith_reg_operand")))
1891 (clobber (reg:SI T_REG))]
1894 "&& can_create_pseudo_p ()"
1897 emit_insn (gen_clrt ());
1898 emit_insn (gen_addc (gen_lowpart (SImode, operands[0]),
1899 gen_lowpart (SImode, operands[1]),
1900 gen_lowpart (SImode, operands[2])));
1901 emit_insn (gen_addc (gen_highpart (SImode, operands[0]),
1902 gen_highpart (SImode, operands[1]),
1903 gen_highpart (SImode, operands[2])));
1908 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1909 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1910 (match_operand:SI 2 "arith_reg_operand" "r"))
1913 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1916 [(set_attr "type" "arith")])
1918 ;; A simplified version of the addc insn, where the exact value of the
1919 ;; T bit doesn't matter. This is easier for combine to pick up.
1920 ;; We allow a reg or 0 for one of the operands in order to be able to
1921 ;; do 'reg + T' sequences.
1922 (define_insn_and_split "*addc"
1923 [(set (match_operand:SI 0 "arith_reg_dest")
1924 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand")
1925 (match_operand:SI 2 "arith_reg_or_0_operand"))
1926 (match_operand 3 "treg_set_expr")))
1927 (clobber (reg:SI T_REG))]
1928 "TARGET_SH1 && can_create_pseudo_p ()"
1933 sh_treg_insns ti = sh_split_treg_set_expr (operands[3], curr_insn);
1934 if (ti.has_trailing_nott ())
1936 if (operands[2] == const0_rtx)
1938 /* op1 + 0 + (1 - T) = op1 + 1 - T = op1 - (-1) - T */
1939 remove_insn (ti.trailing_nott ());
1940 emit_insn (gen_subc (operands[0], operands[1],
1941 force_reg (SImode, GEN_INT (-1))));
1944 else if (!TARGET_SH2A)
1946 /* op1 + op2 + (1 - T) = op1 - (0 - op2 - 1) - T = op1 - ~op2 - T
1947 On SH2A keep the nott insn, because nott-addc sequence doesn't
1948 mutate the inputs. */
1949 remove_insn (ti.trailing_nott ());
1950 rtx tmp = gen_reg_rtx (SImode);
1951 emit_insn (gen_one_cmplsi2 (tmp, operands[2]));
1952 emit_insn (gen_subc (operands[0], operands[1], tmp));
1957 emit_insn (gen_addc (operands[0], operands[1],
1958 force_reg (SImode, operands[2])));
1962 (define_insn_and_split "*addc"
1963 [(set (match_operand:SI 0 "arith_reg_dest")
1964 (plus:SI (plus:SI (match_operand 1 "treg_set_expr")
1965 (match_operand:SI 2 "arith_reg_operand"))
1966 (match_operand:SI 3 "arith_reg_operand")))
1967 (clobber (reg:SI T_REG))]
1968 "TARGET_SH1 && can_create_pseudo_p ()"
1971 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
1973 (clobber (reg:SI T_REG))])])
1975 (define_insn_and_split "*addc"
1976 [(set (match_operand:SI 0 "arith_reg_dest")
1977 (plus:SI (match_operand 1 "treg_set_expr")
1978 (plus:SI (match_operand:SI 2 "arith_reg_operand")
1979 (match_operand:SI 3 "arith_reg_operand"))))
1980 (clobber (reg:SI T_REG))]
1981 "TARGET_SH1 && can_create_pseudo_p ()"
1984 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
1986 (clobber (reg:SI T_REG))])])
1988 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1989 ;; matched. Split this up into a simple sub add sequence, as this will save
1990 ;; us one sett insn.
1991 (define_insn_and_split "*minus_plus_one"
1992 [(set (match_operand:SI 0 "arith_reg_dest" "")
1993 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1994 (match_operand:SI 2 "arith_reg_operand" ""))
1999 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
2000 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
2003 ;; The tree optimiziers canonicalize
2008 ;; On SH2A an add-bclr sequence will be used to handle this.
2009 ;; On non-SH2A re-emit the add-and sequence to improve register utilization.
2010 (define_insn_and_split "*round_int_even"
2011 [(set (match_operand:SI 0 "arith_reg_dest")
2012 (and:SI (plus:SI (match_operand:SI 1 "arith_reg_operand")
2015 "TARGET_SH1 && !TARGET_SH2A && can_create_pseudo_p ()
2016 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2019 [(set (match_dup 0) (const_int -2))
2020 (set (match_dup 2) (plus:SI (match_dup 1) (const_int 1)))
2021 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))]
2023 operands[2] = gen_reg_rtx (SImode);
2026 ;; If the *round_int_even pattern is combined with another plus,
2027 ;; convert it into an addc pattern to emit an shlr-addc sequence.
2028 ;; This split is taken by combine on non-SH2A and SH2A.
2030 [(set (match_operand:SI 0 "arith_reg_dest")
2031 (plus:SI (and:SI (plus:SI (match_operand:SI 1 "arith_reg_operand")
2034 (match_operand:SI 2 "arith_reg_operand")))]
2035 "TARGET_SH1 && can_create_pseudo_p ()"
2036 [(parallel [(set (match_dup 0)
2037 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
2038 (and:SI (match_dup 1) (const_int 1))))
2039 (clobber (reg:SI T_REG))])])
2041 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
2042 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2043 ;; operation, as opposed to sequences such as
2047 ;; Even if the constant is not CSE-ed, a sequence such as
2050 ;; can be scheduled much better since the load of the constant can be
2051 ;; done earlier, before any comparison insns that store the result in
2053 ;; However, avoid things like 'reg + 1', which would expand into a
2054 ;; 3 insn sequence, instead of add #imm8.
2055 (define_insn_and_split "*addc_t_r"
2056 [(set (match_operand:SI 0 "arith_reg_dest")
2057 (plus:SI (match_operand 1 "treg_set_expr_not_const01")
2058 (match_operand:SI 2 "arith_reg_operand")))
2059 (clobber (reg:SI T_REG))]
2060 "TARGET_SH1 && can_create_pseudo_p ()"
2063 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (const_int 0))
2065 (clobber (reg:SI T_REG))])])
2067 (define_insn_and_split "*addc_r_t"
2068 [(set (match_operand:SI 0 "arith_reg_dest")
2069 (plus:SI (match_operand:SI 1 "arith_reg_operand")
2070 (match_operand 2 "treg_set_expr_not_const01")))
2071 (clobber (reg:SI T_REG))]
2072 "TARGET_SH1 && can_create_pseudo_p ()"
2075 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (const_int 0))
2077 (clobber (reg:SI T_REG))])])
2079 ;; Convert '2 * reg + T' into 'reg + reg + T'.
2080 (define_insn_and_split "*addc_2r_t"
2081 [(set (match_operand:SI 0 "arith_reg_dest")
2082 (plus:SI (match_operand 1 "treg_set_expr")
2083 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
2085 (clobber (reg:SI T_REG))]
2086 "TARGET_SH1 && can_create_pseudo_p ()"
2089 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 2))
2091 (clobber (reg:SI T_REG))])])
2093 (define_insn_and_split "*addc_2r_t"
2094 [(set (match_operand:SI 0 "arith_reg_dest")
2095 (plus:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
2097 (match_operand 2 "treg_set_expr")))
2098 (clobber (reg:SI T_REG))]
2099 "TARGET_SH1 && can_create_pseudo_p ()"
2102 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
2104 (clobber (reg:SI T_REG))])])
2106 ;; Convert '(op2 + T) - op3' into 'op2 + (-op3) + T'
2107 (define_insn_and_split "*addc_negreg_t"
2108 [(set (match_operand:SI 0 "arith_reg_dest")
2109 (minus:SI (plus:SI (match_operand 1 "treg_set_expr")
2110 (match_operand:SI 2 "arith_reg_operand"))
2111 (match_operand:SI 3 "arith_reg_operand")))
2112 (clobber (reg:SI T_REG))]
2113 "TARGET_SH1 && can_create_pseudo_p ()"
2116 [(set (match_dup 4) (neg:SI (match_dup 3)))
2117 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 4))
2119 (clobber (reg:SI T_REG))])]
2121 operands[4] = gen_reg_rtx (SImode);
2124 (define_expand "addsi3"
2125 [(set (match_operand:SI 0 "arith_reg_dest")
2126 (plus:SI (match_operand:SI 1 "arith_reg_operand")
2127 (match_operand:SI 2 "arith_or_int_operand")))]
2130 if (TARGET_SH1 && !arith_operand (operands[2], SImode))
2132 if (!sh_lra_p () || reg_overlap_mentioned_p (operands[0], operands[1]))
2134 emit_insn (gen_addsi3_scr (operands[0], operands[1], operands[2]));
2140 (define_insn "addsi3_media"
2141 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2142 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
2143 (match_operand:SI 2 "arith_operand" "r,I10")))]
2148 [(set_attr "type" "arith_media")
2149 (set_attr "highpart" "ignore")])
2151 (define_insn "addsidi3_media"
2152 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
2153 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
2155 (match_operand:SI 2 "arith_operand"
2161 [(set_attr "type" "arith_media")
2162 (set_attr "highpart" "ignore")])
2164 ;; The *addsi3_compact is made an insn_and_split and accepts actually
2165 ;; impossible constraints to make LRA's register elimination work well on SH.
2166 ;; The problem is that LRA expects something like
2167 ;; (set rA (plus rB (const_int N)))
2168 ;; to work. We can do that, but we have to split out an additional reg-reg
2169 ;; copy or constant load before the actual add insn.
2170 ;; Use u constraint for that case to avoid the invalid value in the stack
2172 ;; This also results in better code when LRA is not used. However, we have
2173 ;; to use different sets of patterns and the order of these patterns is
2175 ;; In some cases the constant zero might end up in operands[2] of the
2176 ;; patterns. We have to accept that and convert it into a reg-reg move.
2177 (define_insn_and_split "*addsi3_compact_lra"
2178 [(set (match_operand:SI 0 "arith_reg_dest" "=r,&u")
2179 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r")
2180 (match_operand:SI 2 "arith_or_int_operand" "rI08,rn")))]
2181 "TARGET_SH1 && sh_lra_p ()
2182 && (! reg_overlap_mentioned_p (operands[0], operands[1])
2183 || arith_operand (operands[2], SImode))"
2187 "&& reload_completed
2188 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2189 [(set (match_dup 0) (match_dup 2))
2190 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
2192 /* Prefer 'mov r0,r1; add #imm8,r1' over 'mov #imm8,r1; add r0,r1' */
2193 if (satisfies_constraint_I08 (operands[2]))
2194 std::swap (operands[1], operands[2]);
2196 [(set_attr "type" "arith")])
2198 (define_insn_and_split "addsi3_scr"
2199 [(set (match_operand:SI 0 "arith_reg_dest" "=r,&u,&u")
2200 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r,r")
2201 (match_operand:SI 2 "arith_or_int_operand" "rI08,r,n")))
2202 (clobber (match_scratch:SI 3 "=X,X,&u"))]
2208 "&& reload_completed"
2209 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
2211 if (operands[2] == const0_rtx)
2213 emit_move_insn (operands[0], operands[1]);
2217 if (CONST_INT_P (operands[2]) && !satisfies_constraint_I08 (operands[2]))
2219 if (reg_overlap_mentioned_p (operands[0], operands[1]))
2221 emit_move_insn (operands[3], operands[2]);
2222 emit_move_insn (operands[0], operands[1]);
2223 operands[2] = operands[3];
2227 emit_move_insn (operands[0], operands[2]);
2228 operands[2] = operands[1];
2231 else if (!reg_overlap_mentioned_p (operands[0], operands[1]))
2232 emit_move_insn (operands[0], operands[1]);
2234 [(set_attr "type" "arith")])
2236 (define_insn_and_split "*addsi3"
2237 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2238 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r")
2239 (match_operand:SI 2 "arith_operand" "rI08,Z")))]
2240 "TARGET_SH1 && !sh_lra_p ()"
2244 "&& operands[2] == const0_rtx"
2245 [(set (match_dup 0) (match_dup 1))]
2248 [(set_attr "type" "arith")])
2250 ;; -------------------------------------------------------------------------
2251 ;; Subtraction instructions
2252 ;; -------------------------------------------------------------------------
2254 (define_expand "subdi3"
2255 [(set (match_operand:DI 0 "arith_reg_operand" "")
2256 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
2257 (match_operand:DI 2 "arith_reg_operand" "")))]
2262 operands[1] = force_reg (DImode, operands[1]);
2263 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
2268 (define_insn "*subdi3_media"
2269 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2270 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2271 (match_operand:DI 2 "arith_reg_operand" "r")))]
2274 [(set_attr "type" "arith_media")])
2276 (define_insn "subdisi3_media"
2277 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
2278 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2279 (match_operand:DI 2 "arith_reg_operand" "r")))]
2282 [(set_attr "type" "arith_media")
2283 (set_attr "highpart" "ignore")])
2285 (define_insn_and_split "subdi3_compact"
2286 [(set (match_operand:DI 0 "arith_reg_dest")
2287 (minus:DI (match_operand:DI 1 "arith_reg_operand")
2288 (match_operand:DI 2 "arith_reg_operand")))
2289 (clobber (reg:SI T_REG))]
2292 "&& can_create_pseudo_p ()"
2295 emit_insn (gen_clrt ());
2296 emit_insn (gen_subc (gen_lowpart (SImode, operands[0]),
2297 gen_lowpart (SImode, operands[1]),
2298 gen_lowpart (SImode, operands[2])));
2299 emit_insn (gen_subc (gen_highpart (SImode, operands[0]),
2300 gen_highpart (SImode, operands[1]),
2301 gen_highpart (SImode, operands[2])));
2306 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2307 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2308 (match_operand:SI 2 "arith_reg_operand" "r"))
2311 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
2316 [(set_attr "type" "arith")])
2318 ;; A simplified version of the subc insn, where the exact value of the
2319 ;; T bit doesn't matter. This is easier for combine to pick up.
2320 ;; We allow a reg or 0 for one of the operands in order to be able to
2321 ;; do 'reg - T' sequences. Reload will load the constant 0 into the reg
2323 (define_insn_and_split "*subc"
2324 [(set (match_operand:SI 0 "arith_reg_dest")
2325 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand")
2326 (match_operand:SI 2 "arith_reg_or_0_operand"))
2327 (match_operand 3 "treg_set_expr")))
2328 (clobber (reg:SI T_REG))]
2329 "TARGET_SH1 && can_create_pseudo_p ()"
2334 sh_treg_insns ti = sh_split_treg_set_expr (operands[3], curr_insn);
2335 if (ti.has_trailing_nott ())
2337 if (operands[2] == const0_rtx)
2339 /* op1 - (1 - T) = op1 - 1 + T = op1 + (-1) + T */
2340 remove_insn (ti.trailing_nott ());
2341 emit_insn (gen_addc (operands[0], operands[1],
2342 force_reg (SImode, GEN_INT (-1))));
2345 else if (!TARGET_SH2A)
2347 /* op1 - op2 - (1 - T) = op1 + (0 - op2 - 1) + T = op1 + ~op2 + T
2348 On SH2A keep the nott insn, because nott-subc sequence doesn't
2349 mutate the inputs. */
2350 remove_insn (ti.trailing_nott ());
2351 rtx tmp = gen_reg_rtx (SImode);
2352 emit_insn (gen_one_cmplsi2 (tmp, operands[2]));
2353 emit_insn (gen_addc (operands[0], operands[1], tmp));
2358 emit_insn (gen_subc (operands[0], operands[1],
2359 force_reg (SImode, operands[2])));
2363 ;; Convert reg - T - reg = reg - reg - T
2364 (define_insn_and_split "*subc"
2365 [(set (match_operand:SI 0 "arith_reg_dest")
2366 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand")
2367 (match_operand 2 "treg_set_expr"))
2368 (match_operand:SI 3 "arith_reg_operand")))
2369 (clobber (reg:SI T_REG))]
2370 "TARGET_SH1 && can_create_pseudo_p ()"
2373 [(parallel [(set (match_dup 0)
2374 (minus:SI (minus:SI (match_dup 1) (match_dup 3))
2376 (clobber (reg:SI T_REG))])])
2378 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
2379 ;; better, if the sett insn can be done early.
2380 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
2381 (define_insn_and_split "*subc"
2382 [(set (match_operand:SI 0 "arith_reg_dest" "")
2383 (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
2384 (match_operand:SI 2 "arith_reg_operand" "")))
2385 (clobber (reg:SI T_REG))]
2386 "TARGET_SH1 && can_create_pseudo_p ()"
2389 [(parallel [(set (match_dup 0)
2390 (minus:SI (minus:SI (match_dup 2) (match_dup 1))
2392 (clobber (reg:SI T_REG))])])
2394 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
2395 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2396 ;; operation, as opposed to sequences such as
2400 ;; Even if the constant is not CSE-ed, a sequence such as
2403 ;; can be scheduled much better since the load of the constant can be
2404 ;; done earlier, before any comparison insns that store the result in
2406 ;; However, avoid things like 'reg - 1', which would expand into a
2407 ;; 3 insn sequence, instead of add #imm8.
2408 (define_insn_and_split "*subc"
2409 [(set (match_operand:SI 0 "arith_reg_dest" "")
2410 (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2411 (match_operand 2 "treg_set_expr_not_const01")))
2412 (clobber (reg:SI T_REG))]
2413 "TARGET_SH1 && can_create_pseudo_p ()"
2416 [(parallel [(set (match_dup 0)
2417 (minus:SI (minus:SI (match_dup 1) (const_int 0))
2419 (clobber (reg:SI T_REG))])])
2422 ;; (1 - T) - op2 = 1 - op2 - T
2423 (define_insn_and_split "*subc_negt_reg"
2424 [(set (match_operand:SI 0 "arith_reg_dest")
2425 (minus:SI (match_operand 1 "treg_set_expr_not_const01")
2426 (match_operand:SI 2 "arith_reg_operand")))
2427 (clobber (reg:SI T_REG))]
2428 "TARGET_SH1 && can_create_pseudo_p ()"
2433 sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
2434 if (ti.remove_trailing_nott ())
2436 /* (1 - T) - op2 = 1 - op2 - T */
2437 emit_insn (gen_subc (operands[0],
2438 force_reg (SImode, GEN_INT (1)), operands[2]));
2442 /* T - op2: use movt,sub sequence. */
2443 rtx tmp = gen_reg_rtx (SImode);
2444 emit_insn (gen_movt (tmp, get_t_reg_rtx ()));
2445 emit_insn (gen_subsi3 (operands[0], tmp, operands[2]));
2451 ;; op1 - (1 - T) + op3 = op1 - 1 + T + op3
2452 ;; (op1 - T) + op3 = op1 - (-op3) - T
2453 (define_insn_and_split "*subc_negreg_t"
2454 [(set (match_operand:SI 0 "arith_reg_dest")
2455 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand")
2456 (match_operand 2 "treg_set_expr"))
2457 (match_operand:SI 3 "arith_reg_operand")))
2458 (clobber (reg:SI T_REG))]
2459 "TARGET_SH1 && can_create_pseudo_p ()"
2464 sh_treg_insns ti = sh_split_treg_set_expr (operands[2], curr_insn);
2465 if (ti.remove_trailing_nott ())
2467 /* op1 - (1 - T) + op3 = (op1 - 1) + op3 + T */
2468 rtx tmp = gen_reg_rtx (SImode);
2469 emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (-1)));
2470 emit_insn (gen_addc (operands[0], tmp, operands[3]));
2474 /* (op1 - T) + op3' = 'op1 - (-op3) - T */
2475 rtx tmp = gen_reg_rtx (SImode);
2476 emit_insn (gen_negsi2 (tmp, operands[3]));
2477 emit_insn (gen_subc (operands[0], operands[1], tmp));
2482 (define_insn "*subsi3_internal"
2483 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2484 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2485 (match_operand:SI 2 "arith_reg_operand" "r")))]
2488 [(set_attr "type" "arith")])
2490 (define_insn_and_split "*subsi3_media"
2491 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2492 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2493 (match_operand:SI 2 "extend_reg_operand" "r")))]
2495 && (operands[1] != constm1_rtx
2496 || (GET_CODE (operands[2]) != TRUNCATE
2497 && GET_CODE (operands[2]) != SUBREG))"
2499 "operands[1] == constm1_rtx"
2500 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2502 [(set_attr "type" "arith_media")
2503 (set_attr "highpart" "ignore")])
2506 [(set (match_operand:SI 0 "arith_reg_dest" "")
2507 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2508 "general_extend_operand"
2510 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2511 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2512 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2516 [(set (match_operand:SI 0 "arith_reg_dest" "")
2517 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2518 "general_extend_operand"
2520 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
2521 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2522 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2530 ;; since this will sometimes save one instruction.
2531 ;; Otherwise we might get a sequence like
2535 ;; if the source and dest regs are the same.
2536 (define_expand "subsi3"
2537 [(set (match_operand:SI 0 "arith_reg_operand" "")
2538 (minus:SI (match_operand:SI 1 "arith_operand" "")
2539 (match_operand:SI 2 "arith_reg_operand" "")))]
2542 if (TARGET_SH1 && CONST_INT_P (operands[1]))
2544 emit_insn (gen_negsi2 (operands[0], operands[2]));
2545 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2550 if (!can_create_pseudo_p ()
2551 && ! arith_reg_or_0_operand (operands[1], SImode))
2553 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2554 operands[1] = force_reg (SImode, operands[1]);
2558 ;; -------------------------------------------------------------------------
2559 ;; Division instructions
2560 ;; -------------------------------------------------------------------------
2562 ;; We take advantage of the library routines which don't clobber as many
2563 ;; registers as a normal function call would.
2565 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2566 ;; also has an effect on the register that holds the address of the sfunc.
2567 ;; To make this work, we have an extra dummy insn that shows the use
2568 ;; of this register for reorg.
2570 (define_insn "use_sfunc_addr"
2571 [(set (reg:SI PR_REG)
2572 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2573 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2575 [(set_attr "length" "0")])
2577 (define_insn "udivsi3_sh2a"
2578 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2579 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2580 (match_operand:SI 2 "arith_reg_operand" "z")))]
2583 [(set_attr "type" "arith")
2584 (set_attr "in_delay_slot" "no")])
2586 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2587 ;; hard register 0. If we used hard register 0, then the next instruction
2588 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
2589 ;; gets allocated to a stack slot that needs its address reloaded, then
2590 ;; there is nothing to prevent reload from using r0 to reload the address.
2591 ;; This reload would clobber the value in r0 we are trying to store.
2592 ;; If we let reload allocate r0, then this problem can never happen.
2593 (define_insn "udivsi3_i1"
2594 [(set (match_operand:SI 0 "register_operand" "=z")
2595 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2596 (clobber (reg:SI T_REG))
2597 (clobber (reg:SI PR_REG))
2598 (clobber (reg:SI R1_REG))
2599 (clobber (reg:SI R4_REG))
2600 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2601 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2603 [(set_attr "type" "sfunc")
2604 (set_attr "needs_delay_slot" "yes")])
2606 ; Since shmedia-nofpu code could be linked against shcompact code, and
2607 ; the udivsi3 libcall has the same name, we must consider all registers
2608 ; clobbered that are in the union of the registers clobbered by the
2609 ; shmedia and the shcompact implementation. Note, if the shcompact
2610 ; implementation actually used shcompact code, we'd need to clobber
2611 ; also r23 and fr23.
2612 (define_insn "udivsi3_i1_media"
2613 [(set (match_operand:SI 0 "register_operand" "=z")
2614 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2615 (clobber (reg:SI T_MEDIA_REG))
2616 (clobber (reg:SI PR_MEDIA_REG))
2617 (clobber (reg:SI R20_REG))
2618 (clobber (reg:SI R21_REG))
2619 (clobber (reg:SI R22_REG))
2620 (clobber (reg:DI TR0_REG))
2621 (clobber (reg:DI TR1_REG))
2622 (clobber (reg:DI TR2_REG))
2623 (use (match_operand 1 "target_reg_operand" "b"))]
2624 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2626 [(set_attr "type" "sfunc")
2627 (set_attr "needs_delay_slot" "yes")])
2629 (define_expand "udivsi3_i4_media"
2631 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2633 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2634 (set (match_dup 5) (float:DF (match_dup 3)))
2635 (set (match_dup 6) (float:DF (match_dup 4)))
2636 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2637 (set (match_dup 8) (fix:DI (match_dup 7)))
2638 (set (match_operand:SI 0 "register_operand" "")
2639 (truncate:SI (match_dup 8)))]
2640 "TARGET_SHMEDIA_FPU"
2642 operands[3] = gen_reg_rtx (DImode);
2643 operands[4] = gen_reg_rtx (DImode);
2644 operands[5] = gen_reg_rtx (DFmode);
2645 operands[6] = gen_reg_rtx (DFmode);
2646 operands[7] = gen_reg_rtx (DFmode);
2647 operands[8] = gen_reg_rtx (DImode);
2650 (define_insn "udivsi3_i4"
2651 [(set (match_operand:SI 0 "register_operand" "=y")
2652 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2653 (clobber (reg:SI T_REG))
2654 (clobber (reg:SI PR_REG))
2655 (clobber (reg:DF DR0_REG))
2656 (clobber (reg:DF DR2_REG))
2657 (clobber (reg:DF DR4_REG))
2658 (clobber (reg:SI R0_REG))
2659 (clobber (reg:SI R1_REG))
2660 (clobber (reg:SI R4_REG))
2661 (clobber (reg:SI R5_REG))
2662 (clobber (reg:SI FPSCR_STAT_REG))
2663 (use (match_operand:SI 1 "arith_reg_operand" "r"))
2664 (use (reg:SI FPSCR_MODES_REG))]
2665 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2667 [(set_attr "type" "sfunc")
2668 (set_attr "fp_mode" "double")
2669 (set_attr "needs_delay_slot" "yes")])
2671 (define_insn "udivsi3_i4_single"
2672 [(set (match_operand:SI 0 "register_operand" "=y")
2673 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2674 (clobber (reg:SI T_REG))
2675 (clobber (reg:SI PR_REG))
2676 (clobber (reg:DF DR0_REG))
2677 (clobber (reg:DF DR2_REG))
2678 (clobber (reg:DF DR4_REG))
2679 (clobber (reg:SI R0_REG))
2680 (clobber (reg:SI R1_REG))
2681 (clobber (reg:SI R4_REG))
2682 (clobber (reg:SI R5_REG))
2683 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2684 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2685 && TARGET_FPU_SINGLE"
2687 [(set_attr "type" "sfunc")
2688 (set_attr "needs_delay_slot" "yes")])
2690 (define_insn "udivsi3_i4_int"
2691 [(set (match_operand:SI 0 "register_operand" "=z")
2692 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2693 (clobber (reg:SI T_REG))
2694 (clobber (reg:SI R1_REG))
2695 (clobber (reg:SI PR_REG))
2696 (clobber (reg:SI MACH_REG))
2697 (clobber (reg:SI MACL_REG))
2698 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2701 [(set_attr "type" "sfunc")
2702 (set_attr "needs_delay_slot" "yes")])
2705 (define_expand "udivsi3"
2706 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2707 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2708 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2709 (parallel [(set (match_operand:SI 0 "register_operand" "")
2710 (udiv:SI (reg:SI R4_REG)
2712 (clobber (reg:SI T_REG))
2713 (clobber (reg:SI PR_REG))
2714 (clobber (reg:SI R4_REG))
2715 (use (match_dup 3))])]
2720 operands[3] = gen_reg_rtx (Pmode);
2721 /* Emit the move of the address to a pseudo outside of the libcall. */
2722 if (TARGET_DIVIDE_CALL_TABLE)
2724 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2725 that causes problems when the divide code is supposed to come from a
2726 separate library. Division by zero is undefined, so dividing 1 can be
2727 implemented by comparing with the divisor. */
2728 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2730 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2731 emit_insn (gen_cstoresi4 (operands[0], test,
2732 operands[1], operands[2]));
2735 else if (operands[2] == const0_rtx)
2737 emit_move_insn (operands[0], operands[2]);
2740 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2741 last = gen_udivsi3_i4_int (operands[0], operands[3]);
2743 else if (TARGET_DIVIDE_CALL_FP)
2745 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2746 if (TARGET_FPU_SINGLE)
2747 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2749 last = gen_udivsi3_i4 (operands[0], operands[3]);
2751 else if (TARGET_SHMEDIA_FPU)
2753 operands[1] = force_reg (SImode, operands[1]);
2754 operands[2] = force_reg (SImode, operands[2]);
2755 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2758 else if (TARGET_SH2A)
2760 operands[1] = force_reg (SImode, operands[1]);
2761 operands[2] = force_reg (SImode, operands[2]);
2762 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2765 else if (TARGET_SH5)
2767 function_symbol (operands[3],
2768 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2772 last = gen_udivsi3_i1_media (operands[0], operands[3]);
2773 else if (TARGET_FPU_ANY)
2774 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2776 last = gen_udivsi3_i1 (operands[0], operands[3]);
2780 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2781 last = gen_udivsi3_i1 (operands[0], operands[3]);
2783 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2784 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2789 (define_insn "divsi3_sh2a"
2790 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2791 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2792 (match_operand:SI 2 "arith_reg_operand" "z")))]
2795 [(set_attr "type" "arith")
2796 (set_attr "in_delay_slot" "no")])
2798 (define_insn "divsi3_i1"
2799 [(set (match_operand:SI 0 "register_operand" "=z")
2800 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2801 (clobber (reg:SI T_REG))
2802 (clobber (reg:SI PR_REG))
2803 (clobber (reg:SI R1_REG))
2804 (clobber (reg:SI R2_REG))
2805 (clobber (reg:SI R3_REG))
2806 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2807 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2809 [(set_attr "type" "sfunc")
2810 (set_attr "needs_delay_slot" "yes")])
2812 (define_insn "divsi3_i1_media"
2813 [(set (match_operand:SI 0 "register_operand" "=z")
2814 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2815 (clobber (reg:SI T_MEDIA_REG))
2816 (clobber (reg:SI PR_MEDIA_REG))
2817 (clobber (reg:SI R1_REG))
2818 (clobber (reg:SI R20_REG))
2819 (clobber (reg:SI R21_REG))
2820 (clobber (reg:SI TR0_REG))
2821 (use (match_operand 1 "target_reg_operand" "b"))]
2822 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2824 [(set_attr "type" "sfunc")])
2826 (define_insn "divsi3_media_2"
2827 [(set (match_operand:SI 0 "register_operand" "=z")
2828 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2829 (clobber (reg:SI T_MEDIA_REG))
2830 (clobber (reg:SI PR_MEDIA_REG))
2831 (clobber (reg:SI R1_REG))
2832 (clobber (reg:SI R21_REG))
2833 (clobber (reg:SI TR0_REG))
2834 (use (reg:SI R20_REG))
2835 (use (match_operand 1 "target_reg_operand" "b"))]
2836 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2838 [(set_attr "type" "sfunc")])
2840 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2841 ;; hard reg clobbers and data dependencies that we need when we want
2842 ;; to rematerialize the division into a call.
2843 (define_insn_and_split "divsi_inv_call"
2844 [(set (match_operand:SI 0 "register_operand" "=r")
2845 (div:SI (match_operand:SI 1 "register_operand" "r")
2846 (match_operand:SI 2 "register_operand" "r")))
2847 (clobber (reg:SI R4_REG))
2848 (clobber (reg:SI R5_REG))
2849 (clobber (reg:SI T_MEDIA_REG))
2850 (clobber (reg:SI PR_MEDIA_REG))
2851 (clobber (reg:SI R1_REG))
2852 (clobber (reg:SI R21_REG))
2853 (clobber (reg:SI TR0_REG))
2854 (clobber (reg:SI R20_REG))
2855 (use (match_operand:SI 3 "register_operand" "r"))]
2858 "&& (reload_in_progress || reload_completed)"
2859 [(set (match_dup 0) (match_dup 3))]
2861 [(set_attr "highpart" "must_split")])
2863 ;; This is the combiner pattern for -mdiv=inv:call .
2864 (define_insn_and_split "*divsi_inv_call_combine"
2865 [(set (match_operand:SI 0 "register_operand" "=z")
2866 (div:SI (match_operand:SI 1 "register_operand" "r")
2867 (match_operand:SI 2 "register_operand" "r")))
2868 (clobber (reg:SI R4_REG))
2869 (clobber (reg:SI R5_REG))
2870 (clobber (reg:SI T_MEDIA_REG))
2871 (clobber (reg:SI PR_MEDIA_REG))
2872 (clobber (reg:SI R1_REG))
2873 (clobber (reg:SI R21_REG))
2874 (clobber (reg:SI TR0_REG))
2875 (clobber (reg:SI R20_REG))
2876 (use (unspec:SI [(match_dup 1)
2877 (match_operand:SI 3 "" "")
2878 (unspec:SI [(match_operand:SI 4 "" "")
2880 (match_operand:DI 5 "" "")]
2882 (match_operand:DI 6 "" "")
2885 UNSPEC_DIV_INV_M3))]
2888 "&& (reload_in_progress || reload_completed)"
2891 const char *name = sh_divsi3_libfunc;
2892 enum sh_function_kind kind = SFUNC_GOT;
2895 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2896 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2897 while (TARGET_DIVIDE_INV_CALL2)
2899 rtx x = operands[3];
2901 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2903 x = XVECEXP (x, 0, 0);
2904 name = "__sdivsi3_2";
2905 kind = SFUNC_STATIC;
2906 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2909 sym = function_symbol (NULL, name, kind);
2910 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2913 [(set_attr "highpart" "must_split")])
2915 (define_expand "divsi3_i4_media"
2916 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2917 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2918 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2919 (set (match_operand:SI 0 "register_operand" "=r")
2920 (fix:SI (match_dup 5)))]
2921 "TARGET_SHMEDIA_FPU"
2923 operands[3] = gen_reg_rtx (DFmode);
2924 operands[4] = gen_reg_rtx (DFmode);
2925 operands[5] = gen_reg_rtx (DFmode);
2928 (define_insn "divsi3_i4"
2929 [(set (match_operand:SI 0 "register_operand" "=y")
2930 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2931 (clobber (reg:SI PR_REG))
2932 (clobber (reg:DF DR0_REG))
2933 (clobber (reg:DF DR2_REG))
2934 (clobber (reg:SI FPSCR_STAT_REG))
2935 (use (match_operand:SI 1 "arith_reg_operand" "r"))
2936 (use (reg:SI FPSCR_MODES_REG))]
2937 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2939 [(set_attr "type" "sfunc")
2940 (set_attr "fp_mode" "double")
2941 (set_attr "needs_delay_slot" "yes")])
2943 (define_insn "divsi3_i4_single"
2944 [(set (match_operand:SI 0 "register_operand" "=y")
2945 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2946 (clobber (reg:SI PR_REG))
2947 (clobber (reg:DF DR0_REG))
2948 (clobber (reg:DF DR2_REG))
2949 (clobber (reg:SI R2_REG))
2950 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2951 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2952 && TARGET_FPU_SINGLE"
2954 [(set_attr "type" "sfunc")
2955 (set_attr "needs_delay_slot" "yes")])
2957 (define_insn "divsi3_i4_int"
2958 [(set (match_operand:SI 0 "register_operand" "=z")
2959 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2960 (clobber (reg:SI T_REG))
2961 (clobber (reg:SI PR_REG))
2962 (clobber (reg:SI R1_REG))
2963 (clobber (reg:SI MACH_REG))
2964 (clobber (reg:SI MACL_REG))
2965 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2968 [(set_attr "type" "sfunc")
2969 (set_attr "needs_delay_slot" "yes")])
2971 (define_expand "divsi3"
2972 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2973 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2974 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2975 (parallel [(set (match_operand:SI 0 "register_operand" "")
2976 (div:SI (reg:SI R4_REG)
2978 (clobber (reg:SI T_REG))
2979 (clobber (reg:SI PR_REG))
2980 (clobber (reg:SI R1_REG))
2981 (clobber (reg:SI R2_REG))
2982 (clobber (reg:SI R3_REG))
2983 (use (match_dup 3))])]
2988 operands[3] = gen_reg_rtx (Pmode);
2989 /* Emit the move of the address to a pseudo outside of the libcall. */
2990 if (TARGET_DIVIDE_CALL_TABLE)
2992 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2993 last = gen_divsi3_i4_int (operands[0], operands[3]);
2995 else if (TARGET_DIVIDE_CALL_FP)
2997 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2998 if (TARGET_FPU_SINGLE)
2999 last = gen_divsi3_i4_single (operands[0], operands[3]);
3001 last = gen_divsi3_i4 (operands[0], operands[3]);
3003 else if (TARGET_SH2A)
3005 operands[1] = force_reg (SImode, operands[1]);
3006 operands[2] = force_reg (SImode, operands[2]);
3007 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
3010 else if (TARGET_DIVIDE_INV)
3012 rtx dividend = operands[1];
3013 rtx divisor = operands[2];
3015 rtx nsb_res = gen_reg_rtx (DImode);
3016 rtx norm64 = gen_reg_rtx (DImode);
3017 rtx tab_ix = gen_reg_rtx (DImode);
3018 rtx norm32 = gen_reg_rtx (SImode);
3019 rtx i92 = force_reg (DImode, GEN_INT (92));
3020 rtx scratch0a = gen_reg_rtx (DImode);
3021 rtx scratch0b = gen_reg_rtx (DImode);
3022 rtx inv0 = gen_reg_rtx (SImode);
3023 rtx scratch1a = gen_reg_rtx (DImode);
3024 rtx scratch1b = gen_reg_rtx (DImode);
3025 rtx shift = gen_reg_rtx (DImode);
3027 rtx inv1 = gen_reg_rtx (SImode);
3028 rtx scratch2a = gen_reg_rtx (DImode);
3029 rtx scratch2b = gen_reg_rtx (SImode);
3030 rtx inv2 = gen_reg_rtx (SImode);
3031 rtx scratch3a = gen_reg_rtx (DImode);
3032 rtx scratch3b = gen_reg_rtx (DImode);
3033 rtx scratch3c = gen_reg_rtx (DImode);
3034 rtx scratch3d = gen_reg_rtx (SImode);
3035 rtx scratch3e = gen_reg_rtx (DImode);
3036 rtx result = gen_reg_rtx (SImode);
3038 if (! arith_reg_or_0_operand (dividend, SImode))
3039 dividend = force_reg (SImode, dividend);
3040 if (! arith_reg_operand (divisor, SImode))
3041 divisor = force_reg (SImode, divisor);
3042 if (flag_pic && Pmode != DImode)
3044 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
3045 tab_base = gen_datalabel_ref (tab_base);
3046 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
3050 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
3051 tab_base = gen_datalabel_ref (tab_base);
3052 tab_base = force_reg (DImode, tab_base);
3054 if (TARGET_DIVIDE_INV20U)
3055 i2p27 = force_reg (DImode, GEN_INT ((unsigned HOST_WIDE_INT)-2 << 27));
3057 i2p27 = GEN_INT (0);
3058 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
3059 i43 = force_reg (DImode, GEN_INT (43));
3062 emit_insn (gen_nsbdi (nsb_res,
3063 simplify_gen_subreg (DImode, divisor, SImode, 0)));
3064 emit_insn (gen_ashldi3_media (norm64,
3065 gen_rtx_SUBREG (DImode, divisor, 0),
3067 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
3068 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
3069 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
3070 inv0, scratch0a, scratch0b,
3071 scratch1a, scratch1b));
3072 emit_insn (gen_subdi3 (shift, i92, nsb_res));
3073 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
3075 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
3077 scratch3a, scratch3b, scratch3c,
3078 scratch2a, scratch2b, scratch3d, scratch3e));
3079 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
3080 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
3081 else if (TARGET_DIVIDE_INV_FP)
3082 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
3083 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
3084 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
3085 gen_reg_rtx (DFmode)));
3087 emit_move_insn (operands[0], result);
3090 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
3092 operands[1] = force_reg (SImode, operands[1]);
3093 operands[2] = force_reg (SImode, operands[2]);
3094 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
3097 else if (TARGET_SH5)
3099 if (TARGET_DIVIDE_CALL2)
3101 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
3102 tab_base = gen_datalabel_ref (tab_base);
3103 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
3105 if (TARGET_FPU_ANY && TARGET_SH1)
3106 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
3107 else if (TARGET_DIVIDE_CALL2)
3108 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
3110 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
3113 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
3114 (operands[0], operands[3]));
3115 else if (TARGET_FPU_ANY)
3116 last = gen_divsi3_i4_single (operands[0], operands[3]);
3118 last = gen_divsi3_i1 (operands[0], operands[3]);
3122 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
3123 last = gen_divsi3_i1 (operands[0], operands[3]);
3125 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
3126 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
3131 ;; operands: scratch, tab_base, tab_ix
3132 ;; These are unspecs because we could generate an indexed addressing mode
3133 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
3134 ;; confuse reload. See PR27117.
3135 (define_insn "divsi_inv_qitable"
3136 [(set (match_operand:DI 0 "register_operand" "=r")
3137 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
3138 (match_operand:DI 2 "register_operand" "r")]
3139 UNSPEC_DIV_INV_TABLE)))]
3142 [(set_attr "type" "load_media")
3143 (set_attr "highpart" "user")])
3145 ;; operands: scratch, tab_base, tab_ix
3146 (define_insn "divsi_inv_hitable"
3147 [(set (match_operand:DI 0 "register_operand" "=r")
3148 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
3149 (match_operand:DI 2 "register_operand" "r")]
3150 UNSPEC_DIV_INV_TABLE)))]
3153 [(set_attr "type" "load_media")
3154 (set_attr "highpart" "user")])
3156 ;; operands: inv0, tab_base, tab_ix, norm32
3157 ;; scratch equiv in sdivsi3_2: r19, r21
3158 (define_expand "divsi_inv_m0"
3159 [(set (match_operand:SI 0 "register_operand" "=r")
3160 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
3161 (match_operand:DI 2 "register_operand" "r")
3162 (match_operand:SI 3 "register_operand" "r")]
3164 (clobber (match_operand:DI 4 "register_operand" "=r"))
3165 (clobber (match_operand:DI 5 "register_operand" "=r"))]
3172 ldx.ub r20, r21, r19 // u0.8
3174 muls.l r25, r19, r19 // s2.38
3175 ldx.w r20, r21, r21 // s2.14
3176 shari r19, 24, r19 // truncate to s2.14
3177 sub r21, r19, r19 // some 11 bit inverse in s1.14
3180 rtx inv0 = operands[0];
3181 rtx tab_base = operands[1];
3182 rtx tab_ix = operands[2];
3183 rtx norm32 = operands[3];
3184 rtx scratch0 = operands[4];
3185 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3186 rtx scratch1 = operands[5];
3188 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
3189 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
3190 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
3191 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
3192 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
3193 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
3197 ;; operands: inv1, tab_base, tab_ix, norm32
3198 (define_insn_and_split "divsi_inv_m1"
3199 [(set (match_operand:SI 0 "register_operand" "=r")
3200 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
3201 (match_operand:DI 2 "register_operand" "r")
3202 (match_operand:SI 3 "register_operand" "r")]
3204 (clobber (match_operand:SI 4 "register_operand" "=r"))
3205 (clobber (match_operand:DI 5 "register_operand" "=r"))
3206 (clobber (match_operand:DI 6 "register_operand" "=r"))
3207 (clobber (match_operand:DI 7 "register_operand" "=r"))
3208 (clobber (match_operand:DI 8 "register_operand" "=r"))]
3211 "&& !can_create_pseudo_p ()"
3215 muls.l r19, r19, r18 // u0.28
3216 muls.l r25, r18, r18 // s2.58
3217 shlli r19, 45, r0 // multiply by two and convert to s2.58
3219 shari r18, 28, r18 // some 18 bit inverse in s1.30
3222 rtx inv1 = operands[0];
3223 rtx tab_base = operands[1];
3224 rtx tab_ix = operands[2];
3225 rtx norm32 = operands[3];
3226 rtx inv0 = operands[4];
3227 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
3228 rtx scratch0a = operands[5];
3229 rtx scratch0b = operands[6];
3230 rtx scratch0 = operands[7];
3231 rtx scratch1 = operands[8];
3232 rtx scratch1_si = gen_lowpart (SImode, scratch1);
3234 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
3235 scratch0a, scratch0b));
3236 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
3237 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
3238 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
3239 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
3240 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
3244 ;; operands: inv2, norm32, inv1, i92
3245 (define_insn_and_split "divsi_inv_m2"
3246 [(set (match_operand:SI 0 "register_operand" "=r")
3247 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3248 (match_operand:SI 2 "register_operand" "r")
3249 (match_operand:DI 3 "register_operand" "r")]
3251 (clobber (match_operand:DI 4 "register_operand" "=r"))]
3254 "&& !can_create_pseudo_p ()"
3258 muls.l r18, r25, r0 // s2.60
3259 shari r0, 16, r0 // s-16.44
3261 muls.l r0, r18, r19 // s-16.74
3262 shari r19, 30, r19 // s-16.44
3264 rtx inv2 = operands[0];
3265 rtx norm32 = operands[1];
3266 rtx inv1 = operands[2];
3267 rtx i92 = operands[3];
3268 rtx scratch0 = operands[4];
3269 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3271 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
3272 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
3273 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
3274 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
3275 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
3279 (define_insn_and_split "divsi_inv_m3"
3280 [(set (match_operand:SI 0 "register_operand" "=r")
3281 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3282 (match_operand:SI 2 "register_operand" "r")
3283 (match_operand:SI 3 "register_operand" "r")
3284 (match_operand:DI 4 "register_operand" "r")
3285 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
3286 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
3288 (clobber (match_operand:DI 7 "register_operand" "=r"))
3289 (clobber (match_operand:DI 8 "register_operand" "=r"))
3290 (clobber (match_operand:DI 9 "register_operand" "=r"))
3291 (clobber (match_operand:DI 10 "register_operand" "=r"))
3292 (clobber (match_operand:SI 11 "register_operand" "=r"))
3293 (clobber (match_operand:SI 12 "register_operand" "=r"))
3294 (clobber (match_operand:DI 13 "register_operand" "=r"))]
3297 "&& !can_create_pseudo_p ()"
3301 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
3302 r0: scratch0 r19: scratch1 r21: scratch2
3304 muls.l r18, r4, r25 // s32.30
3305 muls.l r19, r4, r19 // s15.30
3307 shari r19, 14, r19 // s18.-14
3313 rtx result = operands[0];
3314 rtx dividend = operands[1];
3315 rtx inv1 = operands[2];
3316 rtx inv2 = operands[3];
3317 rtx shift = operands[4];
3318 rtx scratch0 = operands[7];
3319 rtx scratch1 = operands[8];
3320 rtx scratch2 = operands[9];
3322 if (satisfies_constraint_N (dividend))
3324 emit_move_insn (result, dividend);
3328 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
3329 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
3330 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
3331 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
3332 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
3333 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
3334 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
3338 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
3339 ;; inv1: tab_base, tab_ix, norm32
3340 ;; inv2: norm32, inv1, i92
3341 (define_insn_and_split "divsi_inv_m1_3"
3342 [(set (match_operand:SI 0 "register_operand" "=r")
3343 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3344 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
3345 (match_operand:DI 3 "register_operand" "r")
3346 (match_operand:SI 4 "register_operand" "r")]
3348 (unspec:SI [(match_dup 4)
3349 (unspec:SI [(match_dup 2)
3351 (match_dup 4)] UNSPEC_DIV_INV_M1)
3352 (match_operand:SI 5 "" "")]
3354 (match_operand:DI 6 "register_operand" "r")
3355 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
3356 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
3358 (clobber (match_operand:DI 9 "register_operand" "=r"))
3359 (clobber (match_operand:DI 10 "register_operand" "=r"))
3360 (clobber (match_operand:DI 11 "register_operand" "=r"))
3361 (clobber (match_operand:DI 12 "register_operand" "=r"))
3362 (clobber (match_operand:SI 13 "register_operand" "=r"))
3363 (clobber (match_operand:SI 14 "register_operand" "=r"))
3364 (clobber (match_operand:DI 15 "register_operand" "=r"))]
3366 && (TARGET_DIVIDE_INV_MINLAT
3367 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3369 "&& !can_create_pseudo_p ()"
3372 rtx result = operands[0];
3373 rtx dividend = operands[1];
3374 rtx tab_base = operands[2];
3375 rtx tab_ix = operands[3];
3376 rtx norm32 = operands[4];
3377 /* rtx i92 = operands[5]; */
3378 rtx shift = operands[6];
3379 rtx i2p27 = operands[7];
3380 rtx i43 = operands[8];
3381 rtx scratch0 = operands[9];
3382 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3383 rtx scratch1 = operands[10];
3384 rtx scratch1_si = gen_lowpart (SImode, scratch1);
3385 rtx scratch2 = operands[11];
3386 rtx scratch3 = operands[12];
3387 rtx scratch4 = operands[13];
3388 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
3389 rtx scratch5 = operands[14];
3390 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
3391 rtx scratch6 = operands[15];
3393 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
3394 scratch0, scratch1));
3395 /* inv0 == scratch4 */
3396 if (! TARGET_DIVIDE_INV20U)
3398 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
3400 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
3404 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
3405 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
3407 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
3408 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
3409 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
3410 /* inv1 == scratch4 */
3412 if (TARGET_DIVIDE_INV_MINLAT)
3414 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
3415 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
3416 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
3417 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
3418 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
3419 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
3420 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
3421 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
3422 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
3423 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
3424 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
3428 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
3429 /* Use separate scratch regs for nsb and sign to allow scheduling. */
3430 emit_insn (gen_nsbdi (scratch6,
3431 simplify_gen_subreg (DImode, dividend, SImode, 0)));
3432 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
3433 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
3434 emit_insn (gen_divsi_inv20 (scratch2,
3435 norm32, scratch4, dividend,
3436 scratch6, scratch3, i43,
3437 /* scratch0 may be shared with i2p27. */
3438 scratch0, scratch1, scratch5,
3439 label, label, i2p27));
3441 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
3442 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
3446 (define_insn "divsi_inv20"
3447 [(set (match_operand:DI 0 "register_operand" "=&r")
3448 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
3449 (match_operand:SI 2 "register_operand" "r")
3450 (match_operand:SI 3 "register_operand" "r")
3451 (match_operand:DI 4 "register_operand" "r")
3452 (match_operand:DI 5 "register_operand" "r")
3453 (match_operand:DI 6 "register_operand" "r")
3454 (match_operand:DI 12 "register_operand" "r")
3455 (match_operand 10 "target_operand" "b")
3456 (match_operand 11 "immediate_operand" "i")]
3458 (clobber (match_operand:DI 7 "register_operand" "=&r"))
3459 (clobber (match_operand:DI 8 "register_operand" "=&r"))
3460 (clobber (match_operand:SI 9 "register_operand" "=r"))]
3462 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3464 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
3465 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
3466 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
3467 %10 label (tr), %11 label (imm)
3469 muls.l inv1, norm32, scratch0 // s2.60
3470 muls.l inv1, dividend, result // s32.30
3471 xor i2p27, result_sign, round_scratch
3472 bge/u dividend_nsb, i43, tr.. (label)
3473 shari scratch0, 16, scratch0 // s-16.44
3474 muls.l sratch0_si, inv1, scratch0 // s-16.74
3475 sub result, round_scratch, result
3476 shari dividend, 14, scratch1 // s19.-14
3477 shari scratch0, 30, scratch0 // s-16.44
3478 muls.l scratch0, scratch1, round_scratch // s15.30
3480 sub result, round_scratch, result */
3482 const bool likely = TARGET_DIVIDE_INV20L;
3485 "muls.l %2, %3, %0" "\n"
3486 " xor %12, %5, %7" "\n"
3487 " bge/l %4, %6, %10" "\n"
3488 " muls.l %2, %1, %8" "\n"
3489 " shari %8, 16, %8" "\n"
3490 " muls.l %8, %2, %8" "\n"
3491 " shari %3, 14, %9" "\n"
3492 " shari %8, 30, %8" "\n"
3493 " muls.l %8, %9, %8" "\n"
3494 " sub %0, %8, %0" "\n"
3495 "%11: add %0, %7, %0";
3498 "muls.l %2, %1, %8" "\n"
3499 " muls.l %2, %3, %0" "\n"
3500 " xor %12, %5, %7" "\n"
3501 " bge/u %4, %6, %10" "\n"
3502 " shari %8, 16, %8" "\n"
3503 " muls.l %8, %2, %8" "\n"
3504 " sub %0, %7, %0" "\n"
3505 " shari %3, 14, %9" "\n"
3506 " shari %8, 30, %8" "\n"
3507 " muls.l %8, %9, %7" "\n"
3508 "%11: sub %0, %7, %0";
3511 (define_insn_and_split "divsi_inv_fp"
3512 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3513 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3514 (match_operand:SI 2 "register_operand" "rf")))
3515 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3516 (clobber (match_operand:SI 4 "register_operand" "=r"))
3517 (clobber (match_operand:SI 5 "register_operand" "=r"))
3518 (clobber (match_operand:DF 6 "register_operand" "=r"))
3519 (clobber (match_operand:DF 7 "register_operand" "=r"))
3520 (clobber (match_operand:DF 8 "register_operand" "=r"))]
3521 "TARGET_SHMEDIA_FPU"
3523 "&& (reload_in_progress || reload_completed)"
3524 [(set (match_dup 0) (match_dup 3))]
3526 [(set_attr "highpart" "must_split")])
3528 ;; If a matching group of divide-by-inverse instructions is in the same
3529 ;; basic block after gcse & loop optimizations, we want to transform them
3530 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3531 (define_insn_and_split "*divsi_inv_fp_combine"
3532 [(set (match_operand:SI 0 "register_operand" "=f")
3533 (div:SI (match_operand:SI 1 "register_operand" "f")
3534 (match_operand:SI 2 "register_operand" "f")))
3535 (use (unspec:SI [(match_dup 1)
3536 (match_operand:SI 3 "" "")
3537 (unspec:SI [(match_operand:SI 4 "" "")
3539 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3540 (match_operand:DI 6 "" "")
3542 (const_int 0)] UNSPEC_DIV_INV_M3))
3543 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3544 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3545 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3546 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3547 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3548 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3551 [(set (match_dup 9) (float:DF (match_dup 1)))
3552 (set (match_dup 10) (float:DF (match_dup 2)))
3553 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3555 (fix:SI (match_dup 11)))
3556 (set (match_dup 0) (match_dup 8))]
3558 if (! fp_arith_reg_operand (operands[1], SImode))
3560 emit_move_insn (operands[7], operands[1]);
3561 operands[1] = operands[7];
3563 if (! fp_arith_reg_operand (operands[2], SImode))
3565 emit_move_insn (operands[8], operands[2]);
3566 operands[2] = operands[8];
3569 [(set_attr "highpart" "must_split")])
3571 ;; -------------------------------------------------------------------------
3572 ;; Multiplication instructions
3573 ;; -------------------------------------------------------------------------
3575 (define_insn "umulhisi3_i"
3576 [(set (reg:SI MACL_REG)
3577 (mult:SI (zero_extend:SI
3578 (match_operand:HI 0 "arith_reg_operand" "r"))
3580 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3583 [(set_attr "type" "smpy")])
3585 (define_insn "mulhisi3_i"
3586 [(set (reg:SI MACL_REG)
3587 (mult:SI (sign_extend:SI
3588 (match_operand:HI 0 "arith_reg_operand" "r"))
3590 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3593 [(set_attr "type" "smpy")])
3595 (define_expand "mulhisi3"
3596 [(set (reg:SI MACL_REG)
3597 (mult:SI (sign_extend:SI
3598 (match_operand:HI 1 "arith_reg_operand" ""))
3600 (match_operand:HI 2 "arith_reg_operand" ""))))
3601 (set (match_operand:SI 0 "arith_reg_operand" "")
3608 macl = gen_rtx_REG (SImode, MACL_REG);
3610 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3611 insn = get_insns ();
3613 /* expand_binop can't find a suitable code in umul_widen_optab to
3614 make a REG_EQUAL note from, so make one here.
3615 See also smulsi3_highpart.
3616 ??? Alternatively, we could put this at the calling site of expand_binop,
3617 i.e. expand_expr. */
3618 /* Use emit_libcall_block for loop invariant code motion and to make
3619 a REG_EQUAL note. */
3620 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3625 (define_expand "umulhisi3"
3626 [(set (reg:SI MACL_REG)
3627 (mult:SI (zero_extend:SI
3628 (match_operand:HI 1 "arith_reg_operand" ""))
3630 (match_operand:HI 2 "arith_reg_operand" ""))))
3631 (set (match_operand:SI 0 "arith_reg_operand" "")
3638 macl = gen_rtx_REG (SImode, MACL_REG);
3640 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3641 insn = get_insns ();
3643 /* expand_binop can't find a suitable code in umul_widen_optab to
3644 make a REG_EQUAL note from, so make one here.
3645 See also smulsi3_highpart.
3646 ??? Alternatively, we could put this at the calling site of expand_binop,
3647 i.e. expand_expr. */
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], macl, SET_SRC (single_set (insn)));
3655 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3656 ;; a call to a routine which clobbers known registers.
3658 [(set (match_operand:SI 1 "register_operand" "=z")
3659 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3660 (clobber (reg:SI MACL_REG))
3661 (clobber (reg:SI T_REG))
3662 (clobber (reg:SI PR_REG))
3663 (clobber (reg:SI R3_REG))
3664 (clobber (reg:SI R2_REG))
3665 (clobber (reg:SI R1_REG))
3666 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3669 [(set_attr "type" "sfunc")
3670 (set_attr "needs_delay_slot" "yes")])
3672 (define_expand "mulsi3_call"
3673 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3674 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3675 (parallel[(set (match_operand:SI 0 "register_operand" "")
3676 (mult:SI (reg:SI R4_REG)
3678 (clobber (reg:SI MACL_REG))
3679 (clobber (reg:SI T_REG))
3680 (clobber (reg:SI PR_REG))
3681 (clobber (reg:SI R3_REG))
3682 (clobber (reg:SI R2_REG))
3683 (clobber (reg:SI R1_REG))
3684 (use (match_operand:SI 3 "register_operand" ""))])]
3688 (define_insn "mul_r"
3689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691 (match_operand:SI 2 "arith_reg_operand" "z")))]
3694 [(set_attr "type" "dmpy")])
3696 (define_insn "mul_l"
3697 [(set (reg:SI MACL_REG)
3698 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3699 (match_operand:SI 1 "arith_reg_operand" "r")))]
3702 [(set_attr "type" "dmpy")])
3704 (define_expand "mulsi3"
3705 [(set (reg:SI MACL_REG)
3706 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
3707 (match_operand:SI 2 "arith_reg_operand" "")))
3708 (set (match_operand:SI 0 "arith_reg_operand" "")
3714 /* The address must be set outside the libcall,
3715 since it goes into a pseudo. */
3716 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3717 rtx addr = force_reg (SImode, sym);
3718 rtx insns = gen_mulsi3_call (operands[0], operands[1],
3724 rtx macl = gen_rtx_REG (SImode, MACL_REG);
3726 emit_insn (gen_mul_l (operands[1], operands[2]));
3727 /* consec_sets_giv can only recognize the first insn that sets a
3728 giv as the giv insn. So we must tag this also with a REG_EQUAL
3730 emit_insn (gen_movsi_i ((operands[0]), macl));
3735 (define_insn "mulsidi3_i"
3736 [(set (reg:SI MACH_REG)
3740 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3741 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3743 (set (reg:SI MACL_REG)
3744 (mult:SI (match_dup 0)
3748 [(set_attr "type" "dmpy")])
3750 (define_expand "mulsidi3"
3751 [(set (match_operand:DI 0 "arith_reg_dest" "")
3752 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3753 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3754 "TARGET_SH2 || TARGET_SHMEDIA"
3758 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3763 (define_insn "mulsidi3_media"
3764 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3765 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3766 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3769 [(set_attr "type" "dmpy_media")
3770 (set_attr "highpart" "ignore")])
3772 (define_insn_and_split "mulsidi3_compact"
3773 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3775 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3776 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3777 (clobber (reg:SI MACH_REG))
3778 (clobber (reg:SI MACL_REG))]
3784 rtx low_dst = gen_lowpart (SImode, operands[0]);
3785 rtx high_dst = gen_highpart (SImode, operands[0]);
3787 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3789 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3790 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3791 /* We need something to tag the possible REG_EQUAL notes on to. */
3792 emit_move_insn (operands[0], operands[0]);
3796 (define_insn "umulsidi3_i"
3797 [(set (reg:SI MACH_REG)
3801 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3802 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3804 (set (reg:SI MACL_REG)
3805 (mult:SI (match_dup 0)
3809 [(set_attr "type" "dmpy")])
3811 (define_expand "umulsidi3"
3812 [(set (match_operand:DI 0 "arith_reg_dest" "")
3813 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3814 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3815 "TARGET_SH2 || TARGET_SHMEDIA"
3819 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3824 (define_insn "umulsidi3_media"
3825 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3826 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3827 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3830 [(set_attr "type" "dmpy_media")
3831 (set_attr "highpart" "ignore")])
3833 (define_insn_and_split "umulsidi3_compact"
3834 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3836 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3837 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3838 (clobber (reg:SI MACH_REG))
3839 (clobber (reg:SI MACL_REG))]
3845 rtx low_dst = gen_lowpart (SImode, operands[0]);
3846 rtx high_dst = gen_highpart (SImode, operands[0]);
3848 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3850 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3851 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3852 /* We need something to tag the possible REG_EQUAL notes on to. */
3853 emit_move_insn (operands[0], operands[0]);
3857 (define_insn "smulsi3_highpart_i"
3858 [(set (reg:SI MACH_REG)
3862 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3863 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3865 (clobber (reg:SI MACL_REG))]
3868 [(set_attr "type" "dmpy")])
3870 (define_expand "smulsi3_highpart"
3872 [(set (reg:SI MACH_REG)
3876 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3877 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3879 (clobber (reg:SI MACL_REG))])
3880 (set (match_operand:SI 0 "arith_reg_operand" "")
3887 mach = gen_rtx_REG (SImode, MACH_REG);
3889 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3890 insn = get_insns ();
3892 /* expand_binop can't find a suitable code in mul_highpart_optab to
3893 make a REG_EQUAL note from, so make one here.
3894 See also {,u}mulhisi.
3895 ??? Alternatively, we could put this at the calling site of expand_binop,
3896 i.e. expand_mult_highpart. */
3897 /* Use emit_libcall_block for loop invariant code motion and to make
3898 a REG_EQUAL note. */
3899 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3904 (define_insn "umulsi3_highpart_i"
3905 [(set (reg:SI MACH_REG)
3909 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3910 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3912 (clobber (reg:SI MACL_REG))]
3915 [(set_attr "type" "dmpy")])
3917 (define_expand "umulsi3_highpart"
3919 [(set (reg:SI MACH_REG)
3923 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3924 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3926 (clobber (reg:SI MACL_REG))])
3927 (set (match_operand:SI 0 "arith_reg_operand" "")
3934 mach = gen_rtx_REG (SImode, MACH_REG);
3936 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3937 insn = get_insns ();
3939 /* Use emit_libcall_block for loop invariant code motion and to make
3940 a REG_EQUAL note. */
3941 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3946 (define_insn_and_split "muldi3"
3947 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3949 (match_operand:DI 2 "arith_reg_operand" "r")))
3950 (clobber (match_scratch:DI 3 "=&r"))
3951 (clobber (match_scratch:DI 4 "=r"))]
3957 rtx op3_v2si, op2_v2si;
3959 op3_v2si = operands[3];
3960 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3962 op3_v2si = XEXP (op3_v2si, 0);
3963 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3965 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3966 op2_v2si = operands[2];
3967 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3969 op2_v2si = XEXP (op2_v2si, 0);
3970 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3972 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3973 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3974 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3975 emit_insn (gen_umulsidi3_media (operands[4],
3976 sh_gen_truncate (SImode, operands[1], 0),
3977 sh_gen_truncate (SImode, operands[2], 0)));
3978 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3979 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3980 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3981 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3985 ;; -------------------------------------------------------------------------
3986 ;; Logical operations
3987 ;; -------------------------------------------------------------------------
3989 (define_expand "andsi3"
3990 [(set (match_operand:SI 0 "arith_reg_operand" "")
3991 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3992 (match_operand:SI 2 "logical_and_operand" "")))]
3995 /* If it is possible to turn the and insn into a zero extension
3996 already, redundant zero extensions will be folded, which results
3998 Ideally the splitter of *andsi_compact would be enough, if redundant
3999 zero extensions were detected after the combine pass, which does not
4000 happen at the moment. */
4003 if (satisfies_constraint_Jmb (operands[2]))
4005 emit_insn (gen_zero_extendqisi2 (operands[0],
4006 gen_lowpart (QImode, operands[1])));
4009 else if (satisfies_constraint_Jmw (operands[2]))
4011 emit_insn (gen_zero_extendhisi2 (operands[0],
4012 gen_lowpart (HImode, operands[1])));
4018 (define_insn_and_split "*andsi_compact"
4019 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
4020 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
4021 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
4029 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
4031 if (satisfies_constraint_Jmb (operands[2]))
4032 operands[1] = gen_lowpart (QImode, operands[1]);
4033 else if (satisfies_constraint_Jmw (operands[2]))
4034 operands[1] = gen_lowpart (HImode, operands[1]);
4038 [(set_attr "type" "arith")])
4040 (define_insn "*andsi3_media"
4041 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4042 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
4043 (match_operand:SI 2 "logical_operand" "r,I10")))]
4048 [(set_attr "type" "arith_media")])
4050 (define_insn "*andsi3_bclr"
4051 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4052 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
4053 (match_operand:SI 2 "const_int_operand" "Psz")))]
4054 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
4056 [(set_attr "type" "arith")])
4058 (define_insn_and_split "anddi3"
4059 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
4060 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
4061 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
4068 && ! logical_operand (operands[2], DImode)"
4071 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
4072 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
4074 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
4077 [(set_attr "type" "arith_media")])
4079 (define_insn "andcsi3"
4080 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4081 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
4082 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4085 [(set_attr "type" "arith_media")])
4087 (define_insn "andcdi3"
4088 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4089 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
4090 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
4093 [(set_attr "type" "arith_media")])
4095 (define_expand "iorsi3"
4096 [(set (match_operand:SI 0 "arith_reg_operand" "")
4097 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
4098 (match_operand:SI 2 "logical_operand" "")))]
4102 (define_insn "*iorsi3_compact"
4103 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
4104 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
4105 (match_operand:SI 2 "logical_operand" "r,K08")))]
4107 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
4109 [(set_attr "type" "arith")])
4111 (define_insn "*iorsi3_media"
4112 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4113 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
4114 (match_operand:SI 2 "logical_operand" "r,I10")))]
4119 [(set_attr "type" "arith_media")])
4121 (define_insn "*iorsi3_bset"
4122 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4123 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
4124 (match_operand:SI 2 "const_int_operand" "Pso")))]
4125 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
4127 [(set_attr "type" "arith")])
4129 (define_insn "iordi3"
4130 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4131 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
4132 (match_operand:DI 2 "logical_operand" "r,I10")))]
4137 [(set_attr "type" "arith_media")])
4139 (define_insn_and_split "*logical_sidi3"
4140 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4141 (sign_extend:DI (match_operator:SI 3 "logical_operator"
4142 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
4143 (match_operand:SI 2 "logical_operand" "r,I10")])))]
4146 "&& reload_completed"
4147 [(set (match_dup 0) (match_dup 3))]
4150 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
4151 simplify_gen_subreg (DImode, operands[1], SImode, 0),
4152 simplify_gen_subreg (DImode, operands[2], SImode, 0));
4155 (define_insn_and_split "*logical_sidisi3"
4156 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4157 (truncate:SI (sign_extend:DI
4158 (match_operator:SI 3 "logical_operator"
4159 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
4160 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
4164 [(set (match_dup 0) (match_dup 3))])
4166 (define_insn_and_split "*logical_sidi3_2"
4167 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4168 (sign_extend:DI (truncate:SI (sign_extend:DI
4169 (match_operator:SI 3 "logical_operator"
4170 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
4171 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
4175 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
4177 (define_expand "xorsi3"
4178 [(set (match_operand:SI 0 "arith_reg_operand" "")
4179 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
4180 (match_operand:SI 2 "xor_operand" "")))]
4184 (define_insn "*xorsi3_compact"
4185 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
4186 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
4187 (match_operand:SI 2 "logical_operand" "K08,r")))]
4190 [(set_attr "type" "arith")])
4192 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
4193 ;; of results where one of the inputs is a T bit store. Notice that this
4194 ;; pattern must not match during reload. If reload picks this pattern it
4195 ;; will be impossible to split it afterwards.
4196 (define_insn_and_split "*logical_op_t"
4197 [(set (match_operand:SI 0 "arith_reg_dest")
4198 (match_operator:SI 3 "logical_operator"
4199 [(match_operand:SI 1 "arith_reg_operand")
4200 (match_operand:SI 2 "t_reg_operand")]))]
4201 "TARGET_SH1 && can_create_pseudo_p ()"
4204 [(set (match_dup 4) (reg:SI T_REG))
4205 (set (match_dup 0) (match_dup 3))]
4207 operands[4] = gen_reg_rtx (SImode);
4208 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
4209 operands[1], operands[4]);
4212 (define_insn "*xorsi3_media"
4213 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4214 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
4215 (match_operand:SI 2 "xor_operand" "r,I06")))]
4220 [(set_attr "type" "arith_media")])
4222 (define_insn "xordi3"
4223 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4224 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
4225 (match_operand:DI 2 "xor_operand" "r,I06")))]
4230 [(set_attr "type" "arith_media")])
4232 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
4233 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
4235 [(set (match_operand:DI 0 "arith_reg_dest" "")
4236 (sign_extend:DI (match_operator 4 "binary_logical_operator"
4237 [(match_operand 1 "any_register_operand" "")
4238 (match_operand 2 "any_register_operand" "")])))]
4240 [(set (match_dup 5) (match_dup 4))
4241 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
4243 machine_mode inmode = GET_MODE (operands[1]);
4246 if (GET_CODE (operands[0]) == SUBREG)
4248 offset = SUBREG_BYTE (operands[0]);
4249 operands[0] = SUBREG_REG (operands[0]);
4251 gcc_assert (REG_P (operands[0]));
4252 if (TARGET_BIG_ENDIAN)
4253 offset += 8 - GET_MODE_SIZE (inmode);
4254 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
4257 ;; -------------------------------------------------------------------------
4258 ;; Shifts and rotates
4259 ;; -------------------------------------------------------------------------
4261 ;; Let combine see that we can get the MSB and LSB into the T bit
4262 ;; via shll and shlr. This allows it to plug it into insns that can have
4263 ;; the T bit as an input (e.g. addc).
4264 ;; On SH2A use bld #0,Rn instead of shlr to avoid mutating the input.
4265 (define_insn_and_split "*reg_lsb_t"
4266 [(set (reg:SI T_REG)
4267 (and:SI (match_operand:SI 0 "arith_reg_operand")
4269 "TARGET_SH1 && can_create_pseudo_p ()"
4274 emit_insn (TARGET_SH2A ? gen_bldsi_reg (operands[0], const0_rtx)
4275 : gen_shlr (gen_reg_rtx (SImode), operands[0]));
4278 (define_insn_and_split "*reg_msb_t"
4279 [(set (reg:SI T_REG)
4280 (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
4282 "TARGET_SH1 && can_create_pseudo_p ()"
4287 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[0]));
4290 (define_expand "rotldi3"
4291 [(set (match_operand:DI 0 "arith_reg_dest" "")
4292 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
4293 (match_operand:HI 2 "mextr_bit_offset" "")))]
4296 if (! mextr_bit_offset (operands[2], HImode))
4300 (define_insn "rotldi3_mextr"
4301 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4302 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
4303 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4306 static char templ[16];
4307 sprintf (templ, "mextr%d %%1,%%1,%%0",
4308 8 - (int) (INTVAL (operands[2]) >> 3));
4311 [(set_attr "type" "arith_media")])
4313 (define_expand "rotrdi3"
4314 [(set (match_operand:DI 0 "arith_reg_dest" "")
4315 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
4316 (match_operand:HI 2 "mextr_bit_offset" "")))]
4319 if (! mextr_bit_offset (operands[2], HImode))
4323 (define_insn "rotrdi3_mextr"
4324 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4325 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
4326 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4329 static char templ[16];
4330 sprintf (templ, "mextr%d %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
4333 [(set_attr "type" "arith_media")])
4336 [(set (match_operand:DI 0 "arith_reg_dest" "")
4337 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
4338 "ua_address_operand" "")))
4339 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
4341 (clobber (match_operand:DI 3 "register_operand" ""))]
4343 [(match_dup 4) (match_dup 5)]
4345 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
4346 (operands[3], operands[1]));
4347 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
4348 GEN_INT (56), GEN_INT (8));
4351 (define_expand "rotrsi3"
4352 [(set (match_operand:SI 0 "arith_reg_dest")
4353 (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
4354 (match_operand:SI 2 "const_int_operand")))]
4357 HOST_WIDE_INT ival = INTVAL (operands[2]);
4360 emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
4367 (define_insn "rotrsi3_1"
4368 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4369 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4372 (and:SI (match_dup 1) (const_int 1)))]
4375 [(set_attr "type" "arith")])
4377 ;; A slimplified version of rotr for combine.
4378 (define_insn "*rotrsi3_1"
4379 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4380 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4382 (clobber (reg:SI T_REG))]
4385 [(set_attr "type" "arith")])
4387 (define_insn "rotlsi3_1"
4388 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4389 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4392 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4395 [(set_attr "type" "arith")])
4397 ;; A simplified version of rotl for combine.
4398 (define_insn "*rotlsi3_1"
4399 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4400 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4402 (clobber (reg:SI T_REG))]
4405 [(set_attr "type" "arith")])
4407 (define_insn "rotlsi3_31"
4408 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4409 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4411 (clobber (reg:SI T_REG))]
4414 [(set_attr "type" "arith")])
4416 (define_insn "rotlsi3_16"
4417 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4418 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
4422 [(set_attr "type" "arith")])
4424 (define_expand "rotlsi3"
4425 [(set (match_operand:SI 0 "arith_reg_dest")
4426 (rotate:SI (match_operand:SI 1 "arith_reg_operand")
4427 (match_operand:SI 2 "const_int_operand")))]
4430 static const char rot_tab[] = {
4431 000, 000, 000, 000, 000, 000, 010, 001,
4432 001, 001, 011, 013, 003, 003, 003, 003,
4433 003, 003, 003, 003, 003, 013, 012, 002,
4434 002, 002, 010, 000, 000, 000, 000, 000,
4437 int count = INTVAL (operands[2]);
4438 int choice = rot_tab[count];
4439 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
4445 emit_move_insn (operands[0], operands[1]);
4446 count -= (count & 16) * 2;
4449 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
4456 parts[0] = gen_reg_rtx (SImode);
4457 parts[1] = gen_reg_rtx (SImode);
4458 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
4459 emit_move_insn (parts[choice-1], operands[1]);
4460 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
4461 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
4462 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
4463 count = (count & ~16) - 8;
4467 for (; count > 0; count--)
4468 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
4469 for (; count < 0; count++)
4470 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4475 (define_insn "rotlhi3_8"
4476 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4477 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
4481 [(set_attr "type" "arith")])
4483 (define_expand "rotlhi3"
4484 [(set (match_operand:HI 0 "arith_reg_operand")
4485 (rotate:HI (match_operand:HI 1 "arith_reg_operand")
4486 (match_operand:HI 2 "const_int_operand")))]
4489 if (INTVAL (operands[2]) != 8)
4493 ;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
4494 ;; They can also be used to implement things like
4496 ;; int x0 = (y >> 1) | (t << 31); // rotcr
4497 ;; int x1 = (y << 1) | t; // rotcl
4498 (define_insn "rotcr"
4499 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4500 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4502 (ashift:SI (match_operand:SI 2 "t_reg_operand")
4505 (and:SI (match_dup 1) (const_int 1)))]
4508 [(set_attr "type" "arith")])
4510 (define_insn "rotcl"
4511 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4512 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4514 (match_operand:SI 2 "t_reg_operand")))
4516 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4519 [(set_attr "type" "arith")])
4521 ;; Simplified rotcr version for combine, which allows arbitrary shift
4522 ;; amounts for the reg. If the shift amount is '1' rotcr can be used
4523 ;; directly. Otherwise we have to insert a shift in between.
4524 (define_insn_and_split "*rotcr"
4525 [(set (match_operand:SI 0 "arith_reg_dest")
4526 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_or_0_operand")
4527 (match_operand:SI 2 "const_int_operand"))
4528 (ashift:SI (match_operand 3 "arith_reg_or_treg_set_expr")
4530 (clobber (reg:SI T_REG))]
4531 "TARGET_SH1 && can_create_pseudo_p ()"
4536 rtx prev_set_t_insn = NULL_RTX;
4538 if (!arith_reg_operand (operands[3], SImode))
4540 sh_treg_insns ti = sh_split_treg_set_expr (operands[3], curr_insn);
4541 if (!ti.was_treg_operand ())
4542 prev_set_t_insn = ti.first_insn ();
4544 operands[3] = get_t_reg_rtx ();
4546 if (TARGET_SH2A && ti.has_trailing_nott () && operands[1] == const0_rtx)
4548 /* Convert to a movrt, rotr sequence. */
4549 remove_insn (ti.trailing_nott ());
4550 rtx tmp = gen_reg_rtx (SImode);
4551 emit_insn (gen_movnegt (tmp, get_t_reg_rtx ()));
4552 emit_insn (gen_rotrsi3_1 (operands[0], tmp));
4557 if (operands[1] == const0_rtx)
4559 operands[1] = gen_reg_rtx (SImode);
4560 emit_insn (gen_movt (operands[1], get_t_reg_rtx ()));
4563 if (INTVAL (operands[2]) > 1)
4565 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4566 rtx tmp_t_reg = NULL_RTX;
4568 /* If we're going to emit a shift sequence that clobbers the T_REG,
4569 try to find the previous insn that sets the T_REG and emit the
4570 shift insn before that insn, to remove the T_REG dependency.
4571 If the insn that sets the T_REG cannot be found, store the T_REG
4572 in a temporary reg and restore it after the shift. */
4573 if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4574 && ! sh_dynamicalize_shift_p (shift_count))
4576 if (prev_set_t_insn == NULL)
4577 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4579 /* Skip the nott insn, which was probably inserted by the splitter
4580 of *rotcr_neg_t. Don't use one of the recog functions
4581 here during insn splitting, since that causes problems in later
4583 if (prev_set_t_insn != NULL_RTX)
4585 rtx pat = PATTERN (prev_set_t_insn);
4586 if (GET_CODE (pat) == SET
4587 && t_reg_operand (XEXP (pat, 0), SImode)
4588 && negt_reg_operand (XEXP (pat, 1), SImode))
4589 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4592 if (! (prev_set_t_insn != NULL_RTX
4593 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4594 && ! reg_referenced_p (get_t_reg_rtx (),
4595 PATTERN (prev_set_t_insn))))
4597 prev_set_t_insn = NULL_RTX;
4598 tmp_t_reg = gen_reg_rtx (SImode);
4599 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4603 rtx shift_result = gen_reg_rtx (SImode);
4604 rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4605 operands[1] = shift_result;
4607 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4608 if (prev_set_t_insn != NULL_RTX)
4609 emit_insn_before (shift_insn, prev_set_t_insn);
4611 emit_insn (shift_insn);
4613 /* Restore T_REG if it has been saved before. */
4614 if (tmp_t_reg != NULL_RTX)
4615 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4618 /* For the rotcr insn to work, operands[3] must be in T_REG.
4619 If it is not we can get it there by shifting it right one bit.
4620 In this case T_REG is not an input for this insn, thus we don't have to
4621 pay attention as of where to insert the shlr insn. */
4622 if (! t_reg_operand (operands[3], SImode))
4624 /* We don't care about the shifted result here, only the T_REG. */
4625 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4626 operands[3] = get_t_reg_rtx ();
4629 emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4633 ;; If combine tries the same as above but with swapped operands, split
4634 ;; it so that it will try the pattern above.
4636 [(set (match_operand:SI 0 "arith_reg_dest")
4637 (ior:SI (ashift:SI (match_operand 1 "arith_reg_or_treg_set_expr")
4639 (lshiftrt:SI (match_operand:SI 2 "arith_reg_or_0_operand")
4640 (match_operand:SI 3 "const_int_operand"))))]
4641 "TARGET_SH1 && can_create_pseudo_p ()"
4642 [(parallel [(set (match_dup 0)
4643 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4644 (ashift:SI (match_dup 1) (const_int 31))))
4645 (clobber (reg:SI T_REG))])])
4647 ;; Basically the same as the rotcr pattern above, but for rotcl.
4648 ;; FIXME: Fold copy pasted split code for rotcr and rotcl.
4649 (define_insn_and_split "*rotcl"
4650 [(set (match_operand:SI 0 "arith_reg_dest")
4651 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4652 (match_operand:SI 2 "const_int_operand"))
4653 (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4655 (clobber (reg:SI T_REG))]
4658 "&& can_create_pseudo_p ()"
4661 gcc_assert (INTVAL (operands[2]) > 0);
4663 if (INTVAL (operands[2]) > 1)
4665 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4666 rtx prev_set_t_insn = NULL_RTX;
4667 rtx tmp_t_reg = NULL_RTX;
4669 /* If we're going to emit a shift sequence that clobbers the T_REG,
4670 try to find the previous insn that sets the T_REG and emit the
4671 shift insn before that insn, to remove the T_REG dependency.
4672 If the insn that sets the T_REG cannot be found, store the T_REG
4673 in a temporary reg and restore it after the shift. */
4674 if (sh_ashlsi_clobbers_t_reg_p (shift_count)
4675 && ! sh_dynamicalize_shift_p (shift_count))
4677 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4679 /* Skip the nott insn, which was probably inserted by the splitter
4680 of *rotcl_neg_t. Don't use one of the recog functions
4681 here during insn splitting, since that causes problems in later
4683 if (prev_set_t_insn != NULL_RTX)
4685 rtx pat = PATTERN (prev_set_t_insn);
4686 if (GET_CODE (pat) == SET
4687 && t_reg_operand (XEXP (pat, 0), SImode)
4688 && negt_reg_operand (XEXP (pat, 1), SImode))
4689 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4692 if (! (prev_set_t_insn != NULL_RTX
4693 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4694 && ! reg_referenced_p (get_t_reg_rtx (),
4695 PATTERN (prev_set_t_insn))))
4697 prev_set_t_insn = NULL_RTX;
4698 tmp_t_reg = gen_reg_rtx (SImode);
4699 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4703 rtx shift_result = gen_reg_rtx (SImode);
4704 rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
4705 operands[1] = shift_result;
4707 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4708 if (prev_set_t_insn != NULL_RTX)
4709 emit_insn_before (shift_insn, prev_set_t_insn);
4711 emit_insn (shift_insn);
4713 /* Restore T_REG if it has been saved before. */
4714 if (tmp_t_reg != NULL_RTX)
4715 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4718 /* For the rotcl insn to work, operands[3] must be in T_REG.
4719 If it is not we can get it there by shifting it right one bit.
4720 In this case T_REG is not an input for this insn, thus we don't have to
4721 pay attention as of where to insert the shlr insn. */
4722 if (! t_reg_operand (operands[3], SImode))
4724 /* We don't care about the shifted result here, only the T_REG. */
4725 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4726 operands[3] = get_t_reg_rtx ();
4729 emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
4733 ;; rotcl combine pattern variations
4734 (define_insn_and_split "*rotcl"
4735 [(set (match_operand:SI 0 "arith_reg_dest")
4736 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4737 (match_operand:SI 2 "const_int_operand"))
4738 (match_operand 3 "treg_set_expr")))
4739 (clobber (reg:SI T_REG))]
4742 "&& can_create_pseudo_p ()"
4743 [(parallel [(set (match_dup 0)
4744 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4745 (and:SI (match_dup 3) (const_int 1))))
4746 (clobber (reg:SI T_REG))])]
4748 sh_split_treg_set_expr (operands[3], curr_insn);
4749 operands[3] = get_t_reg_rtx ();
4752 (define_insn_and_split "*rotcl"
4753 [(set (match_operand:SI 0 "arith_reg_dest")
4754 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4756 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4757 (match_operand:SI 3 "const_int_operand"))))
4758 (clobber (reg:SI T_REG))]
4761 "&& can_create_pseudo_p ()"
4762 [(parallel [(set (match_dup 0)
4763 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4764 (and:SI (match_dup 1) (const_int 1))))
4765 (clobber (reg:SI T_REG))])])
4767 (define_insn_and_split "*rotcl"
4768 [(set (match_operand:SI 0 "arith_reg_dest")
4769 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4770 (match_operand:SI 2 "const_int_operand"))
4771 (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4773 (clobber (reg:SI T_REG))]
4776 "&& can_create_pseudo_p ()"
4777 [(parallel [(set (match_dup 0)
4778 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4779 (and:SI (reg:SI T_REG) (const_int 1))))
4780 (clobber (reg:SI T_REG))])]
4782 /* We don't care about the result of the left shift, only the T_REG. */
4783 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4786 (define_insn_and_split "*rotcl"
4787 [(set (match_operand:SI 0 "arith_reg_dest")
4788 (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4790 (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4791 (match_operand:SI 2 "const_int_operand"))))
4792 (clobber (reg:SI T_REG))]
4795 "&& can_create_pseudo_p ()"
4796 [(parallel [(set (match_dup 0)
4797 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4798 (and:SI (reg:SI T_REG) (const_int 1))))
4799 (clobber (reg:SI T_REG))])]
4801 /* We don't care about the result of the left shift, only the T_REG. */
4802 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4805 (define_insn_and_split "*rotcl"
4806 [(set (match_operand:SI 0 "arith_reg_dest")
4807 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4808 (match_operand 2 "const_int_operand"))
4809 (zero_extract:SI (match_operand:SI 3 "arith_reg_operand")
4811 (match_operand 4 "const_int_operand"))))
4812 (clobber (reg:SI T_REG))]
4815 "&& can_create_pseudo_p ()"
4816 [(parallel [(set (match_dup 0)
4817 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4818 (and:SI (match_dup 5) (const_int 1))))
4819 (clobber (reg:SI T_REG))])]
4821 if (TARGET_SH2A && satisfies_constraint_K03 (operands[4]))
4823 /* On SH2A we can use the bld insn to zero extract a single bit
4825 operands[5] = get_t_reg_rtx ();
4826 emit_insn (gen_bldsi_reg (operands[3], operands[4]));
4830 /* If we can't use the bld insn we have to emit a tst + nott sequence
4831 to get the extracted bit into the T bit.
4832 This will probably be worse than pre-shifting the operand. */
4833 operands[5] = gen_reg_rtx (SImode);
4834 emit_insn (gen_lshrsi3 (operands[5], operands[3], operands[4]));
4838 ;; rotcr combine bridge pattern which will make combine try out more
4839 ;; complex patterns.
4840 (define_insn_and_split "*rotcr"
4841 [(set (match_operand:SI 0 "arith_reg_dest")
4842 (ashift:SI (match_operand 1 "treg_set_expr") (const_int 31)))]
4843 "TARGET_SH1 && can_create_pseudo_p ()"
4846 [(parallel [(set (match_dup 0)
4847 (ior:SI (lshiftrt:SI (const_int 0) (const_int 1))
4848 (ashift:SI (match_dup 1) (const_int 31))))
4849 (clobber (reg:SI T_REG))])])
4851 (define_insn_and_split "*rotcr"
4852 [(set (match_operand:SI 0 "arith_reg_dest")
4853 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4854 (const_int -2147483648)) ;; 0xffffffff80000000
4855 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4857 (clobber (reg:SI T_REG))]
4860 "&& can_create_pseudo_p ()"
4863 rtx tmp = gen_reg_rtx (SImode);
4864 emit_insn (gen_shll (tmp, operands[1]));
4865 emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4869 ;; rotcr combine patterns for rotating in the negated T_REG value.
4870 (define_insn_and_split "*rotcr_neg_t"
4871 [(set (match_operand:SI 0 "arith_reg_dest")
4872 (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4873 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4874 (match_operand:SI 3 "const_int_operand"))))
4875 (clobber (reg:SI T_REG))]
4878 "&& can_create_pseudo_p ()"
4879 [(parallel [(set (match_dup 0)
4880 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4881 (ashift:SI (reg:SI T_REG) (const_int 31))))
4882 (clobber (reg:SI T_REG))])]
4884 emit_insn (gen_nott (get_t_reg_rtx ()));
4887 (define_insn_and_split "*rotcr_neg_t"
4888 [(set (match_operand:SI 0 "arith_reg_dest")
4889 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4890 (match_operand:SI 2 "const_int_operand"))
4891 (match_operand:SI 3 "negt_reg_shl31_operand")))
4892 (clobber (reg:SI T_REG))]
4895 "&& can_create_pseudo_p ()"
4896 [(parallel [(set (match_dup 0)
4897 (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4898 (ashift:SI (reg:SI T_REG) (const_int 31))))
4899 (clobber (reg:SI T_REG))])]
4901 emit_insn (gen_nott (get_t_reg_rtx ()));
4904 ;; rotcl combine patterns for rotating in the negated T_REG value.
4905 ;; For some strange reason these have to be specified as splits which combine
4906 ;; will pick up. If they are specified as insn_and_split like the
4907 ;; *rotcr_neg_t patterns above, combine would recognize them successfully
4908 ;; but not emit them on non-SH2A targets.
4910 [(set (match_operand:SI 0 "arith_reg_dest")
4911 (ior:SI (match_operand:SI 1 "negt_reg_operand")
4912 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4913 (match_operand:SI 3 "const_int_operand"))))]
4915 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4916 (parallel [(set (match_dup 0)
4917 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4918 (and:SI (reg:SI T_REG) (const_int 1))))
4919 (clobber (reg:SI T_REG))])])
4922 [(set (match_operand:SI 0 "arith_reg_dest")
4923 (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4924 (match_operand:SI 3 "const_int_operand"))
4925 (match_operand:SI 1 "negt_reg_operand")))]
4927 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4928 (parallel [(set (match_dup 0)
4929 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4930 (and:SI (reg:SI T_REG) (const_int 1))))
4931 (clobber (reg:SI T_REG))])])
4933 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4934 ;; SImode shift left
4936 (define_expand "ashlsi3"
4937 [(set (match_operand:SI 0 "arith_reg_operand" "")
4938 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4939 (match_operand:SI 2 "shift_count_operand" "")))]
4944 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
4946 operands[2] = GEN_INT (-INTVAL (operands[2]));
4947 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4950 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4954 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4955 operands[2] = force_reg (SImode, operands[2]);
4957 /* If the ashlsi3_* insn is going to clobber the T_REG it must be
4959 if (CONST_INT_P (operands[2])
4960 && sh_ashlsi_clobbers_t_reg_p (operands[2])
4961 && ! sh_dynamicalize_shift_p (operands[2]))
4963 emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4968 /* Expand a library call for the dynamic shift. */
4969 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4971 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4972 rtx funcaddr = gen_reg_rtx (Pmode);
4973 function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4974 emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4980 (define_insn "ashlsi3_k"
4981 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4982 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4983 (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4988 [(set_attr "type" "arith")])
4990 (define_insn_and_split "ashlsi3_d"
4991 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4992 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4993 (match_operand:SI 2 "shift_count_operand" "r")))]
4996 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4997 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
5000 if (satisfies_constraint_P27 (operands[2]))
5002 emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
5005 else if (! satisfies_constraint_P27 (operands[2]))
5007 /* This must happen before reload, otherwise the constant will be moved
5008 into a register due to the "r" constraint, after which this split
5009 cannot be done anymore.
5010 Unfortunately the move insn will not always be eliminated.
5011 Also, here we must not create a shift sequence that clobbers the
5013 emit_move_insn (operands[0], operands[1]);
5014 gen_shifty_op (ASHIFT, operands);
5020 [(set_attr "type" "dyn_shift")])
5022 ;; If dynamic shifts are not available use a library function.
5023 ;; By specifying the pattern we reduce the number of call clobbered regs.
5024 ;; In order to make combine understand the truncation of the shift amount
5025 ;; operand we have to allow it to use pseudo regs for the shift operands.
5026 (define_insn "ashlsi3_d_call"
5027 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
5028 (ashift:SI (reg:SI R4_REG)
5029 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5031 (use (match_operand:SI 2 "arith_reg_operand" "r"))
5032 (clobber (reg:SI T_REG))
5033 (clobber (reg:SI PR_REG))]
5034 "TARGET_SH1 && !TARGET_DYNSHIFT"
5036 [(set_attr "type" "sfunc")
5037 (set_attr "needs_delay_slot" "yes")])
5039 (define_insn_and_split "ashlsi3_n"
5040 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5041 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5042 (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
5043 "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
5045 "&& (reload_completed
5046 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5049 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5051 /* If this pattern was picked and dynamic shifts are supported, switch
5052 to dynamic shift pattern before reload. */
5053 operands[2] = force_reg (SImode, operands[2]);
5054 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
5057 gen_shifty_op (ASHIFT, operands);
5062 (define_insn_and_split "ashlsi3_n_clobbers_t"
5063 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5064 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5065 (match_operand:SI 2 "not_p27_shift_count_operand" "")))
5066 (clobber (reg:SI T_REG))]
5067 "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
5069 "&& (reload_completed || INTVAL (operands[2]) == 31
5070 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5073 if (INTVAL (operands[2]) == 31)
5075 /* If the shift amount is 31 we split into a different sequence before
5076 reload so that it gets a chance to allocate R0 for the sequence.
5077 If it fails to do so (due to pressure on R0), it will take one insn
5078 more for the and. */
5079 emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
5080 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
5082 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5084 /* If this pattern was picked and dynamic shifts are supported, switch
5085 to dynamic shift pattern before reload. */
5086 operands[2] = force_reg (SImode, operands[2]);
5087 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
5090 gen_shifty_op (ASHIFT, operands);
5096 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5097 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
5099 (lt:SI (match_dup 1) (const_int 0)))]
5102 [(set_attr "type" "arith")])
5104 (define_insn "*ashlsi_c_void"
5105 [(set (reg:SI T_REG)
5106 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
5107 (clobber (match_scratch:SI 1 "=0"))]
5108 "TARGET_SH1 && cse_not_expected"
5110 [(set_attr "type" "arith")])
5113 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
5115 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
5117 && peep2_reg_dead_p (2, operands[0])
5118 && peep2_reg_dead_p (2, operands[1])"
5121 emit_insn (gen_shll (operands[1], operands[1]));
5125 (define_insn "ashlsi3_media"
5126 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5127 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5128 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5133 [(set_attr "type" "arith_media")
5134 (set_attr "highpart" "ignore")])
5136 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5137 ;; HImode shift left
5139 (define_expand "ashlhi3"
5140 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
5141 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
5142 (match_operand:SI 2 "nonmemory_operand" "")))
5143 (clobber (reg:SI T_REG))])]
5146 if (!CONST_INT_P (operands[2]))
5148 /* It may be possible to call gen_ashlhi3 directly with more generic
5149 operands. Make sure operands[1] is a HImode register here. */
5150 if (!arith_reg_operand (operands[1], HImode))
5151 operands[1] = copy_to_mode_reg (HImode, operands[1]);
5154 (define_insn "ashlhi3_k"
5155 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
5156 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
5157 (match_operand:HI 2 "const_int_operand" "M,P27")))]
5158 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
5162 [(set_attr "type" "arith")])
5164 (define_insn_and_split "*ashlhi3_n"
5165 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
5166 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
5167 (match_operand:HI 2 "const_int_operand" "n")))
5168 (clobber (reg:SI T_REG))]
5171 "&& reload_completed"
5172 [(use (reg:SI R0_REG))]
5174 gen_shifty_hi_op (ASHIFT, operands);
5178 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5179 ;; DImode shift left
5181 (define_expand "ashldi3"
5182 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5183 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
5184 (match_operand:DI 2 "immediate_operand" "")))
5185 (clobber (reg:SI T_REG))])]
5190 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5192 operands[2] = GEN_INT (-INTVAL (operands[2]));
5193 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
5196 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5199 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
5201 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
5204 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
5206 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
5213 ;; Expander for DImode shift left with SImode operations.
5214 (define_expand "ashldi3_std"
5215 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5216 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
5217 (match_operand:DI 2 "const_int_operand" "n")))]
5218 "TARGET_SH1 && INTVAL (operands[2]) < 32"
5220 rtx low_src = gen_lowpart (SImode, operands[1]);
5221 rtx high_src = gen_highpart (SImode, operands[1]);
5222 rtx dst = gen_reg_rtx (DImode);
5223 rtx low_dst = gen_lowpart (SImode, dst);
5224 rtx high_dst = gen_highpart (SImode, dst);
5225 rtx tmp0 = gen_reg_rtx (SImode);
5226 rtx tmp1 = gen_reg_rtx (SImode);
5228 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
5229 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
5230 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
5231 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
5232 emit_move_insn (operands[0], dst);
5236 (define_insn_and_split "ashldi3_k"
5237 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5238 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
5240 (clobber (reg:SI T_REG))]
5243 "&& reload_completed"
5246 rtx high = gen_highpart (SImode, operands[0]);
5247 rtx low = gen_lowpart (SImode, operands[0]);
5248 emit_insn (gen_shll (low, low));
5249 emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
5253 (define_insn "ashldi3_media"
5254 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
5255 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5256 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5261 [(set_attr "type" "arith_media")])
5263 (define_insn "*ashldisi3_media"
5264 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5265 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
5266 (match_operand:DI 2 "const_int_operand" "n")))]
5267 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5268 "shlli.l %1, %2, %0"
5269 [(set_attr "type" "arith_media")
5270 (set_attr "highpart" "ignore")])
5272 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5273 ;; SImode arithmetic shift right
5275 ;; We can't do HImode right shifts correctly unless we start out with an
5276 ;; explicit zero / sign extension; doing that would result in worse overall
5277 ;; code, so just let the machine independent code widen the mode.
5278 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
5280 (define_expand "ashrsi3"
5281 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
5282 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
5283 (match_operand:SI 2 "nonmemory_operand" "")))
5284 (clobber (reg:SI T_REG))])]
5289 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5291 operands[2] = GEN_INT (-INTVAL (operands[2]));
5292 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
5295 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
5298 if (expand_ashiftrt (operands))
5305 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5306 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5309 (and:SI (match_dup 1) (const_int 1)))]
5312 [(set_attr "type" "arith")])
5314 (define_insn "ashrsi3_k"
5315 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5316 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5317 (match_operand:SI 2 "const_int_operand" "M")))
5318 (clobber (reg:SI T_REG))]
5319 "TARGET_SH1 && INTVAL (operands[2]) == 1"
5321 [(set_attr "type" "arith")])
5323 (define_insn_and_split "ashrsi2_16"
5324 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5325 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
5330 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
5331 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
5333 operands[2] = gen_lowpart (HImode, operands[0]);
5336 (define_insn_and_split "ashrsi2_31"
5337 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5338 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5340 (clobber (reg:SI T_REG))]
5346 emit_insn (gen_shll (operands[0], operands[1]));
5347 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
5351 ;; If the shift amount is changed by combine it will try to plug the
5352 ;; use on the symbol of the library function and the PR clobber.
5353 (define_insn_and_split "*ashrsi2_31"
5354 [(set (match_operand:SI 0 "arith_reg_dest")
5355 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand")
5357 (clobber (reg:SI T_REG))
5358 (clobber (reg:SI PR_REG))
5359 (use (match_operand:SI 2 "symbol_ref_operand"))]
5363 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))
5364 (clobber (reg:SI T_REG))])])
5366 (define_insn "ashrsi3_d"
5367 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5368 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5369 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
5372 [(set_attr "type" "dyn_shift")])
5374 (define_insn "ashrsi3_n"
5375 [(set (reg:SI R4_REG)
5376 (ashiftrt:SI (reg:SI R4_REG)
5377 (match_operand:SI 0 "const_int_operand" "i")))
5378 (clobber (reg:SI T_REG))
5379 (clobber (reg:SI PR_REG))
5380 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
5383 [(set_attr "type" "sfunc")
5384 (set_attr "needs_delay_slot" "yes")])
5386 (define_insn "ashrsi3_media"
5387 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5388 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5389 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5394 [(set_attr "type" "arith_media")
5395 (set_attr "highpart" "ignore")])
5397 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5398 ;; DImode arithmetic shift right
5400 (define_expand "ashrdi3"
5401 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5402 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5403 (match_operand:DI 2 "immediate_operand" "")))
5404 (clobber (reg:SI T_REG))])]
5409 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5411 operands[2] = GEN_INT (-INTVAL (operands[2]));
5412 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5415 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
5418 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5422 (define_insn_and_split "ashrdi3_k"
5423 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5424 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5426 (clobber (reg:SI T_REG))]
5429 "&& reload_completed"
5432 rtx high = gen_highpart (SImode, operands[0]);
5433 rtx low = gen_lowpart (SImode, operands[0]);
5434 emit_insn (gen_shar (high, high));
5435 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5439 (define_insn "ashrdi3_media"
5440 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5441 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5442 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5444 && (arith_reg_dest (operands[0], DImode)
5445 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
5449 [(set_attr "type" "arith_media")])
5451 (define_insn "*ashrdisi3_media"
5452 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5453 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5454 (match_operand:DI 2 "const_int_operand" "n")))]
5455 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5456 "shari.l %1, %2, %0"
5457 [(set_attr "type" "arith_media")
5458 (set_attr "highpart" "ignore")])
5460 (define_insn "ashrdisi3_media_high"
5461 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5463 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5464 (match_operand:DI 2 "const_int_operand" "n"))))]
5465 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
5467 [(set_attr "type" "arith_media")])
5469 (define_insn "ashrdisi3_media_opaque"
5470 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5471 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
5472 (match_operand:DI 2 "const_int_operand" "n")]
5476 [(set_attr "type" "arith_media")])
5478 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5479 ;; SImode logical shift right
5481 (define_expand "lshrsi3"
5482 [(set (match_operand:SI 0 "arith_reg_dest" "")
5483 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
5484 (match_operand:SI 2 "shift_count_operand" "")))]
5489 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5491 operands[2] = GEN_INT (-INTVAL (operands[2]));
5492 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
5495 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
5499 /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
5500 here, otherwise the pattern will never match due to the shift amount reg
5503 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
5505 rtx neg_count = force_reg (SImode,
5506 gen_int_mode (- INTVAL (operands[2]), SImode));
5507 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5511 if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
5513 rtx neg_count = gen_reg_rtx (SImode);
5514 emit_insn (gen_negsi2 (neg_count, operands[2]));
5515 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5519 /* If the lshrsi3_* insn is going to clobber the T_REG it must be
5521 if (CONST_INT_P (operands[2])
5522 && sh_lshrsi_clobbers_t_reg_p (operands[2])
5523 && ! sh_dynamicalize_shift_p (operands[2]))
5525 emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
5530 /* Expand a library call for the dynamic shift. */
5531 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
5533 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
5534 rtx funcaddr = gen_reg_rtx (Pmode);
5535 function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
5536 emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
5541 (define_insn "lshrsi3_k"
5542 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5543 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5544 (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
5547 [(set_attr "type" "arith")])
5549 (define_insn_and_split "lshrsi3_d"
5550 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5551 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5552 (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
5555 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
5556 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5559 if (satisfies_constraint_P27 (operands[2]))
5561 /* This will not be done for a shift amount of 1, because it would
5562 clobber the T_REG. */
5563 emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
5566 else if (! satisfies_constraint_P27 (operands[2]))
5568 /* This must happen before reload, otherwise the constant will be moved
5569 into a register due to the "r" constraint, after which this split
5570 cannot be done anymore.
5571 Unfortunately the move insn will not always be eliminated.
5572 Also, here we must not create a shift sequence that clobbers the
5574 emit_move_insn (operands[0], operands[1]);
5575 gen_shifty_op (LSHIFTRT, operands);
5581 [(set_attr "type" "dyn_shift")])
5583 ;; If dynamic shifts are not available use a library function.
5584 ;; By specifying the pattern we reduce the number of call clobbered regs.
5585 ;; In order to make combine understand the truncation of the shift amount
5586 ;; operand we have to allow it to use pseudo regs for the shift operands.
5587 (define_insn "lshrsi3_d_call"
5588 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
5589 (lshiftrt:SI (reg:SI R4_REG)
5590 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5592 (use (match_operand:SI 2 "arith_reg_operand" "r"))
5593 (clobber (reg:SI T_REG))
5594 (clobber (reg:SI PR_REG))]
5595 "TARGET_SH1 && !TARGET_DYNSHIFT"
5597 [(set_attr "type" "sfunc")
5598 (set_attr "needs_delay_slot" "yes")])
5600 (define_insn_and_split "lshrsi3_n"
5601 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5602 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5603 (match_operand:SI 2 "not_p27_rshift_count_operand")))]
5604 "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5606 "&& (reload_completed
5607 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5610 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5612 /* If this pattern was picked and dynamic shifts are supported, switch
5613 to dynamic shift pattern before reload. */
5614 operands[2] = force_reg (SImode,
5615 gen_int_mode (- INTVAL (operands[2]), SImode));
5616 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5619 gen_shifty_op (LSHIFTRT, operands);
5624 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
5625 ;; the shlr pattern.
5626 (define_insn_and_split "lshrsi3_n_clobbers_t"
5627 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5628 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5629 (match_operand:SI 2 "not_p27_rshift_count_operand")))
5630 (clobber (reg:SI T_REG))]
5631 "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
5633 "&& (reload_completed || INTVAL (operands[2]) == 31
5634 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5637 if (INTVAL (operands[2]) == 31)
5639 emit_insn (gen_shll (operands[0], operands[1]));
5640 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
5642 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5644 /* If this pattern was picked and dynamic shifts are supported, switch
5645 to dynamic shift pattern before reload. */
5646 operands[2] = force_reg (SImode,
5647 gen_int_mode (- INTVAL (operands[2]), SImode));
5648 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5651 gen_shifty_op (LSHIFTRT, operands);
5657 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5658 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5661 (and:SI (match_dup 1) (const_int 1)))]
5664 [(set_attr "type" "arith")])
5666 (define_insn "lshrsi3_media"
5667 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5668 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5669 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5674 [(set_attr "type" "arith_media")
5675 (set_attr "highpart" "ignore")])
5677 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5678 ;; DImode logical shift right
5680 (define_expand "lshrdi3"
5681 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5682 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5683 (match_operand:DI 2 "immediate_operand" "")))
5684 (clobber (reg:SI T_REG))])]
5689 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
5691 operands[2] = GEN_INT (-INTVAL (operands[2]));
5692 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
5695 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
5698 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5702 (define_insn_and_split "lshrdi3_k"
5703 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5704 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5706 (clobber (reg:SI T_REG))]
5709 "&& reload_completed"
5712 rtx high = gen_highpart (SImode, operands[0]);
5713 rtx low = gen_lowpart (SImode, operands[0]);
5714 emit_insn (gen_shlr (high, high));
5715 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5719 (define_insn "lshrdi3_media"
5720 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5721 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5722 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5724 && (arith_reg_dest (operands[0], DImode)
5725 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
5729 [(set_attr "type" "arith_media")])
5731 (define_insn "*lshrdisi3_media"
5732 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5733 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5734 (match_operand:DI 2 "const_int_operand" "n")))]
5735 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5736 "shlri.l %1, %2, %0"
5737 [(set_attr "type" "arith_media")
5738 (set_attr "highpart" "ignore")])
5740 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5741 ;; Combined left/right shifts
5744 [(set (match_operand:SI 0 "register_operand" "")
5745 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5746 (match_operand:SI 2 "const_int_operand" ""))
5747 (match_operand:SI 3 "const_int_operand" "")))]
5748 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5749 [(use (reg:SI R0_REG))]
5751 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5757 [(set (match_operand:SI 0 "register_operand" "")
5758 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5759 (match_operand:SI 2 "const_int_operand" ""))
5760 (match_operand:SI 3 "const_int_operand" "")))
5761 (clobber (reg:SI T_REG))]
5762 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5763 [(use (reg:SI R0_REG))]
5765 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5771 [(set (match_operand:SI 0 "register_operand" "=r")
5772 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5773 (match_operand:SI 2 "const_int_operand" "n"))
5774 (match_operand:SI 3 "const_int_operand" "n")))
5775 (clobber (reg:SI T_REG))]
5776 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
5778 [(set (attr "length")
5779 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5781 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5783 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5785 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
5787 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
5789 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
5791 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
5792 (const_string "16")]
5793 (const_string "18")))
5794 (set_attr "type" "arith")])
5797 [(set (match_operand:SI 0 "register_operand" "=z")
5798 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5799 (match_operand:SI 2 "const_int_operand" "n"))
5800 (match_operand:SI 3 "const_int_operand" "n")))
5801 (clobber (reg:SI T_REG))]
5802 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
5804 [(set (attr "length")
5805 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5807 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5809 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5811 (const_string "10")))
5812 (set_attr "type" "arith")])
5814 ;; shift left / and combination with a scratch register: The combine pass
5815 ;; does not accept the individual instructions, even though they are
5816 ;; cheap. But it needs a precise description so that it is usable after
5818 (define_insn "and_shl_scratch"
5819 [(set (match_operand:SI 0 "register_operand" "=r,&r")
5823 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5824 (match_operand:SI 2 "const_int_operand" "N,n"))
5825 (match_operand:SI 3 "" "0,r"))
5826 (match_operand:SI 4 "const_int_operand" "n,n"))
5827 (match_operand:SI 5 "const_int_operand" "n,n")))
5828 (clobber (reg:SI T_REG))]
5831 [(set (attr "length")
5832 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5834 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5836 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5838 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5839 (const_string "10")]
5840 (const_string "12")))
5841 (set_attr "type" "arith")])
5844 [(set (match_operand:SI 0 "register_operand" "")
5848 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5849 (match_operand:SI 2 "const_int_operand" ""))
5850 (match_operand:SI 3 "register_operand" ""))
5851 (match_operand:SI 4 "const_int_operand" ""))
5852 (match_operand:SI 5 "const_int_operand" "")))
5853 (clobber (reg:SI T_REG))]
5855 [(use (reg:SI R0_REG))]
5857 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5859 if (INTVAL (operands[2]))
5861 gen_shifty_op (LSHIFTRT, operands);
5863 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5864 operands[2] = operands[4];
5865 gen_shifty_op (ASHIFT, operands);
5866 if (INTVAL (operands[5]))
5868 operands[2] = operands[5];
5869 gen_shifty_op (LSHIFTRT, operands);
5874 ;; signed left/right shift combination.
5876 [(set (match_operand:SI 0 "register_operand" "")
5878 (ashift:SI (match_operand:SI 1 "register_operand" "")
5879 (match_operand:SI 2 "const_int_operand" ""))
5880 (match_operand:SI 3 "const_int_operand" "")
5882 (clobber (reg:SI T_REG))]
5884 [(use (reg:SI R0_REG))]
5886 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5891 (define_insn "shl_sext_ext"
5892 [(set (match_operand:SI 0 "register_operand" "=r")
5894 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5895 (match_operand:SI 2 "const_int_operand" "n"))
5896 (match_operand:SI 3 "const_int_operand" "n")
5898 (clobber (reg:SI T_REG))]
5899 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5901 [(set (attr "length")
5902 (cond [(match_test "shl_sext_length (insn)")
5904 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5906 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5908 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5910 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5912 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5914 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5916 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5917 (const_string "16")]
5918 (const_string "18")))
5919 (set_attr "type" "arith")])
5921 (define_insn "shl_sext_sub"
5922 [(set (match_operand:SI 0 "register_operand" "=z")
5924 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5925 (match_operand:SI 2 "const_int_operand" "n"))
5926 (match_operand:SI 3 "const_int_operand" "n")
5928 (clobber (reg:SI T_REG))]
5929 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5931 [(set (attr "length")
5932 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5934 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5936 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5938 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5939 (const_string "12")]
5940 (const_string "14")))
5941 (set_attr "type" "arith")])
5943 ;; The xtrct_left and xtrct_right patterns are used in expansions of DImode
5944 ;; shifts by 16, and allow the xtrct instruction to be generated from C
5946 (define_insn "xtrct_left"
5947 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5948 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5950 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5954 [(set_attr "type" "arith")])
5956 (define_insn "xtrct_right"
5957 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5958 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5960 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5964 [(set_attr "type" "arith")])
5966 ;; -------------------------------------------------------------------------
5968 ;; -------------------------------------------------------------------------
5971 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5972 (neg:SI (plus:SI (reg:SI T_REG)
5973 (match_operand:SI 1 "arith_reg_operand" "r"))))
5975 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5979 [(set_attr "type" "arith")])
5981 ;; A simplified version of the negc insn, where the exact value of the
5982 ;; T bit doesn't matter. This is easier for combine to pick up.
5983 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5984 ;; extra patterns for this case.
5985 (define_insn_and_split "*negc"
5986 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5987 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5988 (match_operand 2 "treg_set_expr")))
5989 (clobber (reg:SI T_REG))]
5990 "TARGET_SH1 && can_create_pseudo_p ()"
5995 sh_split_treg_set_expr (operands[2], curr_insn);
5996 emit_insn (gen_negc (operands[0], operands[1]));
6000 (define_insn "*negdi_media"
6001 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
6002 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
6005 [(set_attr "type" "arith_media")])
6007 ;; Don't split into individual negc insns immediately so that neg:DI (abs:DI)
6009 (define_expand "negdi2"
6010 [(parallel [(set (match_operand:DI 0 "arith_reg_dest")
6011 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
6012 (clobber (reg:SI T_REG))])]
6015 (define_insn_and_split "*negdi2"
6016 [(set (match_operand:DI 0 "arith_reg_dest")
6017 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
6018 (clobber (reg:SI T_REG))]
6021 "&& can_create_pseudo_p ()"
6024 emit_insn (gen_clrt ());
6025 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
6026 gen_lowpart (SImode, operands[1])));
6027 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
6028 gen_highpart (SImode, operands[1])));
6032 (define_insn "negsi2"
6033 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6034 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
6037 [(set_attr "type" "arith")])
6039 (define_insn_and_split "one_cmplsi2"
6040 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6041 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
6044 "&& can_create_pseudo_p ()"
6045 [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
6046 (set (match_dup 0) (reg:SI T_REG))]
6049 If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
6052 (set (reg0) (not:SI (reg0) (reg1)))
6053 (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
6054 (clobber (reg:SI T_REG))])
6056 ... match and combine the sequence manually in the split pass after the
6057 combine pass. Notice that combine does try the target pattern of this
6058 split, but if the pattern is added it interferes with other patterns, in
6059 particular with the div0s comparisons.
6060 This could also be done with a peephole but doing it here before register
6061 allocation can save one temporary.
6062 When we're here, the not:SI pattern obviously has been matched already
6063 and we only have to see whether the following insn is the left shift. */
6065 rtx_insn *i = next_nonnote_insn_bb (curr_insn);
6066 if (i == NULL_RTX || !NONJUMP_INSN_P (i))
6069 rtx p = PATTERN (i);
6070 if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
6073 rtx p0 = XVECEXP (p, 0, 0);
6074 rtx p1 = XVECEXP (p, 0, 1);
6076 if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
6077 GET_CODE (p0) == SET
6078 && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
6079 && REG_P (XEXP (XEXP (p0, 1), 0))
6080 && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
6081 && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
6082 && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
6084 /* (clobber (reg:SI T_REG)) */
6085 && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
6086 && REGNO (XEXP (p1, 0)) == T_REG)
6088 operands[0] = XEXP (p0, 0);
6089 set_insn_deleted (i);
6094 [(set_attr "type" "arith")])
6096 (define_expand "one_cmpldi2"
6097 [(set (match_operand:DI 0 "arith_reg_dest" "")
6098 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
6100 "TARGET_SHMEDIA" "")
6102 (define_expand "abs<mode>2"
6103 [(parallel [(set (match_operand:SIDI 0 "arith_reg_dest")
6104 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
6105 (clobber (reg:SI T_REG))])]
6108 (define_insn_and_split "*abs<mode>2"
6109 [(set (match_operand:SIDI 0 "arith_reg_dest")
6110 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
6111 (clobber (reg:SI T_REG))]
6114 "&& can_create_pseudo_p ()"
6117 if (<MODE>mode == SImode)
6118 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
6121 rtx high_src = gen_highpart (SImode, operands[1]);
6122 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
6125 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
6130 (define_insn_and_split "*negabs<mode>2"
6131 [(set (match_operand:SIDI 0 "arith_reg_dest")
6132 (neg:SIDI (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand"))))
6133 (clobber (reg:SI T_REG))]
6136 "&& can_create_pseudo_p ()"
6139 if (<MODE>mode == SImode)
6140 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
6143 rtx high_src = gen_highpart (SImode, operands[1]);
6144 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
6147 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
6152 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
6153 ;; This can be used as some kind of conditional execution, which is useful
6155 ;; Actually the instruction scheduling should decide whether to use a
6156 ;; zero-offset branch or not for any generic case involving a single
6157 ;; instruction on SH4 202.
6158 (define_insn_and_split "negsi_cond"
6159 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
6161 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand" "M,N"))
6162 (match_operand:SI 1 "arith_reg_operand" "0,0")
6163 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
6164 "TARGET_SH1 && TARGET_ZDCBRANCH"
6166 static const char* alt[] =
6176 return alt[which_alternative];
6178 "TARGET_SH1 && ! TARGET_ZDCBRANCH"
6181 rtx skip_neg_label = gen_label_rtx ();
6183 emit_move_insn (operands[0], operands[1]);
6185 emit_jump_insn (INTVAL (operands[3])
6186 ? gen_branch_true (skip_neg_label)
6187 : gen_branch_false (skip_neg_label));
6189 emit_label_after (skip_neg_label,
6190 emit_insn (gen_negsi2 (operands[0], operands[1])));
6193 [(set_attr "type" "arith") ;; poor approximation
6194 (set_attr "length" "4")])
6196 (define_insn_and_split "negdi_cond"
6197 [(set (match_operand:DI 0 "arith_reg_dest")
6199 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand"))
6200 (match_operand:DI 1 "arith_reg_operand")
6201 (neg:DI (match_operand:DI 2 "arith_reg_operand"))))
6202 (clobber (reg:SI T_REG))]
6205 "&& can_create_pseudo_p ()"
6208 rtx skip_neg_label = gen_label_rtx ();
6210 emit_move_insn (operands[0], operands[1]);
6212 emit_jump_insn (INTVAL (operands[3])
6213 ? gen_branch_true (skip_neg_label)
6214 : gen_branch_false (skip_neg_label));
6216 if (!INTVAL (operands[3]))
6217 emit_insn (gen_clrt ());
6219 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
6220 gen_lowpart (SImode, operands[1])));
6221 emit_label_after (skip_neg_label,
6222 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
6223 gen_highpart (SImode, operands[1]))));
6227 (define_expand "bswapsi2"
6228 [(set (match_operand:SI 0 "arith_reg_dest" "")
6229 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
6232 if (! can_create_pseudo_p ())
6236 rtx tmp0 = gen_reg_rtx (SImode);
6237 rtx tmp1 = gen_reg_rtx (SImode);
6239 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
6240 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
6241 emit_insn (gen_swapbsi2 (operands[0], tmp1));
6246 (define_insn "swapbsi2"
6247 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6248 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
6249 (const_int -65536)) ;; 0xFFFF0000
6250 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
6252 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
6253 (const_int 255)))))]
6256 [(set_attr "type" "arith")])
6258 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
6259 ;; partial byte swap expressions such as...
6260 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
6261 ;; ...which are currently not handled by the tree optimizers.
6262 ;; The combine pass will not initially try to combine the full expression,
6263 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
6264 ;; pattern acts as an intermediate pattern that will eventually lead combine
6265 ;; to the swapbsi2 pattern above.
6266 ;; As a side effect this also improves code that does (x & 0xFF) << 8
6267 ;; or (x << 8) & 0xFF00.
6268 (define_insn_and_split "*swapbisi2_and_shl8"
6269 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6270 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
6273 (match_operand:SI 2 "arith_reg_operand" "r")))]
6274 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
6276 "&& can_create_pseudo_p ()"
6279 rtx tmp0 = gen_reg_rtx (SImode);
6280 rtx tmp1 = gen_reg_rtx (SImode);
6282 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
6283 emit_insn (gen_swapbsi2 (tmp1, tmp0));
6284 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
6288 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
6289 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
6290 (define_insn_and_split "*swapbhisi2"
6291 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6292 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
6295 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
6296 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
6298 "&& can_create_pseudo_p ()"
6301 rtx tmp = gen_reg_rtx (SImode);
6303 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
6304 emit_insn (gen_swapbsi2 (operands[0], tmp));
6308 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
6312 ;; which can be simplified to...
6315 [(set (match_operand:SI 0 "arith_reg_dest" "")
6316 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
6317 (const_int -65536)) ;; 0xFFFF0000
6318 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
6320 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
6322 (set (match_operand:SI 2 "arith_reg_dest" "")
6324 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
6326 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
6327 (const_int -65536)) ;; 0xFFFF0000
6328 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
6330 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
6331 (const_int 255)))))])
6333 ;; -------------------------------------------------------------------------
6334 ;; Zero extension instructions
6335 ;; -------------------------------------------------------------------------
6337 (define_insn "zero_extendsidi2"
6338 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
6339 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
6341 "addz.l %1, r63, %0"
6342 [(set_attr "type" "arith_media")
6343 (set_attr "highpart" "extend")])
6345 (define_insn "zero_extendhidi2"
6346 [(set (match_operand:DI 0 "register_operand" "=r,r")
6347 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6352 [(set_attr "type" "*,load_media")
6353 (set (attr "highpart")
6354 (cond [(match_test "sh_contains_memref_p (insn)")
6355 (const_string "user")]
6356 (const_string "ignore")))])
6359 [(set (match_operand:DI 0 "register_operand" "")
6360 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
6361 "TARGET_SHMEDIA && reload_completed"
6362 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
6363 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6365 if (GET_CODE (operands[1]) == TRUNCATE)
6366 operands[1] = XEXP (operands[1], 0);
6369 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
6370 ;; reload the entire truncate expression.
6371 (define_insn_and_split "*loaddi_trunc"
6372 [(set (match_operand 0 "any_register_operand" "=r")
6373 (truncate (match_operand:DI 1 "memory_operand" "m")))]
6374 "TARGET_SHMEDIA && reload_completed"
6376 "TARGET_SHMEDIA && reload_completed"
6377 [(set (match_dup 0) (match_dup 1))]
6379 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6382 (define_insn "zero_extendqidi2"
6383 [(set (match_operand:DI 0 "register_operand" "=r,r")
6384 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6389 [(set_attr "type" "arith_media,load_media")
6390 (set (attr "highpart")
6391 (cond [(match_test "sh_contains_memref_p (insn)")
6392 (const_string "user")]
6393 (const_string "ignore")))])
6395 (define_expand "zero_extend<mode>si2"
6396 [(set (match_operand:SI 0 "arith_reg_dest")
6397 (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
6399 (define_insn_and_split "*zero_extend<mode>si2_compact"
6400 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6401 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6404 "&& can_create_pseudo_p ()"
6405 [(set (match_dup 0) (match_dup 2))]
6407 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6408 reg with a following zero extension. In the split pass after combine,
6409 try to figure out how the extended reg was set. If it originated from
6410 the T bit we can replace the zero extension with a reg move, which will
6411 be eliminated. Notice that this also helps the *cbranch_t splitter when
6412 it tries to post-combine tests and conditional branches, as it does not
6413 check for zero extensions. */
6414 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6415 if (operands[2] == NULL_RTX)
6418 [(set_attr "type" "arith")])
6420 (define_insn "*zero_extendhisi2_media"
6421 [(set (match_operand:SI 0 "register_operand" "=r,r")
6422 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6427 [(set_attr "type" "arith_media,load_media")
6428 (set (attr "highpart")
6429 (cond [(match_test "sh_contains_memref_p (insn)")
6430 (const_string "user")]
6431 (const_string "ignore")))])
6434 [(set (match_operand:SI 0 "register_operand" "")
6435 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6436 "TARGET_SHMEDIA && reload_completed"
6437 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6438 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
6440 rtx op1 = operands[1];
6442 if (GET_CODE (op1) == TRUNCATE)
6443 op1 = XEXP (op1, 0);
6445 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6446 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6449 (define_insn "*zero_extendqisi2_media"
6450 [(set (match_operand:SI 0 "register_operand" "=r,r")
6451 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6456 [(set_attr "type" "arith_media,load_media")
6457 (set (attr "highpart")
6458 (cond [(match_test "sh_contains_memref_p (insn)")
6459 (const_string "user")]
6460 (const_string "ignore")))])
6462 (define_insn "zero_extendqihi2"
6463 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6464 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6467 [(set_attr "type" "arith")])
6469 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
6470 ;; They could also be used for simple memory addresses like @Rn by setting
6471 ;; the displacement value to zero. However, doing so too early results in
6472 ;; missed opportunities for other optimizations such as post-inc or index
6473 ;; addressing loads.
6474 ;; We don't allow the zero extending loads to match during RTL expansion
6475 ;; (see zero_extend_operand predicate), as this would pessimize other
6476 ;; optimization opportunities such as bit extractions of unsigned mems,
6477 ;; where the zero extraction is irrelevant. If the zero extracting mem
6478 ;; loads are emitted early it will be more difficult to change them back
6479 ;; to sign extending loads (which are preferred).
6480 ;; The combine pass will also try to combine mem loads and zero extends,
6481 ;; which is prevented by 'sh_legitimate_combined_insn'.
6482 (define_insn "*zero_extend<mode>si2_disp_mem"
6483 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
6485 (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
6489 movu.<bw> @(0,%t1),%0"
6490 [(set_attr "type" "load")
6491 (set_attr "length" "4")])
6493 ;; Convert the zero extending loads in sequences such as:
6494 ;; movu.b @(1,r5),r0 movu.w @(2,r5),r0
6495 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6497 ;; back to sign extending loads like:
6498 ;; mov.b @(1,r5),r0 mov.w @(2,r5),r0
6499 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6501 ;; if the extension type is irrelevant. The sign extending mov.{b|w} insn
6502 ;; is only 2 bytes in size if the displacement is {K04|K05}.
6503 ;; If the displacement is greater it doesn't matter, so we convert anyways.
6505 [(set (match_operand:SI 0 "arith_reg_dest" "")
6506 (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
6507 (set (match_operand 2 "nonimmediate_operand" "")
6508 (match_operand 3 "arith_reg_operand" ""))]
6510 && REGNO (operands[0]) == REGNO (operands[3])
6511 && peep2_reg_dead_p (2, operands[0])
6512 && GET_MODE_SIZE (GET_MODE (operands[2]))
6513 <= GET_MODE_SIZE (GET_MODE (operands[1]))"
6514 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
6515 (set (match_dup 2) (match_dup 3))])
6517 ;; Fold sequences such as
6521 ;; movu.b @(0,r3),r7
6522 ;; This does not reduce the code size but the number of instructions is
6523 ;; halved, which results in faster code.
6525 [(set (match_operand:SI 0 "arith_reg_dest" "")
6526 (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
6527 (set (match_operand:SI 2 "arith_reg_dest" "")
6528 (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
6530 && GET_MODE (operands[1]) == GET_MODE (operands[3])
6531 && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
6532 && REGNO (operands[0]) == REGNO (operands[3])
6533 && (REGNO (operands[2]) == REGNO (operands[0])
6534 || peep2_reg_dead_p (2, operands[0]))"
6535 [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
6538 = replace_equiv_address (operands[1],
6539 gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
6543 ;; -------------------------------------------------------------------------
6544 ;; Sign extension instructions
6545 ;; -------------------------------------------------------------------------
6547 ;; ??? This should be a define expand.
6548 ;; ??? Or perhaps it should be dropped?
6550 ;; convert_move generates good code for SH[1-4].
6551 (define_insn "extendsidi2"
6552 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6553 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
6559 [(set_attr "type" "arith_media,load_media,fpconv_media")
6560 (set (attr "highpart")
6561 (cond [(match_test "sh_contains_memref_p (insn)")
6562 (const_string "user")]
6563 (const_string "extend")))])
6565 (define_insn "extendhidi2"
6566 [(set (match_operand:DI 0 "register_operand" "=r,r")
6567 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6572 [(set_attr "type" "*,load_media")
6573 (set (attr "highpart")
6574 (cond [(match_test "sh_contains_memref_p (insn)")
6575 (const_string "user")]
6576 (const_string "ignore")))])
6579 [(set (match_operand:DI 0 "register_operand" "")
6580 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
6581 "TARGET_SHMEDIA && reload_completed"
6582 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
6583 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6585 if (GET_CODE (operands[1]) == TRUNCATE)
6586 operands[1] = XEXP (operands[1], 0);
6589 (define_insn "extendqidi2"
6590 [(set (match_operand:DI 0 "register_operand" "=r,r")
6591 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6596 [(set_attr "type" "*,load_media")
6597 (set (attr "highpart")
6598 (cond [(match_test "sh_contains_memref_p (insn)")
6599 (const_string "user")]
6600 (const_string "ignore")))])
6603 [(set (match_operand:DI 0 "register_operand" "")
6604 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
6605 "TARGET_SHMEDIA && reload_completed"
6606 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
6607 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6609 if (GET_CODE (operands[1]) == TRUNCATE)
6610 operands[1] = XEXP (operands[1], 0);
6613 (define_expand "extend<mode>si2"
6614 [(set (match_operand:SI 0 "arith_reg_dest")
6615 (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
6617 (define_insn "*extendhisi2_media"
6618 [(set (match_operand:SI 0 "register_operand" "=r,r")
6619 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6624 [(set_attr "type" "arith_media,load_media")
6625 (set (attr "highpart")
6626 (cond [(match_test "sh_contains_memref_p (insn)")
6627 (const_string "user")]
6628 (const_string "ignore")))])
6631 [(set (match_operand:SI 0 "register_operand" "")
6632 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6633 "TARGET_SHMEDIA && reload_completed"
6634 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6635 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
6637 rtx op1 = operands[1];
6638 if (GET_CODE (op1) == TRUNCATE)
6639 op1 = XEXP (op1, 0);
6641 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6642 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6645 (define_insn_and_split "*extend<mode>si2_compact_reg"
6646 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6647 (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6650 "&& can_create_pseudo_p ()"
6651 [(set (match_dup 0) (match_dup 2))]
6653 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6654 reg with a following sign extension. In the split pass after combine,
6655 try to figure the extended reg was set. If it originated from the T
6656 bit we can replace the sign extension with a reg move, which will be
6658 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6659 if (operands[2] == NULL_RTX)
6662 [(set_attr "type" "arith")])
6664 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
6666 (define_insn "*extend<mode>si2_compact_mem_disp"
6667 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
6671 (match_operand:SI 1 "arith_reg_operand" "%r,r")
6672 (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
6673 "TARGET_SH1 && ! TARGET_SH2A
6674 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6676 mov.<bw> @(%O2,%1),%0
6678 [(set_attr "type" "load")])
6680 (define_insn "*extend<mode>si2_compact_mem_disp"
6681 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
6685 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6686 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
6687 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6689 mov.<bw> @(%O2,%1),%0
6691 mov.<bw> @(%O2,%1),%0"
6692 [(set_attr "type" "load")
6693 (set_attr "length" "2,2,4")])
6695 ;; The *_snd patterns will take care of other QImode/HImode addressing
6696 ;; modes than displacement addressing. They must be defined _after_ the
6697 ;; displacement addressing patterns. Otherwise the displacement addressing
6698 ;; patterns will not be picked.
6699 (define_insn "*extend<mode>si2_compact_snd"
6700 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6702 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
6705 [(set_attr "type" "load")])
6707 (define_insn "*extendqisi2_media"
6708 [(set (match_operand:SI 0 "register_operand" "=r,r")
6709 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6714 [(set_attr "type" "arith_media,load_media")
6715 (set (attr "highpart")
6716 (cond [(match_test "sh_contains_memref_p (insn)")
6717 (const_string "user")]
6718 (const_string "ignore")))])
6721 [(set (match_operand:SI 0 "register_operand" "")
6722 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
6723 "TARGET_SHMEDIA && reload_completed"
6724 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
6725 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
6727 rtx op1 = operands[1];
6728 if (GET_CODE (op1) == TRUNCATE)
6729 op1 = XEXP (op1, 0);
6731 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6732 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6735 (define_expand "extendqihi2"
6736 [(set (match_operand:HI 0 "arith_reg_dest")
6737 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand")))]
6740 (define_insn "*extendqihi2_compact_reg"
6741 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6742 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6745 [(set_attr "type" "arith")])
6747 ;; It would seem useful to combine the truncXi patterns into the movXi
6748 ;; patterns, but unary operators are ignored when matching constraints,
6749 ;; so we need separate patterns.
6750 (define_insn "truncdisi2"
6751 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
6752 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
6761 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,
6762 fpconv_media,fmove_media")
6763 (set (attr "highpart")
6764 (cond [(match_test "sh_contains_memref_p (insn)")
6765 (const_string "user")]
6766 (const_string "extend")))])
6768 (define_insn "truncdihi2"
6769 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
6770 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
6773 static const char* alt[] =
6775 "shlli %1,48,%0" "\n"
6780 return alt[which_alternative];
6782 [(set_attr "type" "arith_media,store_media")
6783 (set_attr "length" "8,4")
6784 (set (attr "highpart")
6785 (cond [(match_test "sh_contains_memref_p (insn)")
6786 (const_string "user")]
6787 (const_string "extend")))])
6789 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
6790 ; Because we use zero extension, we can't provide signed QImode compares
6791 ; using a simple compare or conditional branch insn.
6792 (define_insn "truncdiqi2"
6793 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
6794 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
6799 [(set_attr "type" "arith_media,store")
6800 (set (attr "highpart")
6801 (cond [(match_test "sh_contains_memref_p (insn)")
6802 (const_string "user")]
6803 (const_string "extend")))])
6805 ;; -------------------------------------------------------------------------
6806 ;; Move instructions
6807 ;; -------------------------------------------------------------------------
6809 ;; define push and pop so it is easy for sh.c
6810 ;; We can't use push and pop on SHcompact because the stack must always
6811 ;; be 8-byte aligned.
6812 (define_expand "push"
6813 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6814 (match_operand:SI 0 "register_operand" "r,l,x"))]
6815 "TARGET_SH1 && ! TARGET_SH5"
6818 (define_expand "pop"
6819 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6820 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6821 "TARGET_SH1 && ! TARGET_SH5"
6824 (define_expand "push_e"
6825 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6826 (match_operand:SF 0 "" ""))
6827 (use (reg:SI FPSCR_MODES_REG))
6828 (clobber (scratch:SI))])]
6829 "TARGET_SH1 && ! TARGET_SH5"
6832 (define_insn "push_fpul"
6833 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6834 "TARGET_SH2E && ! TARGET_SH5"
6836 [(set_attr "type" "fstore")
6837 (set_attr "late_fp_use" "yes")
6838 (set_attr "hit_stack" "yes")])
6840 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6842 (define_expand "push_4"
6843 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6844 (match_operand:DF 0 "" ""))
6845 (use (reg:SI FPSCR_MODES_REG))
6846 (clobber (scratch:SI))])]
6847 "TARGET_SH1 && ! TARGET_SH5"
6850 (define_expand "pop_e"
6851 [(parallel [(set (match_operand:SF 0 "" "")
6852 (mem:SF (post_inc:SI (reg:SI SP_REG))))
6853 (use (reg:SI FPSCR_MODES_REG))
6854 (clobber (scratch:SI))])]
6855 "TARGET_SH1 && ! TARGET_SH5"
6858 (define_insn "pop_fpul"
6859 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6860 "TARGET_SH2E && ! TARGET_SH5"
6862 [(set_attr "type" "load")
6863 (set_attr "hit_stack" "yes")])
6865 (define_expand "pop_4"
6866 [(parallel [(set (match_operand:DF 0 "" "")
6867 (mem:DF (post_inc:SI (reg:SI SP_REG))))
6868 (use (reg:SI FPSCR_MODES_REG))
6869 (clobber (scratch:SI))])]
6870 "TARGET_SH1 && ! TARGET_SH5"
6873 (define_expand "push_fpscr"
6880 gen_frame_mem (SImode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)))),
6881 REG_INC, stack_pointer_rtx);
6885 (define_expand "pop_fpscr"
6892 gen_frame_mem (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx)))),
6893 REG_INC, stack_pointer_rtx);
6897 ;; The clrt and sett patterns can happen as the result of optimization and
6899 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6900 ;; In this case they might not disappear completely, because the T reg is
6901 ;; a fixed hard reg.
6902 ;; When DImode operations that use the T reg as carry/borrow are split into
6903 ;; individual SImode operations, the T reg is usually cleared before the
6904 ;; first SImode insn.
6906 [(set (reg:SI T_REG) (const_int 0))]
6909 [(set_attr "type" "mt_group")])
6912 [(set (reg:SI T_REG) (const_int 1))]
6915 [(set_attr "type" "mt_group")])
6917 ;; Use the combine pass to transform sequences such as
6921 ;; mov.l @(r0,r4),r0
6927 ;; See also PR 39423.
6928 ;; Notice that these patterns have a T_REG clobber, because the shift
6929 ;; sequence that will be split out might clobber the T_REG. Ideally, the
6930 ;; clobber would be added conditionally, depending on the result of
6931 ;; sh_ashlsi_clobbers_t_reg_p. When splitting out the shifts we must go
6932 ;; through the ashlsi3 expander in order to get the right shift insn --
6933 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6934 ;; FIXME: Combine never tries this kind of patterns for DImode.
6935 (define_insn_and_split "*movsi_index_disp_load"
6936 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6937 (match_operand:SI 1 "mem_index_disp_operand" "m"))
6938 (clobber (reg:SI T_REG))]
6941 "&& can_create_pseudo_p ()"
6942 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6943 (set (match_dup 0) (match_dup 7))]
6945 rtx mem = operands[1];
6946 rtx plus0_rtx = XEXP (mem, 0);
6947 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6948 rtx mult_rtx = XEXP (plus1_rtx, 0);
6950 operands[1] = XEXP (mult_rtx, 0);
6951 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6952 operands[3] = XEXP (plus1_rtx, 1);
6953 operands[4] = XEXP (plus0_rtx, 1);
6954 operands[5] = gen_reg_rtx (SImode);
6955 operands[6] = gen_reg_rtx (SImode);
6957 replace_equiv_address (mem,
6958 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6960 emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6963 (define_insn_and_split "*movhi_index_disp_load"
6964 [(set (match_operand:SI 0 "arith_reg_dest")
6965 (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6966 (clobber (reg:SI T_REG))]
6969 "&& can_create_pseudo_p ()"
6972 rtx mem = operands[1];
6973 rtx plus0_rtx = XEXP (mem, 0);
6974 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6975 rtx mult_rtx = XEXP (plus1_rtx, 0);
6977 rtx op_1 = XEXP (mult_rtx, 0);
6978 rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6979 rtx op_3 = XEXP (plus1_rtx, 1);
6980 rtx op_4 = XEXP (plus0_rtx, 1);
6981 rtx op_5 = gen_reg_rtx (SImode);
6982 rtx op_6 = gen_reg_rtx (SImode);
6983 rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6985 emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6986 emit_insn (gen_addsi3 (op_6, op_5, op_3));
6988 if (<CODE> == SIGN_EXTEND)
6990 emit_insn (gen_extendhisi2 (operands[0], op_7));
6993 else if (<CODE> == ZERO_EXTEND)
6995 /* On SH2A the movu.w insn can be used for zero extending loads. */
6997 emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
7000 emit_insn (gen_extendhisi2 (operands[0], op_7));
7001 emit_insn (gen_zero_extendhisi2 (operands[0],
7002 gen_lowpart (HImode, operands[0])));
7010 (define_insn_and_split "*mov<mode>_index_disp_store"
7011 [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
7012 (match_operand:HISI 1 "arith_reg_operand" "r"))
7013 (clobber (reg:SI T_REG))]
7016 "&& can_create_pseudo_p ()"
7017 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
7018 (set (match_dup 7) (match_dup 1))]
7020 rtx mem = operands[0];
7021 rtx plus0_rtx = XEXP (mem, 0);
7022 rtx plus1_rtx = XEXP (plus0_rtx, 0);
7023 rtx mult_rtx = XEXP (plus1_rtx, 0);
7025 operands[0] = XEXP (mult_rtx, 0);
7026 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
7027 operands[3] = XEXP (plus1_rtx, 1);
7028 operands[4] = XEXP (plus0_rtx, 1);
7029 operands[5] = gen_reg_rtx (SImode);
7030 operands[6] = gen_reg_rtx (SImode);
7032 replace_equiv_address (mem,
7033 gen_rtx_PLUS (SImode, operands[6], operands[4]));
7035 emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
7038 ;; t/r must come after r/r, lest reload will try to reload stuff like
7039 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
7040 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
7041 (define_insn "movsi_i"
7042 [(set (match_operand:SI 0 "general_movdst_operand"
7043 "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
7044 (match_operand:SI 1 "general_movsrc_operand"
7045 "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
7049 && (register_operand (operands[0], SImode)
7050 || register_operand (operands[1], SImode))"
7066 [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,
7067 pstore,gp_mac,prset,mem_mac,pload,pcload_si")
7068 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
7070 ;; t/r must come after r/r, lest reload will try to reload stuff like
7071 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
7072 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
7073 ;; will require a reload.
7074 ;; ??? We can't include f/f because we need the proper FPSCR setting when
7075 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
7076 (define_insn "movsi_ie"
7077 [(set (match_operand:SI 0 "general_movdst_operand"
7078 "=r,r,r,r,r,r,r,r,mr,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
7079 (match_operand:SI 1 "general_movsrc_operand"
7080 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
7081 "(TARGET_SH2E || TARGET_SH2A)
7082 && ((register_operand (operands[0], SImode)
7083 && !fpscr_operand (operands[0], SImode))
7084 || (register_operand (operands[1], SImode)
7085 && !fpscr_operand (operands[1], SImode)))"
7110 ! move optimized away"
7111 [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,
7112 mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,
7113 pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
7114 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
7115 (set_attr_alternative "length"
7122 (match_test "TARGET_SH2A")
7123 (const_int 4) (const_int 2))
7127 (match_test "TARGET_SH2A")
7128 (const_int 4) (const_int 2))
7145 (define_insn "movsi_i_lowpart"
7146 [(set (strict_low_part
7147 (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
7148 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
7150 && (register_operand (operands[0], SImode)
7151 || register_operand (operands[1], SImode))"
7161 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
7163 (define_insn_and_split "load_ra"
7164 [(set (match_operand:SI 0 "general_movdst_operand" "")
7165 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
7168 "&& ! currently_expanding_to_rtl"
7169 [(set (match_dup 0) (match_dup 1))]
7171 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
7172 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
7175 ;; The '?'s in the following constraints may not reflect the time taken
7176 ;; to perform the move. They are there to discourage the use of floating-
7177 ;; point registers for storing integer values.
7178 (define_insn "*movsi_media"
7179 [(set (match_operand:SI 0 "general_movdst_operand"
7180 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
7181 (match_operand:SI 1 "general_movsrc_operand"
7182 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7184 && (register_operand (operands[0], SImode)
7185 || sh_register_operand (operands[1], SImode)
7186 || GET_CODE (operands[1]) == TRUNCATE)"
7201 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7202 fload_media,fstore_media,fload_media,fpconv_media,
7203 fmove_media,ptabs_media,gettr_media,pt_media")
7204 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
7205 (set (attr "highpart")
7206 (cond [(match_test "sh_contains_memref_p (insn)")
7207 (const_string "user")]
7208 (const_string "ignore")))])
7210 (define_insn "*movsi_media_nofpu"
7211 [(set (match_operand:SI 0 "general_movdst_operand"
7212 "=r,r,r,r,m,*b,r,*b")
7213 (match_operand:SI 1 "general_movsrc_operand"
7214 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
7216 && (register_operand (operands[0], SImode)
7217 || sh_register_operand (operands[1], SImode)
7218 || GET_CODE (operands[1]) == TRUNCATE)"
7228 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7229 ptabs_media,gettr_media,pt_media")
7230 (set_attr "length" "4,4,8,4,4,4,4,12")
7231 (set (attr "highpart")
7232 (cond [(match_test "sh_contains_memref_p (insn)")
7233 (const_string "user")]
7234 (const_string "ignore")))])
7236 (define_expand "movsi_const"
7237 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7238 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
7239 (const_int 16)] UNSPEC_EXTRACT_S16)))
7241 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
7242 (const:SI (unspec:SI [(match_dup 1)
7243 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7244 "TARGET_SHMEDIA && reload_completed
7245 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7247 if (GET_CODE (operands[1]) == LABEL_REF
7248 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
7249 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
7250 else if (GOTOFF_P (operands[1]))
7252 rtx unspec = XEXP (operands[1], 0);
7254 if (! UNSPEC_GOTOFF_P (unspec))
7256 unspec = XEXP (unspec, 0);
7257 if (! UNSPEC_GOTOFF_P (unspec))
7260 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
7261 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
7262 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
7266 (define_expand "movsi_const_16bit"
7267 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7268 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
7269 (const_int 0)] UNSPEC_EXTRACT_S16)))]
7270 "TARGET_SHMEDIA && flag_pic && reload_completed
7271 && GET_CODE (operands[1]) == SYMBOL_REF"
7275 [(set (match_operand:SI 0 "arith_reg_dest" "")
7276 (match_operand:SI 1 "immediate_operand" ""))]
7277 "TARGET_SHMEDIA && reload_completed
7278 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7281 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
7283 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7289 [(set (match_operand:SI 0 "register_operand" "")
7290 (match_operand:SI 1 "immediate_operand" ""))]
7291 "TARGET_SHMEDIA && reload_completed
7292 && ((CONST_INT_P (operands[1])
7293 && ! satisfies_constraint_I16 (operands[1]))
7294 || GET_CODE (operands[1]) == CONST_DOUBLE)"
7295 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
7297 (define_expand "movsi"
7298 [(set (match_operand:SI 0 "general_movdst_operand" "")
7299 (match_operand:SI 1 "general_movsrc_operand" ""))]
7302 prepare_move_operands (operands, SImode);
7305 (define_expand "ic_invalidate_line"
7306 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
7307 (match_dup 1)] UNSPEC_ICACHE)
7308 (clobber (scratch:SI))])]
7309 "TARGET_HARD_SH4 || TARGET_SH5"
7313 emit_insn (gen_ic_invalidate_line_media (operands[0]));
7316 else if (TARGET_SHCOMPACT)
7318 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
7319 operands[1] = force_reg (Pmode, operands[1]);
7320 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
7323 else if (TARGET_SH4A || TARGET_SH4_300)
7325 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
7328 operands[0] = force_reg (Pmode, operands[0]);
7329 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
7333 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
7334 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
7335 ;; the requirement *1*00 for associative address writes. The alignment of
7336 ;; %0 implies that its least significant bit is cleared,
7337 ;; thus we clear the V bit of a matching entry if there is one.
7338 (define_insn "ic_invalidate_line_i"
7339 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
7340 (match_operand:SI 1 "register_operand" "r")]
7342 (clobber (match_scratch:SI 2 "=&r"))]
7345 return "ocbwb @%0" "\n"
7346 " extu.w %0,%2" "\n"
7350 [(set_attr "length" "8")
7351 (set_attr "type" "cwb")])
7353 (define_insn "ic_invalidate_line_sh4a"
7354 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
7356 "TARGET_SH4A || TARGET_SH4_300"
7358 return "ocbwb @%0" "\n"
7362 [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
7363 (set_attr "type" "cwb")])
7365 ;; ??? could make arg 0 an offsettable memory operand to allow to save
7366 ;; an add in the code that calculates the address.
7367 (define_insn "ic_invalidate_line_media"
7368 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
7372 return "ocbwb %0,0" "\n"
7377 [(set_attr "length" "16")
7378 (set_attr "type" "invalidate_line_media")])
7380 (define_insn "ic_invalidate_line_compact"
7381 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
7382 (match_operand:SI 1 "register_operand" "r")]
7384 (clobber (reg:SI PR_REG))]
7387 [(set_attr "type" "sfunc")
7388 (set_attr "needs_delay_slot" "yes")])
7390 (define_expand "initialize_trampoline"
7391 [(match_operand:SI 0 "" "")
7392 (match_operand:SI 1 "" "")
7393 (match_operand:SI 2 "" "")]
7398 tramp = force_reg (Pmode, operands[0]);
7399 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
7401 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
7402 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
7404 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
7408 (define_insn "initialize_trampoline_compact"
7409 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
7410 (match_operand:SI 1 "register_operand" "r")
7411 (reg:SI R2_REG) (reg:SI R3_REG)]
7414 (clobber (reg:SI PR_REG))]
7417 [(set_attr "type" "sfunc")
7418 (set_attr "needs_delay_slot" "yes")])
7420 (define_expand "mov<mode>"
7421 [(set (match_operand:QIHI 0 "general_movdst_operand")
7422 (match_operand:QIHI 1 "general_movsrc_operand"))]
7425 if (can_create_pseudo_p () && CONST_INT_P (operands[1])
7426 && REG_P (operands[0]) && REGNO (operands[0]) != R0_REG)
7428 rtx reg = gen_reg_rtx(SImode);
7429 emit_move_insn (reg, operands[1]);
7430 operands[1] = gen_lowpart (<MODE>mode, reg);
7433 prepare_move_operands (operands, <MODE>mode);
7436 ;; Specifying the displacement addressing load / store patterns separately
7437 ;; before the generic movqi / movhi pattern allows controlling the order
7438 ;; in which load / store insns are selected in a more fine grained way.
7439 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
7440 ;; "enabled" attribute as it is done in other targets.
7441 (define_insn "*mov<mode>_store_mem_disp04"
7443 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
7444 (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
7445 (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
7446 "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
7448 mov.<bw> %2,@(%O1,%0)
7450 [(set_attr "type" "store")])
7452 (define_insn "*mov<mode>_store_mem_disp12"
7454 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
7455 (match_operand:SI 1 "const_int_operand" "<disp12>")))
7456 (match_operand:QIHI 2 "arith_reg_operand" "r"))]
7457 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
7458 "mov.<bw> %2,@(%O1,%0)"
7459 [(set_attr "type" "store")
7460 (set_attr "length" "4")])
7462 (define_insn "*mov<mode>_load_mem_disp04"
7463 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
7465 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
7466 (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
7467 "TARGET_SH1 && ! TARGET_SH2A
7468 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
7470 mov.<bw> @(%O2,%1),%0
7472 [(set_attr "type" "load")])
7474 (define_insn "*mov<mode>_load_mem_disp12"
7475 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
7478 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
7479 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
7480 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
7482 mov.<bw> @(%O2,%1),%0
7484 mov.<bw> @(%O2,%1),%0"
7485 [(set_attr "type" "load")
7486 (set_attr "length" "2,2,4")])
7488 ;; The order of the constraint alternatives is important here.
7489 ;; Q/r has to come first, otherwise PC relative loads might wrongly get
7490 ;; placed into delay slots. Since there is no QImode PC relative load, the
7491 ;; Q constraint and general_movsrc_operand will reject it for QImode.
7492 ;; The Sid/Ssd alternatives should come before Sdd in order to avoid
7493 ;; a preference of using r0 als the register operand for addressing modes
7494 ;; other than displacement addressing.
7495 ;; The Sdd alternatives allow only r0 as register operand, even though on
7496 ;; SH2A any register could be allowed by switching to a 32 bit insn.
7497 ;; Generally sticking to the r0 is preferrable, since it generates smaller
7498 ;; code. Obvious r0 reloads can then be eliminated with a peephole on SH2A.
7499 (define_insn "*mov<mode>"
7500 [(set (match_operand:QIHI 0 "general_movdst_operand"
7501 "=r,r,r,Sid,^zr,Ssd,r, Sdd,z, r,l")
7502 (match_operand:QIHI 1 "general_movsrc_operand"
7503 "Q,r,i,^zr,Sid,r, Ssd,z, Sdd,l,r"))]
7505 && (arith_reg_operand (operands[0], <MODE>mode)
7506 || arith_reg_operand (operands[1], <MODE>mode))"
7519 [(set_attr "type" "pcload,move,movi8,store,load,store,load,store,load,prget,prset")
7520 (set (attr "length")
7521 (cond [(and (match_operand 0 "displacement_mem_operand")
7522 (not (match_operand 0 "short_displacement_mem_operand")))
7524 (and (match_operand 1 "displacement_mem_operand")
7525 (not (match_operand 1 "short_displacement_mem_operand")))
7529 (define_insn "*movqi_media"
7530 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
7531 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
7533 && (arith_reg_operand (operands[0], QImode)
7534 || extend_reg_or_0_operand (operands[1], QImode))"
7540 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
7541 (set (attr "highpart")
7542 (cond [(match_test "sh_contains_memref_p (insn)")
7543 (const_string "user")]
7544 (const_string "ignore")))])
7546 (define_expand "reload_inqi"
7547 [(set (match_operand:SI 2 "" "=&r")
7548 (match_operand:QI 1 "inqhi_operand" ""))
7549 (set (match_operand:QI 0 "arith_reg_operand" "=r")
7550 (truncate:QI (match_dup 3)))]
7553 rtx inner = XEXP (operands[1], 0);
7554 int regno = REGNO (inner);
7556 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7557 operands[1] = gen_rtx_REG (SImode, regno);
7558 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7561 (define_insn "*movhi_media"
7562 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
7563 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
7565 && (arith_reg_operand (operands[0], HImode)
7566 || arith_reg_or_0_operand (operands[1], HImode))"
7573 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
7574 (set (attr "highpart")
7575 (cond [(match_test "sh_contains_memref_p (insn)")
7576 (const_string "user")]
7577 (const_string "ignore")))])
7580 [(set (match_operand:HI 0 "register_operand" "")
7581 (match_operand:HI 1 "immediate_operand" ""))]
7582 "TARGET_SHMEDIA && reload_completed
7583 && ! satisfies_constraint_I16 (operands[1])"
7584 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
7586 (define_expand "reload_inhi"
7587 [(set (match_operand:SI 2 "" "=&r")
7588 (match_operand:HI 1 "inqhi_operand" ""))
7589 (set (match_operand:HI 0 "arith_reg_operand" "=r")
7590 (truncate:HI (match_dup 3)))]
7593 rtx inner = XEXP (operands[1], 0);
7594 int regno = REGNO (inner);
7596 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7597 operands[1] = gen_rtx_REG (SImode, regno);
7598 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7601 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7602 ;; compiled with -m2 -ml -O3 -funroll-loops
7603 (define_insn "*movdi_i"
7604 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7605 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7607 && (arith_reg_operand (operands[0], DImode)
7608 || arith_reg_operand (operands[1], DImode))"
7610 return output_movedouble (insn, operands, DImode);
7612 [(set_attr "length" "4")
7613 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7615 ;; If the output is a register and the input is memory or a register, we have
7616 ;; to be careful and see which word needs to be loaded first.
7618 [(set (match_operand:DI 0 "general_movdst_operand" "")
7619 (match_operand:DI 1 "general_movsrc_operand" ""))]
7620 "TARGET_SH1 && reload_completed"
7621 [(set (match_dup 2) (match_dup 3))
7622 (set (match_dup 4) (match_dup 5))]
7626 if ((MEM_P (operands[0])
7627 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7628 || (MEM_P (operands[1])
7629 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7632 switch (GET_CODE (operands[0]))
7635 regno = REGNO (operands[0]);
7638 regno = subreg_regno (operands[0]);
7647 if (regno == -1 || ! refers_to_regno_p (regno, operands[1]))
7649 operands[2] = operand_subword (operands[0], 0, 0, DImode);
7650 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7651 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7652 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7656 operands[2] = operand_subword (operands[0], 1, 0, DImode);
7657 operands[3] = operand_subword (operands[1], 1, 0, DImode);
7658 operands[4] = operand_subword (operands[0], 0, 0, DImode);
7659 operands[5] = operand_subword (operands[1], 0, 0, DImode);
7662 if (operands[2] == 0 || operands[3] == 0
7663 || operands[4] == 0 || operands[5] == 0)
7667 ;; The '?'s in the following constraints may not reflect the time taken
7668 ;; to perform the move. They are there to discourage the use of floating-
7669 ;; point registers for storing integer values.
7670 (define_insn "*movdi_media"
7671 [(set (match_operand:DI 0 "general_movdst_operand"
7672 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7673 (match_operand:DI 1 "general_movsrc_operand"
7674 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7676 && (register_operand (operands[0], DImode)
7677 || sh_register_operand (operands[1], DImode))"
7692 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7693 fload_media,fstore_media,fload_media,dfpconv_media,
7694 fmove_media,ptabs_media,gettr_media,pt_media")
7695 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7697 (define_insn "*movdi_media_nofpu"
7698 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7699 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7701 && (register_operand (operands[0], DImode)
7702 || sh_register_operand (operands[1], DImode))"
7712 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7713 ptabs_media,gettr_media,pt_media")
7714 (set_attr "length" "4,4,16,4,4,4,4,*")])
7716 (define_insn "*movdi_media_I16"
7717 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7718 (match_operand:DI 1 "const_int_operand" "I16"))]
7719 "TARGET_SHMEDIA && reload_completed"
7721 [(set_attr "type" "arith_media")
7722 (set_attr "length" "4")])
7725 [(set (match_operand:DI 0 "arith_reg_dest" "")
7726 (match_operand:DI 1 "immediate_operand" ""))]
7727 "TARGET_SHMEDIA && reload_completed
7728 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7729 [(set (match_dup 0) (match_dup 1))]
7733 if (TARGET_SHMEDIA64)
7734 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7736 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7738 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7743 (define_expand "movdi_const"
7744 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7745 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7746 (const_int 48)] UNSPEC_EXTRACT_S16)))
7748 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7749 (const:DI (unspec:DI [(match_dup 1)
7750 (const_int 32)] UNSPEC_EXTRACT_U16))))
7752 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7753 (const:DI (unspec:DI [(match_dup 1)
7754 (const_int 16)] UNSPEC_EXTRACT_U16))))
7756 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7757 (const:DI (unspec:DI [(match_dup 1)
7758 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7759 "TARGET_SHMEDIA64 && reload_completed
7760 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7762 sh_mark_label (operands[1], 4);
7765 (define_expand "movdi_const_32bit"
7766 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7767 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7768 (const_int 16)] UNSPEC_EXTRACT_S16)))
7770 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7771 (const:DI (unspec:DI [(match_dup 1)
7772 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7773 "TARGET_SHMEDIA32 && reload_completed
7774 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7776 sh_mark_label (operands[1], 2);
7779 (define_expand "movdi_const_16bit"
7780 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7781 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7782 (const_int 0)] UNSPEC_EXTRACT_S16)))]
7783 "TARGET_SHMEDIA && flag_pic && reload_completed
7784 && GET_CODE (operands[1]) == SYMBOL_REF"
7788 [(set (match_operand:DI 0 "ext_dest_operand" "")
7789 (match_operand:DI 1 "immediate_operand" ""))]
7790 "TARGET_SHMEDIA && reload_completed
7791 && CONST_INT_P (operands[1])
7792 && ! satisfies_constraint_I16 (operands[1])"
7793 [(set (match_dup 0) (match_dup 2))
7796 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7797 unsigned HOST_WIDE_INT low = val;
7798 unsigned HOST_WIDE_INT high = val;
7799 unsigned HOST_WIDE_INT sign;
7800 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7802 /* Zero-extend the 16 least-significant bits. */
7805 /* Arithmetic shift right the word by 16 bits. */
7807 if (GET_CODE (operands[0]) == SUBREG
7808 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7817 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7823 /* If we can't generate the constant with a two-insn movi / shori
7824 sequence, try some other strategies. */
7825 if (! CONST_OK_FOR_I16 (high))
7827 /* Try constant load / left shift. We know VAL != 0. */
7828 val2 = val ^ (val-1);
7831 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7833 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7834 || (! CONST_OK_FOR_I16 (high >> 16)
7835 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7837 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7838 operands[1] = gen_ashldi3_media (operands[0], operands[0],
7839 GEN_INT (trailing_zeroes));
7843 /* Try constant load / right shift. */
7844 val2 = (val >> 15) + 1;
7845 if (val2 == (val2 & -val2))
7847 int shift = 49 - exact_log2 (val2);
7849 val2 = trunc_int_for_mode (val << shift, DImode);
7850 if (CONST_OK_FOR_I16 (val2))
7852 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7858 val2 = val & 0xffff;
7859 if ((val >> 16 & 0xffff) == val2
7860 && (val >> 32 & 0xffff) == val2
7861 && (val >> 48 & 0xffff) == val2)
7863 val2 = (HOST_WIDE_INT) val >> 48;
7864 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7865 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7868 /* Try movi / mshflo.l */
7869 val2 = (HOST_WIDE_INT) val >> 32;
7870 if (val2 == ((unsigned HOST_WIDE_INT)
7871 trunc_int_for_mode (val, SImode)))
7873 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7877 /* Try movi / mshflo.l w/ r63. */
7878 val2 = val + ((HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 32));
7879 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7881 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7887 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7890 operands[2] = GEN_INT (val2);
7894 [(set (match_operand:DI 0 "ext_dest_operand" "")
7895 (match_operand:DI 1 "immediate_operand" ""))]
7896 "TARGET_SHMEDIA && reload_completed
7897 && GET_CODE (operands[1]) == CONST_DOUBLE"
7898 [(set (match_dup 0) (match_dup 2))
7900 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7902 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7903 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7904 unsigned HOST_WIDE_INT val = low;
7905 unsigned HOST_WIDE_INT sign;
7907 /* Zero-extend the 16 least-significant bits. */
7909 operands[1] = GEN_INT (val);
7911 /* Arithmetic shift right the double-word by 16 bits. */
7913 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7916 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7920 /* This will only be true if high is a sign-extension of low, i.e.,
7921 it must be either 0 or (unsigned)-1, and be zero iff the
7922 most-significant bit of low is set. */
7923 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7924 operands[2] = GEN_INT (low);
7926 operands[2] = immed_double_const (low, high, DImode);
7929 (define_insn "shori_media"
7930 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7931 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7933 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7934 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7938 [(set_attr "type" "arith_media,*")])
7940 (define_insn "*shori_media_si"
7941 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7942 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7944 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7948 (define_expand "movdi"
7949 [(set (match_operand:DI 0 "general_movdst_operand" "")
7950 (match_operand:DI 1 "general_movsrc_operand" ""))]
7953 prepare_move_operands (operands, DImode);
7956 /* When the dest operand is (R0, R1) register pair, split it to
7957 two movsi of which dest is R1 and R0 so as to lower R0-register
7958 pressure on the first movsi. Apply only for simple source not
7959 to make complex rtl here. */
7960 if (REG_P (operands[0])
7961 && REGNO (operands[0]) == R0_REG
7962 && REG_P (operands[1])
7963 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
7965 emit_insn (gen_movsi (gen_rtx_REG (SImode, R1_REG),
7966 gen_rtx_SUBREG (SImode, operands[1], 4)));
7967 emit_insn (gen_movsi (gen_rtx_REG (SImode, R0_REG),
7968 gen_rtx_SUBREG (SImode, operands[1], 0)));
7974 (define_insn "movdf_media"
7975 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7976 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7978 && (register_operand (operands[0], DFmode)
7979 || sh_register_operand (operands[1], DFmode))"
7990 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,
7991 fload_media,fstore_media,load_media,store_media")])
7993 (define_insn "movdf_media_nofpu"
7994 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7995 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7997 && (register_operand (operands[0], DFmode)
7998 || sh_register_operand (operands[1], DFmode))"
8004 [(set_attr "type" "arith_media,*,load_media,store_media")])
8007 [(set (match_operand:DF 0 "arith_reg_dest" "")
8008 (match_operand:DF 1 "immediate_operand" ""))]
8009 "TARGET_SHMEDIA && reload_completed"
8010 [(set (match_dup 3) (match_dup 2))]
8012 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
8015 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), values);
8017 if (HOST_BITS_PER_WIDE_INT >= 64)
8018 operands[2] = immed_double_const ((unsigned long) values[endian]
8019 | ((HOST_WIDE_INT) values[1 - endian]
8023 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
8024 operands[2] = immed_double_const (values[endian], values[1 - endian],
8028 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8031 ;; FIXME: This should be a define_insn_and_split.
8032 (define_insn "movdf_k"
8033 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
8034 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
8036 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
8037 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
8038 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8039 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8040 && (arith_reg_operand (operands[0], DFmode)
8041 || arith_reg_operand (operands[1], DFmode))"
8043 return output_movedouble (insn, operands, DFmode);
8045 [(set_attr "length" "4")
8046 (set_attr "type" "move,pcload,load,store")])
8048 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
8049 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
8050 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
8051 ;; the d/m/c/X alternative, which is split later into single-precision
8052 ;; instructions. And when not optimizing, no splits are done before fixing
8053 ;; up pcloads, so we need usable length information for that.
8054 (define_insn "movdf_i4"
8055 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
8056 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
8057 (use (reg:SI FPSCR_MODES_REG))
8058 (clobber (match_scratch:SI 2 "=X,X,&z,X,X,X,X,X,X,X"))]
8059 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
8060 && (arith_reg_operand (operands[0], DFmode)
8061 || arith_reg_operand (operands[1], DFmode))"
8063 switch (which_alternative)
8067 return "fmov %1,%0";
8068 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
8069 return "fmov %R1,%R0" "\n"
8072 return "fmov %S1,%S0" "\n"
8076 return "fmov.d %1,%0";
8081 [(set_attr_alternative "length"
8082 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
8084 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
8085 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
8086 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
8088 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
8089 ;; We can't use 4-byte push/pop on SHcompact, so we have to
8090 ;; increment or decrement r15 explicitly.
8092 (match_test "TARGET_SHCOMPACT")
8093 (const_int 10) (const_int 8))
8095 (match_test "TARGET_SHCOMPACT")
8096 (const_int 10) (const_int 8))])
8097 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
8098 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
8099 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
8100 (const_string "double")
8101 (const_string "none")))])
8103 ;; Moving DFmode between fp/general registers through memory
8104 ;; (the top of the stack) is faster than moving through fpul even for
8105 ;; little endian. Because the type of an instruction is important for its
8106 ;; scheduling, it is beneficial to split these operations, rather than
8107 ;; emitting them in one single chunk, even if this will expose a stack
8108 ;; use that will prevent scheduling of other stack accesses beyond this
8111 [(set (match_operand:DF 0 "register_operand")
8112 (match_operand:DF 1 "register_operand"))
8113 (use (reg:SI FPSCR_MODES_REG))
8114 (clobber (match_scratch:SI 2))]
8115 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
8116 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
8121 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
8123 emit_move_insn (stack_pointer_rtx,
8124 plus_constant (Pmode, stack_pointer_rtx, -8));
8125 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
8128 tos = gen_tmp_stack_mem (DFmode,
8129 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
8130 insn = emit_insn (gen_movdf_i4 (tos, operands[1]));
8131 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
8132 add_reg_note (insn, REG_INC, stack_pointer_rtx);
8133 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
8134 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
8136 tos = gen_tmp_stack_mem (DFmode,
8137 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
8138 insn = emit_insn (gen_movdf_i4 (operands[0], tos));
8139 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
8140 emit_move_insn (stack_pointer_rtx,
8141 plus_constant (Pmode, stack_pointer_rtx, 8));
8143 add_reg_note (insn, REG_INC, stack_pointer_rtx);
8147 ;; local-alloc sometimes allocates scratch registers even when not required,
8148 ;; so we must be prepared to handle these.
8150 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
8152 [(set (match_operand:DF 0 "general_movdst_operand" "")
8153 (match_operand:DF 1 "general_movsrc_operand" ""))
8154 (use (reg:SI FPSCR_MODES_REG))
8155 (clobber (match_scratch:SI 2))]
8156 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
8158 && true_regnum (operands[0]) < 16
8159 && true_regnum (operands[1]) < 16"
8160 [(set (match_dup 0) (match_dup 1))]
8162 /* If this was a reg <-> mem operation with base + index reg addressing,
8163 we have to handle this in a special way. */
8164 rtx mem = operands[0];
8166 if (! memory_operand (mem, DFmode))
8171 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
8172 mem = SUBREG_REG (mem);
8175 rtx addr = XEXP (mem, 0);
8176 if (GET_CODE (addr) == PLUS
8177 && REG_P (XEXP (addr, 0))
8178 && REG_P (XEXP (addr, 1)))
8181 rtx reg0 = gen_rtx_REG (Pmode, 0);
8182 rtx regop = operands[store_p], word0 ,word1;
8184 if (GET_CODE (regop) == SUBREG)
8185 alter_subreg (®op, true);
8186 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
8190 mem = copy_rtx (mem);
8191 PUT_MODE (mem, SImode);
8192 word0 = gen_rtx_SUBREG (SImode, regop, 0);
8193 alter_subreg (&word0, true);
8194 word1 = gen_rtx_SUBREG (SImode, regop, 4);
8195 alter_subreg (&word1, true);
8196 if (store_p || ! refers_to_regno_p (REGNO (word0), addr))
8199 ? gen_movsi_ie (mem, word0)
8200 : gen_movsi_ie (word0, mem));
8201 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
8202 mem = copy_rtx (mem);
8204 ? gen_movsi_ie (mem, word1)
8205 : gen_movsi_ie (word1, mem));
8206 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
8210 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
8211 emit_insn (gen_movsi_ie (word1, mem));
8212 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
8213 mem = copy_rtx (mem);
8214 emit_insn (gen_movsi_ie (word0, mem));
8221 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
8223 [(set (match_operand:DF 0 "register_operand" "")
8224 (match_operand:DF 1 "memory_operand" ""))
8225 (use (reg:SI FPSCR_MODES_REG))
8226 (clobber (reg:SI R0_REG))]
8227 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
8228 [(parallel [(set (match_dup 0) (match_dup 1))
8229 (use (reg:SI FPSCR_MODES_REG))
8230 (clobber (scratch:SI))])]
8233 (define_expand "reload_indf__frn"
8234 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
8235 (match_operand:DF 1 "immediate_operand" "FQ"))
8236 (use (reg:SI FPSCR_MODES_REG))
8237 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8241 (define_expand "reload_outdf__RnFRm"
8242 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
8243 (match_operand:DF 1 "register_operand" "af,r"))
8244 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
8248 ;; Simplify no-op moves.
8250 [(set (match_operand:SF 0 "register_operand" "")
8251 (match_operand:SF 1 "register_operand" ""))
8252 (use (reg:SI FPSCR_MODES_REG))
8253 (clobber (match_scratch:SI 2))]
8254 "TARGET_SH2E && reload_completed
8255 && true_regnum (operands[0]) == true_regnum (operands[1])"
8256 [(set (match_dup 0) (match_dup 0))]
8259 ;; fmovd substitute post-reload splits
8261 [(set (match_operand:DF 0 "register_operand" "")
8262 (match_operand:DF 1 "register_operand" ""))
8263 (use (reg:SI FPSCR_MODES_REG))
8264 (clobber (match_scratch:SI 2))]
8265 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
8266 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
8267 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
8270 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
8271 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
8272 gen_rtx_REG (SFmode, src)));
8273 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
8274 gen_rtx_REG (SFmode, src + 1)));
8279 [(set (match_operand:DF 0 "register_operand" "")
8280 (mem:DF (match_operand:SI 1 "register_operand" "")))
8281 (use (reg:SI FPSCR_MODES_REG))
8282 (clobber (match_scratch:SI 2))]
8283 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
8284 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
8285 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
8288 int regno = true_regnum (operands[0]);
8290 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
8292 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
8293 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
8294 regno + SH_REG_MSW_OFFSET),
8296 add_reg_note (insn, REG_INC, operands[1]);
8297 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
8298 regno + SH_REG_LSW_OFFSET),
8299 change_address (mem, SFmode, NULL_RTX)));
8304 [(set (match_operand:DF 0 "register_operand" "")
8305 (match_operand:DF 1 "memory_operand" ""))
8306 (use (reg:SI FPSCR_MODES_REG))
8307 (clobber (match_scratch:SI 2))]
8308 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
8309 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
8312 int regno = true_regnum (operands[0]);
8314 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
8315 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
8316 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
8318 operands[1] = copy_rtx (mem2);
8319 addr = XEXP (mem2, 0);
8321 switch (GET_CODE (addr))
8324 /* This is complicated. If the register is an arithmetic register
8325 we can just fall through to the REG+DISP case below. Otherwise
8326 we have to use a combination of POST_INC and REG addressing... */
8327 if (! arith_reg_operand (operands[1], SFmode))
8329 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
8330 insn = emit_insn (gen_movsf_ie (reg0, mem2));
8331 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8333 emit_insn (gen_movsf_ie (reg1, operands[1]));
8335 /* If we have modified the stack pointer, the value that we have
8336 read with post-increment might be modified by an interrupt,
8337 so write it back. */
8338 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
8339 emit_insn (gen_push_e (reg0));
8341 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0),
8348 emit_insn (gen_movsf_ie (reg0, operands[1]));
8349 operands[1] = copy_rtx (operands[1]);
8350 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
8351 emit_insn (gen_movsf_ie (reg1, operands[1]));
8355 insn = emit_insn (gen_movsf_ie (reg0, operands[1]));
8356 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8358 insn = emit_insn (gen_movsf_ie (reg1, operands[1]));
8359 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8371 [(set (match_operand:DF 0 "memory_operand" "")
8372 (match_operand:DF 1 "register_operand" ""))
8373 (use (reg:SI FPSCR_MODES_REG))
8374 (clobber (match_scratch:SI 2))]
8375 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
8376 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
8379 int regno = true_regnum (operands[1]);
8381 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
8382 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
8384 operands[0] = copy_rtx (operands[0]);
8385 PUT_MODE (operands[0], SFmode);
8386 addr = XEXP (operands[0], 0);
8388 switch (GET_CODE (addr))
8391 /* This is complicated. If the register is an arithmetic register
8392 we can just fall through to the REG+DISP case below. Otherwise
8393 we have to use a combination of REG and PRE_DEC addressing... */
8394 if (! arith_reg_operand (operands[0], SFmode))
8396 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
8397 emit_insn (gen_movsf_ie (operands[0], reg1));
8399 operands[0] = copy_rtx (operands[0]);
8400 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
8402 insn = emit_insn (gen_movsf_ie (operands[0], reg0));
8403 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8409 /* Since REG+DISP addressing has already been decided upon by gcc
8410 we can rely upon it having chosen an arithmetic register as the
8411 register component of the address. Just emit the lower numbered
8412 register first, to the lower address, then the higher numbered
8413 register to the higher address. */
8414 emit_insn (gen_movsf_ie (operands[0], reg0));
8416 operands[0] = copy_rtx (operands[0]);
8417 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
8419 emit_insn (gen_movsf_ie (operands[0], reg1));
8423 /* This is easy. Output the word to go to the higher address
8424 first (ie the word in the higher numbered register) then the
8425 word to go to the lower address. */
8427 insn = emit_insn (gen_movsf_ie (operands[0], reg1));
8428 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8430 insn = emit_insn (gen_movsf_ie (operands[0], reg0));
8431 add_reg_note (insn, REG_INC, XEXP (addr, 0));
8443 ;; If the output is a register and the input is memory or a register, we have
8444 ;; to be careful and see which word needs to be loaded first.
8446 [(set (match_operand:DF 0 "general_movdst_operand" "")
8447 (match_operand:DF 1 "general_movsrc_operand" ""))]
8448 "TARGET_SH1 && reload_completed"
8449 [(set (match_dup 2) (match_dup 3))
8450 (set (match_dup 4) (match_dup 5))]
8454 if ((MEM_P (operands[0])
8455 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
8456 || (MEM_P (operands[1])
8457 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
8460 switch (GET_CODE (operands[0]))
8463 regno = REGNO (operands[0]);
8466 regno = subreg_regno (operands[0]);
8475 if (regno == -1 || ! refers_to_regno_p (regno, operands[1]))
8477 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
8478 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
8479 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
8480 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
8484 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
8485 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
8486 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
8487 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
8490 if (operands[2] == 0 || operands[3] == 0
8491 || operands[4] == 0 || operands[5] == 0)
8495 (define_expand "movdf"
8496 [(set (match_operand:DF 0 "general_movdst_operand" "")
8497 (match_operand:DF 1 "general_movsrc_operand" ""))]
8500 prepare_move_operands (operands, DFmode);
8503 if (TARGET_SHMEDIA_FPU)
8504 emit_insn (gen_movdf_media (operands[0], operands[1]));
8506 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
8509 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8511 emit_insn (gen_movdf_i4 (operands[0], operands[1]));
8516 ;;This is incompatible with the way gcc uses subregs.
8517 ;;(define_insn "movv2sf_i"
8518 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
8519 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
8520 ;; "TARGET_SHMEDIA_FPU
8521 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
8522 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
8526 ;; fst%M0.p %m0, %1"
8527 ;; [(set_attr "type" "*,fload_media,fstore_media")])
8528 (define_insn_and_split "movv2sf_i"
8529 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8530 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8531 "TARGET_SHMEDIA_FPU"
8533 "TARGET_SHMEDIA_FPU && reload_completed"
8534 [(set (match_dup 0) (match_dup 1))]
8536 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
8537 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
8540 (define_expand "movv2sf"
8541 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
8542 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
8543 "TARGET_SHMEDIA_FPU"
8545 prepare_move_operands (operands, V2SFmode);
8548 (define_expand "addv2sf3"
8549 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8550 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8551 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8552 "TARGET_SHMEDIA_FPU"
8554 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
8558 (define_expand "subv2sf3"
8559 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8560 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8561 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8562 "TARGET_SHMEDIA_FPU"
8564 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
8568 (define_expand "mulv2sf3"
8569 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8570 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8571 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8572 "TARGET_SHMEDIA_FPU"
8574 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
8578 (define_expand "divv2sf3"
8579 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8580 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8581 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8582 "TARGET_SHMEDIA_FPU"
8584 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
8588 (define_insn_and_split "*movv4sf_i"
8589 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8590 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8591 "TARGET_SHMEDIA_FPU"
8593 "&& reload_completed"
8596 for (int i = 0; i < 4/2; i++)
8600 if (MEM_P (operands[0]))
8601 x = adjust_address (operands[0], V2SFmode,
8602 i * GET_MODE_SIZE (V2SFmode));
8604 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
8606 if (MEM_P (operands[1]))
8607 y = adjust_address (operands[1], V2SFmode,
8608 i * GET_MODE_SIZE (V2SFmode));
8610 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8612 emit_insn (gen_movv2sf_i (x, y));
8617 [(set_attr "length" "8")])
8619 (define_expand "movv4sf"
8620 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8621 (match_operand:V4SF 1 "general_operand" ""))]
8622 "TARGET_SHMEDIA_FPU"
8624 prepare_move_operands (operands, V4SFmode);
8627 (define_insn_and_split "*movv16sf_i"
8628 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8629 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8630 "TARGET_SHMEDIA_FPU"
8632 "&& reload_completed"
8635 for (int i = 0; i < 16/2; i++)
8639 if (MEM_P (operands[0]))
8640 x = adjust_address (operands[0], V2SFmode,
8641 i * GET_MODE_SIZE (V2SFmode));
8644 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8645 alter_subreg (&x, true);
8648 if (MEM_P (operands[1]))
8649 y = adjust_address (operands[1], V2SFmode,
8650 i * GET_MODE_SIZE (V2SFmode));
8653 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8654 alter_subreg (&y, true);
8657 emit_insn (gen_movv2sf_i (x, y));
8662 [(set_attr "length" "32")])
8664 (define_expand "movv16sf"
8665 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8666 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8667 "TARGET_SHMEDIA_FPU"
8669 prepare_move_operands (operands, V16SFmode);
8672 (define_insn "movsf_media"
8673 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8674 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8676 && (register_operand (operands[0], SFmode)
8677 || sh_register_operand (operands[1], SFmode))"
8688 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8689 (set (attr "highpart")
8690 (cond [(match_test "sh_contains_memref_p (insn)")
8691 (const_string "user")]
8692 (const_string "ignore")))])
8694 (define_insn "movsf_media_nofpu"
8695 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8696 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8698 && (register_operand (operands[0], SFmode)
8699 || sh_register_operand (operands[1], SFmode))"
8705 [(set_attr "type" "arith_media,*,load_media,store_media")
8706 (set (attr "highpart")
8707 (cond [(match_test "sh_contains_memref_p (insn)")
8708 (const_string "user")]
8709 (const_string "ignore")))])
8712 [(set (match_operand:SF 0 "arith_reg_dest" "")
8713 (match_operand:SF 1 "immediate_operand" ""))]
8714 "TARGET_SHMEDIA && reload_completed
8715 && ! FP_REGISTER_P (true_regnum (operands[0]))"
8716 [(set (match_dup 3) (match_dup 2))]
8720 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), values);
8721 operands[2] = GEN_INT (values);
8723 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8726 (define_insn "movsf_i"
8727 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8728 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
8731 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8732 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8733 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8734 && (arith_reg_operand (operands[0], SFmode)
8735 || arith_reg_operand (operands[1], SFmode))"
8744 [(set_attr "type" "move,move,pcload,load,store,move,move")])
8746 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8747 ;; update_flow_info would not know where to put REG_EQUAL notes
8748 ;; when the destination changes mode.
8749 (define_insn "movsf_ie"
8750 [(set (match_operand:SF 0 "general_movdst_operand"
8751 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8752 (match_operand:SF 1 "general_movsrc_operand"
8753 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8754 (use (reg:SI FPSCR_MODES_REG))
8755 (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8757 && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode)
8758 || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode)
8759 || arith_reg_operand (operands[2], SImode))"
8779 ! move optimized away"
8780 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8781 store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8782 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8783 (set_attr_alternative "length"
8790 (match_test "TARGET_SH2A")
8791 (const_int 4) (const_int 2))
8793 (match_test "TARGET_SH2A")
8794 (const_int 4) (const_int 2))
8797 (match_test "TARGET_SH2A")
8798 (const_int 4) (const_int 2))
8800 (match_test "TARGET_SH2A")
8801 (const_int 4) (const_int 2))
8811 (set_attr_alternative "fp_mode"
8812 [(if_then_else (eq_attr "fmovd" "yes")
8813 (const_string "single") (const_string "none"))
8814 (const_string "none")
8815 (const_string "single")
8816 (const_string "single")
8817 (const_string "none")
8818 (if_then_else (eq_attr "fmovd" "yes")
8819 (const_string "single") (const_string "none"))
8820 (if_then_else (eq_attr "fmovd" "yes")
8821 (const_string "single") (const_string "none"))
8822 (const_string "none")
8823 (const_string "none")
8824 (const_string "none")
8825 (const_string "none")
8826 (const_string "none")
8827 (const_string "none")
8828 (const_string "none")
8829 (const_string "none")
8830 (const_string "none")
8831 (const_string "none")
8832 (const_string "none")
8833 (const_string "none")])])
8835 (define_insn_and_split "movsf_ie_ra"
8836 [(set (match_operand:SF 0 "general_movdst_operand"
8837 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8838 (match_operand:SF 1 "general_movsrc_operand"
8839 "f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y,>,y"))
8840 (use (reg:SI FPSCR_MODES_REG))
8841 (clobber (match_scratch:SF 2 "=r,r,X,X,&z,r,r,X,r,r,r,r,r,y,r,r,r,r,r"))
8844 && (arith_reg_operand (operands[0], SFmode)
8845 || fpul_operand (operands[0], SFmode)
8846 || arith_reg_operand (operands[1], SFmode)
8847 || fpul_operand (operands[1], SFmode))"
8867 ! move optimized away"
8869 && sh_movsf_ie_ra_split_p (operands[0], operands[1], operands[2])"
8872 if (! rtx_equal_p (operands[0], operands[1]))
8874 emit_insn (gen_movsf_ie (operands[2], operands[1]));
8875 emit_insn (gen_movsf_ie (operands[0], operands[2]));
8878 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8879 store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8880 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8881 (set_attr_alternative "length"
8888 (match_test "TARGET_SH2A")
8889 (const_int 4) (const_int 2))
8891 (match_test "TARGET_SH2A")
8892 (const_int 4) (const_int 2))
8895 (match_test "TARGET_SH2A")
8896 (const_int 4) (const_int 2))
8898 (match_test "TARGET_SH2A")
8899 (const_int 4) (const_int 2))
8909 (set_attr_alternative "fp_mode"
8910 [(if_then_else (eq_attr "fmovd" "yes")
8911 (const_string "single") (const_string "none"))
8912 (const_string "none")
8913 (const_string "single")
8914 (const_string "single")
8915 (const_string "none")
8916 (if_then_else (eq_attr "fmovd" "yes")
8917 (const_string "single") (const_string "none"))
8918 (if_then_else (eq_attr "fmovd" "yes")
8919 (const_string "single") (const_string "none"))
8920 (const_string "none")
8921 (const_string "none")
8922 (const_string "none")
8923 (const_string "none")
8924 (const_string "none")
8925 (const_string "none")
8926 (const_string "none")
8927 (const_string "none")
8928 (const_string "none")
8929 (const_string "none")
8930 (const_string "none")
8931 (const_string "none")])])
8934 [(set (match_operand:SF 0 "register_operand" "")
8935 (match_operand:SF 1 "register_operand" ""))
8936 (use (reg:SI FPSCR_MODES_REG))
8937 (clobber (reg:SI FPUL_REG))]
8939 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8940 (use (reg:SI FPSCR_MODES_REG))
8941 (clobber (scratch:SI))])
8942 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8943 (use (reg:SI FPSCR_MODES_REG))
8944 (clobber (scratch:SI))])]
8947 (define_expand "movsf"
8948 [(set (match_operand:SF 0 "general_movdst_operand" "")
8949 (match_operand:SF 1 "general_movsrc_operand" ""))]
8952 prepare_move_operands (operands, SFmode);
8955 if (TARGET_SHMEDIA_FPU)
8956 emit_insn (gen_movsf_media (operands[0], operands[1]));
8958 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8963 if (lra_in_progress)
8965 if (GET_CODE (operands[0]) == SCRATCH)
8967 emit_insn (gen_movsf_ie_ra (operands[0], operands[1]));
8971 emit_insn (gen_movsf_ie (operands[0], operands[1]));
8976 (define_insn "mov_nop"
8977 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8980 [(set_attr "length" "0")
8981 (set_attr "type" "nil")])
8983 (define_expand "reload_insf__frn"
8984 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8985 (match_operand:SF 1 "immediate_operand" "FQ"))
8986 (use (reg:SI FPSCR_MODES_REG))
8987 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8991 (define_expand "reload_insi__i_fpul"
8992 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8993 (match_operand:SI 1 "immediate_operand" "i"))
8994 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8998 (define_expand "ptabs"
8999 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
9002 if (!TARGET_PT_FIXED)
9004 rtx eq = operands[1];
9006 /* ??? For canonical RTL we really should remove any CONST from EQ
9007 before wrapping it in the AND, and finally wrap the EQ into a
9008 const if is constant. However, for reload we must expose the
9009 input register or symbolic constant, and we can't have
9010 different insn structures outside of the operands for different
9011 alternatives of the same pattern. */
9012 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
9015 = (gen_rtx_IF_THEN_ELSE
9018 gen_rtx_MEM (PDImode, operands[1]),
9019 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
9020 PDImode, operands[1])));
9024 ;; expanded by ptabs expander.
9025 (define_insn "*extendsipdi_media"
9026 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
9027 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
9031 (mem:PDI (match_dup 1))
9032 (sign_extend:PDI (match_dup 1))))]
9033 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
9037 [(set_attr "type" "ptabs_media,pt_media")
9038 (set_attr "length" "4,*")])
9040 (define_insn "*truncdipdi_media"
9041 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
9042 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
9046 (mem:PDI (match_dup 1))
9047 (truncate:PDI (match_dup 1))))]
9048 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
9052 [(set_attr "type" "ptabs_media,pt_media")
9053 (set_attr "length" "4,*")])
9055 (define_insn "*movsi_y"
9056 [(set (match_operand:SI 0 "register_operand" "=y,y")
9057 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
9058 (clobber (match_scratch:SI 2 "=&z,r"))]
9060 && (reload_in_progress || reload_completed)"
9062 [(set_attr "length" "4")
9063 (set_attr "type" "pcload,move")])
9066 [(set (match_operand:SI 0 "register_operand" "")
9067 (match_operand:SI 1 "immediate_operand" ""))
9068 (clobber (match_operand:SI 2 "register_operand" ""))]
9070 [(set (match_dup 2) (match_dup 1))
9071 (set (match_dup 0) (match_dup 2))]
9074 ;; ------------------------------------------------------------------------
9075 ;; Define the real conditional branch instructions.
9076 ;; ------------------------------------------------------------------------
9078 (define_expand "branch_true"
9079 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
9080 (label_ref (match_operand 0))
9084 (define_expand "branch_false"
9085 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
9086 (label_ref (match_operand 0))
9090 (define_insn_and_split "*cbranch_t"
9091 [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
9092 (label_ref (match_operand 0))
9096 return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
9101 /* Try to canonicalize the branch condition if it is not one of:
9102 (ne (reg:SI T_REG) (const_int 0))
9103 (eq (reg:SI T_REG) (const_int 0))
9105 Instead of splitting out a new insn, we modify the current insn's
9106 operands as needed. This preserves things such as REG_DEAD notes. */
9108 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9109 && REG_P (XEXP (operands[1], 0)) && REGNO (XEXP (operands[1], 0)) == T_REG
9110 && XEXP (operands[1], 1) == const0_rtx)
9113 int branch_cond = sh_eval_treg_value (operands[1]);
9114 rtx new_cond_rtx = NULL_RTX;
9116 if (branch_cond == 0)
9117 new_cond_rtx = gen_rtx_EQ (VOIDmode, get_t_reg_rtx (), const0_rtx);
9118 else if (branch_cond == 1)
9119 new_cond_rtx = gen_rtx_NE (VOIDmode, get_t_reg_rtx (), const0_rtx);
9121 if (new_cond_rtx != NULL_RTX)
9122 validate_change (curr_insn, &XEXP (XEXP (PATTERN (curr_insn), 1), 0),
9123 new_cond_rtx, false);
9126 [(set_attr "type" "cbranch")])
9128 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
9129 ;; which destination is too far away.
9130 ;; The const_int_operand is distinct for each branch target; it avoids
9131 ;; unwanted matches with redundant_insn.
9132 (define_insn "block_branch_redirect"
9133 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
9136 [(set_attr "length" "0")])
9138 ;; This one has the additional purpose to record a possible scratch register
9139 ;; for the following branch.
9140 ;; ??? Unfortunately, just setting the scratch register is not good enough,
9141 ;; because the insn then might be deemed dead and deleted. And we can't
9142 ;; make the use in the jump insn explicit because that would disable
9143 ;; delay slot scheduling from the target.
9144 (define_insn "indirect_jump_scratch"
9145 [(set (match_operand:SI 0 "register_operand" "=r")
9146 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
9147 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
9150 [(set_attr "length" "0")])
9152 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
9153 ;; being pulled into the delay slot of a condbranch that has been made to
9154 ;; jump around the unconditional jump because it was out of range.
9155 (define_insn "stuff_delay_slot"
9157 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
9158 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
9161 [(set_attr "length" "0")
9162 (set_attr "cond_delay_slot" "yes")])
9164 ;; Conditional branch insns
9166 (define_expand "cbranchint4_media"
9168 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
9169 [(match_operand 1 "" "")
9170 (match_operand 2 "" "")])
9171 (match_operand 3 "" "")
9175 machine_mode mode = GET_MODE (operands[1]);
9176 if (mode == VOIDmode)
9177 mode = GET_MODE (operands[2]);
9178 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
9180 operands[1] = force_reg (mode, operands[1]);
9181 if (CONSTANT_P (operands[2])
9182 && (! satisfies_constraint_I06 (operands[2])))
9183 operands[2] = force_reg (mode, operands[2]);
9187 if (operands[1] != const0_rtx)
9188 operands[1] = force_reg (mode, operands[1]);
9189 if (operands[2] != const0_rtx)
9190 operands[2] = force_reg (mode, operands[2]);
9192 switch (GET_CODE (operands[0]))
9198 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
9199 VOIDmode, operands[2], operands[1]);
9200 operands[1] = XEXP (operands[0], 0);
9201 operands[2] = XEXP (operands[0], 1);
9204 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
9205 VOIDmode, operands[1], operands[2]);
9208 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
9211 (define_expand "cbranchfp4_media"
9213 (if_then_else (match_operator 0 "sh_float_comparison_operator"
9214 [(match_operand 1 "" "")
9215 (match_operand 2 "" "")])
9216 (match_operand 3 "" "")
9220 rtx tmp = gen_reg_rtx (SImode);
9222 if (GET_CODE (operands[0]) == NE)
9223 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
9225 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
9226 operands[1], operands[2]);
9228 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
9230 if (GET_CODE (cmp) == GET_CODE (operands[0]))
9231 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
9233 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9235 operands[2] = const0_rtx;
9236 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
9239 (define_insn "*beq_media_i"
9241 (if_then_else (match_operator 3 "equality_comparison_operator"
9242 [(match_operand:DI 1 "arith_reg_operand" "r,r")
9243 (match_operand:DI 2 "arith_operand" "r,I06")])
9244 (match_operand 0 "target_operand" "b,b")
9249 b%o3i%' %1, %2, %0%>"
9250 [(set_attr "type" "cbranch_media")])
9252 (define_insn "*beq_media_i32"
9254 (if_then_else (match_operator 3 "equality_comparison_operator"
9255 [(match_operand:SI 1 "arith_reg_operand" "r,r")
9256 (match_operand:SI 2 "arith_operand" "r,I06")])
9257 (match_operand 0 "target_operand" "b,b")
9262 b%o3i%' %1, %2, %0%>"
9263 [(set_attr "type" "cbranch_media")])
9265 (define_insn "*bgt_media_i"
9267 (if_then_else (match_operator 3 "greater_comparison_operator"
9268 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
9269 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
9270 (match_operand 0 "target_operand" "b")
9273 "b%o3%' %N1, %N2, %0%>"
9274 [(set_attr "type" "cbranch_media")])
9276 (define_insn "*bgt_media_i32"
9278 (if_then_else (match_operator 3 "greater_comparison_operator"
9279 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
9280 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
9281 (match_operand 0 "target_operand" "b")
9284 "b%o3%' %N1, %N2, %0%>"
9285 [(set_attr "type" "cbranch_media")])
9287 ;; These are only needed to make invert_jump() happy - otherwise, jump
9288 ;; optimization will be silently disabled.
9289 (define_insn "*blt_media_i"
9291 (if_then_else (match_operator 3 "less_comparison_operator"
9292 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
9293 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
9294 (match_operand 0 "target_operand" "b")
9297 "b%o3%' %N2, %N1, %0%>"
9298 [(set_attr "type" "cbranch_media")])
9300 (define_insn "*blt_media_i32"
9302 (if_then_else (match_operator 3 "less_comparison_operator"
9303 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
9304 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
9305 (match_operand 0 "target_operand" "b")
9308 "b%o3%' %N2, %N1, %0%>"
9309 [(set_attr "type" "cbranch_media")])
9311 ;; combiner splitter for test-and-branch on single bit in register. This
9312 ;; is endian dependent because the non-paradoxical subreg looks different
9317 (match_operator 3 "equality_comparison_operator"
9320 (subreg:DI (match_operand:SI 1 "extend_reg_operand" "") 0)
9322 (match_operand 2 "const_int_operand" "")) 0)
9324 (match_operand 0 "target_operand" "")
9326 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
9327 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9328 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
9329 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
9331 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
9332 operands[6] = (GET_CODE (operands[3]) == EQ
9333 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
9334 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
9337 ; operand 0 is the loop count pseudo register
9338 ; operand 1 is the label to jump to at the top of the loop
9339 (define_expand "doloop_end"
9340 [(parallel [(set (pc)
9341 (if_then_else (ne:SI (match_operand:SI 0 "" "")
9343 (label_ref (match_operand 1 "" ""))
9346 (plus:SI (match_dup 0) (const_int -1)))
9347 (clobber (reg:SI T_REG))])]
9350 if (GET_MODE (operands[0]) != SImode)
9352 emit_jump_insn (gen_doloop_end_split (operands[0], operands[1], operands[0]));
9356 (define_insn_and_split "doloop_end_split"
9358 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
9360 (label_ref (match_operand 1 "" ""))
9362 (set (match_operand:SI 0 "arith_reg_dest" "=r")
9363 (plus:SI (match_dup 2) (const_int -1)))
9364 (clobber (reg:SI T_REG))]
9368 [(parallel [(set (reg:SI T_REG)
9369 (eq:SI (match_dup 2) (const_int 1)))
9370 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
9371 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
9372 (label_ref (match_dup 1))
9375 [(set_attr "type" "cbranch")])
9377 ;; ------------------------------------------------------------------------
9378 ;; Jump and linkage insns
9379 ;; ------------------------------------------------------------------------
9381 (define_insn "jump_compact"
9383 (label_ref (match_operand 0 "" "")))]
9384 "TARGET_SH1 && !CROSSING_JUMP_P (insn)"
9386 /* The length is 16 if the delay slot is unfilled. */
9387 if (get_attr_length(insn) > 4)
9388 return output_far_jump(insn, operands[0]);
9392 [(set_attr "type" "jump")
9393 (set_attr "needs_delay_slot" "yes")])
9395 (define_insn "*jump_compact_crossing"
9397 (label_ref (match_operand 0 "" "")))]
9399 && flag_reorder_blocks_and_partition
9400 && CROSSING_JUMP_P (insn)"
9402 /* The length is 16 if the delay slot is unfilled. */
9403 return output_far_jump(insn, operands[0]);
9405 [(set_attr "type" "jump")
9406 (set_attr "length" "16")])
9408 ;; ??? It would be much saner to explicitly use the scratch register
9409 ;; in the jump insn, and have indirect_jump_scratch only set it,
9410 ;; but fill_simple_delay_slots would refuse to do delay slot filling
9411 ;; from the target then, as it uses simplejump_p.
9412 ;;(define_insn "jump_compact_far"
9414 ;; (label_ref (match_operand 0 "" "")))
9415 ;; (use (match_operand 1 "register_operand" "r")]
9417 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
9418 ;; [(set_attr "type" "jump")
9419 ;; (set_attr "needs_delay_slot" "yes")])
9421 (define_insn "jump_media"
9423 (match_operand 0 "target_operand" "b"))]
9426 [(set_attr "type" "jump_media")])
9428 (define_expand "jump"
9430 (label_ref (match_operand 0 "" "")))]
9434 emit_jump_insn (gen_jump_compact (operands[0]));
9435 else if (TARGET_SHMEDIA)
9437 if (reload_in_progress || reload_completed)
9439 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, operands[0])));
9444 (define_insn "force_mode_for_call"
9445 [(use (reg:SI FPSCR_MODES_REG))]
9448 [(set_attr "length" "0")
9449 (set (attr "fp_mode")
9450 (if_then_else (eq_attr "fpu_single" "yes")
9451 (const_string "single") (const_string "double")))])
9453 (define_insn "calli"
9454 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9455 (match_operand 1 "" ""))
9456 (use (reg:SI FPSCR_MODES_REG))
9457 (clobber (reg:SI PR_REG))]
9460 if (TARGET_SH2A && (dbr_sequence_length () == 0))
9465 [(set_attr "type" "call")
9466 (set (attr "fp_mode")
9467 (if_then_else (eq_attr "fpu_single" "yes")
9468 (const_string "single") (const_string "double")))
9469 (set_attr "needs_delay_slot" "yes")
9470 (set_attr "fp_set" "unknown")])
9472 ;; This is TBR relative jump instruction for SH2A architecture.
9473 ;; Its use is enabled by assigning an attribute "function_vector"
9474 ;; and the vector number to a function during its declaration.
9475 (define_insn "calli_tbr_rel"
9476 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
9477 (match_operand 1 "" ""))
9478 (use (reg:SI FPSCR_MODES_REG))
9479 (clobber (reg:SI PR_REG))]
9480 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
9482 unsigned HOST_WIDE_INT vect_num;
9483 vect_num = sh2a_get_function_vector_number (operands[0]);
9484 operands[2] = GEN_INT (vect_num * 4);
9486 return "jsr/n @@(%O2,tbr)";
9488 [(set_attr "type" "call")
9489 (set (attr "fp_mode")
9490 (if_then_else (eq_attr "fpu_single" "yes")
9491 (const_string "single") (const_string "double")))
9492 (set_attr "needs_delay_slot" "no")
9493 (set_attr "fp_set" "unknown")])
9495 ;; This is a pc-rel call, using bsrf, for use with PIC.
9496 (define_insn "calli_pcrel"
9497 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9498 (match_operand 1 "" ""))
9499 (use (reg:SI FPSCR_MODES_REG))
9500 (use (reg:SI PIC_REG))
9501 (use (match_operand 2 "" ""))
9502 (clobber (reg:SI PR_REG))]
9505 return "bsrf %0" "\n"
9508 [(set_attr "type" "call")
9509 (set (attr "fp_mode")
9510 (if_then_else (eq_attr "fpu_single" "yes")
9511 (const_string "single") (const_string "double")))
9512 (set_attr "needs_delay_slot" "yes")
9513 (set_attr "fp_set" "unknown")])
9515 (define_insn_and_split "call_pcrel"
9516 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9517 (match_operand 1 "" ""))
9518 (use (reg:SI FPSCR_MODES_REG))
9519 (use (reg:SI PIC_REG))
9520 (clobber (reg:SI PR_REG))
9521 (clobber (match_scratch:SI 2 "=&r"))]
9527 rtx lab = PATTERN (gen_call_site ());
9529 sh_expand_sym_label2reg (operands[2], operands[0], lab, false);
9530 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
9533 [(set_attr "type" "call")
9534 (set (attr "fp_mode")
9535 (if_then_else (eq_attr "fpu_single" "yes")
9536 (const_string "single") (const_string "double")))
9537 (set_attr "needs_delay_slot" "yes")
9538 (set_attr "fp_set" "unknown")])
9540 (define_insn "call_compact"
9541 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9542 (match_operand 1 "" ""))
9543 (match_operand 2 "immediate_operand" "n")
9544 (use (reg:SI R0_REG))
9545 (use (reg:SI R1_REG))
9546 (use (reg:SI FPSCR_MODES_REG))
9547 (clobber (reg:SI PR_REG))]
9548 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9550 [(set_attr "type" "call")
9551 (set (attr "fp_mode")
9552 (if_then_else (eq_attr "fpu_single" "yes")
9553 (const_string "single") (const_string "double")))
9554 (set_attr "needs_delay_slot" "yes")])
9556 (define_insn "call_compact_rettramp"
9557 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9558 (match_operand 1 "" ""))
9559 (match_operand 2 "immediate_operand" "n")
9560 (use (reg:SI R0_REG))
9561 (use (reg:SI R1_REG))
9562 (use (reg:SI FPSCR_MODES_REG))
9563 (clobber (reg:SI R10_REG))
9564 (clobber (reg:SI PR_REG))]
9565 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9567 [(set_attr "type" "call")
9568 (set (attr "fp_mode")
9569 (if_then_else (eq_attr "fpu_single" "yes")
9570 (const_string "single") (const_string "double")))
9571 (set_attr "needs_delay_slot" "yes")])
9573 (define_insn "call_media"
9574 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
9575 (match_operand 1 "" ""))
9576 (clobber (reg:DI PR_MEDIA_REG))]
9579 [(set_attr "type" "jump_media")])
9581 (define_insn "call_valuei"
9582 [(set (match_operand 0 "" "=rf")
9583 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9584 (match_operand 2 "" "")))
9585 (use (reg:SI FPSCR_MODES_REG))
9586 (clobber (reg:SI PR_REG))]
9589 if (TARGET_SH2A && (dbr_sequence_length () == 0))
9594 [(set_attr "type" "call")
9595 (set (attr "fp_mode")
9596 (if_then_else (eq_attr "fpu_single" "yes")
9597 (const_string "single") (const_string "double")))
9598 (set_attr "needs_delay_slot" "yes")
9599 (set_attr "fp_set" "unknown")])
9601 ;; This is TBR relative jump instruction for SH2A architecture.
9602 ;; Its use is enabled by assigning an attribute "function_vector"
9603 ;; and the vector number to a function during its declaration.
9604 (define_insn "call_valuei_tbr_rel"
9605 [(set (match_operand 0 "" "=rf")
9606 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9607 (match_operand 2 "" "")))
9608 (use (reg:SI FPSCR_MODES_REG))
9609 (clobber (reg:SI PR_REG))]
9610 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
9612 unsigned HOST_WIDE_INT vect_num;
9613 vect_num = sh2a_get_function_vector_number (operands[1]);
9614 operands[3] = GEN_INT (vect_num * 4);
9616 return "jsr/n @@(%O3,tbr)";
9618 [(set_attr "type" "call")
9619 (set (attr "fp_mode")
9620 (if_then_else (eq_attr "fpu_single" "yes")
9621 (const_string "single") (const_string "double")))
9622 (set_attr "needs_delay_slot" "no")
9623 (set_attr "fp_set" "unknown")])
9625 (define_insn "call_valuei_pcrel"
9626 [(set (match_operand 0 "" "=rf")
9627 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9628 (match_operand 2 "" "")))
9629 (use (reg:SI FPSCR_MODES_REG))
9630 (use (reg:SI PIC_REG))
9631 (use (match_operand 3 "" ""))
9632 (clobber (reg:SI PR_REG))]
9635 return "bsrf %1" "\n"
9638 [(set_attr "type" "call")
9639 (set (attr "fp_mode")
9640 (if_then_else (eq_attr "fpu_single" "yes")
9641 (const_string "single") (const_string "double")))
9642 (set_attr "needs_delay_slot" "yes")
9643 (set_attr "fp_set" "unknown")])
9645 (define_insn_and_split "call_value_pcrel"
9646 [(set (match_operand 0 "" "=rf")
9647 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9648 (match_operand 2 "" "")))
9649 (use (reg:SI FPSCR_MODES_REG))
9650 (use (reg:SI PIC_REG))
9651 (clobber (reg:SI PR_REG))
9652 (clobber (match_scratch:SI 3 "=&r"))]
9658 rtx lab = PATTERN (gen_call_site ());
9660 sh_expand_sym_label2reg (operands[3], operands[1], lab, false);
9661 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
9662 operands[2], copy_rtx (lab)));
9665 [(set_attr "type" "call")
9666 (set (attr "fp_mode")
9667 (if_then_else (eq_attr "fpu_single" "yes")
9668 (const_string "single") (const_string "double")))
9669 (set_attr "needs_delay_slot" "yes")
9670 (set_attr "fp_set" "unknown")])
9672 (define_insn "call_value_compact"
9673 [(set (match_operand 0 "" "=rf")
9674 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9675 (match_operand 2 "" "")))
9676 (match_operand 3 "immediate_operand" "n")
9677 (use (reg:SI R0_REG))
9678 (use (reg:SI R1_REG))
9679 (use (reg:SI FPSCR_MODES_REG))
9680 (clobber (reg:SI PR_REG))]
9681 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9683 [(set_attr "type" "call")
9684 (set (attr "fp_mode")
9685 (if_then_else (eq_attr "fpu_single" "yes")
9686 (const_string "single") (const_string "double")))
9687 (set_attr "needs_delay_slot" "yes")])
9689 (define_insn "call_value_compact_rettramp"
9690 [(set (match_operand 0 "" "=rf")
9691 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9692 (match_operand 2 "" "")))
9693 (match_operand 3 "immediate_operand" "n")
9694 (use (reg:SI R0_REG))
9695 (use (reg:SI R1_REG))
9696 (use (reg:SI FPSCR_MODES_REG))
9697 (clobber (reg:SI R10_REG))
9698 (clobber (reg:SI PR_REG))]
9699 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9701 [(set_attr "type" "call")
9702 (set (attr "fp_mode")
9703 (if_then_else (eq_attr "fpu_single" "yes")
9704 (const_string "single") (const_string "double")))
9705 (set_attr "needs_delay_slot" "yes")])
9707 (define_insn "call_value_media"
9708 [(set (match_operand 0 "" "=rf")
9709 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9710 (match_operand 2 "" "")))
9711 (clobber (reg:DI PR_MEDIA_REG))]
9714 [(set_attr "type" "jump_media")])
9716 (define_expand "call"
9717 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9718 (match_operand 1 "" ""))
9719 (match_operand 2 "" "")
9720 (use (reg:SI FPSCR_MODES_REG))
9721 (clobber (reg:SI PR_REG))])]
9726 operands[0] = shmedia_prepare_call_address (operands[0], 0);
9727 emit_call_insn (gen_call_media (operands[0], operands[1]));
9730 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9732 rtx cookie_rtx = operands[2];
9733 long cookie = INTVAL (cookie_rtx);
9734 rtx func = XEXP (operands[0], 0);
9739 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9741 rtx reg = gen_reg_rtx (Pmode);
9743 emit_insn (gen_symGOTPLT2reg (reg, func));
9747 func = legitimize_pic_address (func, Pmode, 0);
9750 r0 = gen_rtx_REG (SImode, R0_REG);
9751 r1 = gen_rtx_REG (SImode, R1_REG);
9753 /* Since such a call function may use all call-clobbered
9754 registers, we force a mode switch earlier, so that we don't
9755 run out of registers when adjusting fpscr for the call. */
9756 emit_insn (gen_force_mode_for_call ());
9759 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9760 operands[0] = force_reg (SImode, operands[0]);
9762 emit_move_insn (r0, func);
9763 emit_move_insn (r1, cookie_rtx);
9765 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9766 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9769 emit_call_insn (gen_call_compact (operands[0], operands[1],
9774 else if (TARGET_SHCOMPACT && flag_pic
9775 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9776 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9778 rtx reg = gen_reg_rtx (Pmode);
9780 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9781 XEXP (operands[0], 0) = reg;
9783 if (!flag_pic && TARGET_SH2A
9784 && MEM_P (operands[0])
9785 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9787 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9789 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9794 if (flag_pic && TARGET_SH2
9795 && MEM_P (operands[0])
9796 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9798 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9803 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9804 operands[1] = operands[2];
9807 emit_call_insn (gen_calli (operands[0], operands[1]));
9811 (define_insn "call_pop_compact"
9812 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9813 (match_operand 1 "" ""))
9814 (match_operand 2 "immediate_operand" "n")
9815 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9816 (match_operand 3 "immediate_operand" "n")))
9817 (use (reg:SI R0_REG))
9818 (use (reg:SI R1_REG))
9819 (use (reg:SI FPSCR_MODES_REG))
9820 (clobber (reg:SI PR_REG))]
9821 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9823 [(set_attr "type" "call")
9824 (set (attr "fp_mode")
9825 (if_then_else (eq_attr "fpu_single" "yes")
9826 (const_string "single") (const_string "double")))
9827 (set_attr "needs_delay_slot" "yes")])
9829 (define_insn "call_pop_compact_rettramp"
9830 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9831 (match_operand 1 "" ""))
9832 (match_operand 2 "immediate_operand" "n")
9833 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9834 (match_operand 3 "immediate_operand" "n")))
9835 (use (reg:SI R0_REG))
9836 (use (reg:SI R1_REG))
9837 (use (reg:SI FPSCR_MODES_REG))
9838 (clobber (reg:SI R10_REG))
9839 (clobber (reg:SI PR_REG))]
9840 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9842 [(set_attr "type" "call")
9843 (set (attr "fp_mode")
9844 (if_then_else (eq_attr "fpu_single" "yes")
9845 (const_string "single") (const_string "double")))
9846 (set_attr "needs_delay_slot" "yes")])
9848 (define_expand "call_pop"
9849 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9850 (match_operand 1 "" ""))
9851 (match_operand 2 "" "")
9852 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9853 (match_operand 3 "" "")))])]
9861 gcc_assert (operands[2] && INTVAL (operands[2]));
9862 cookie_rtx = operands[2];
9863 cookie = INTVAL (cookie_rtx);
9864 func = XEXP (operands[0], 0);
9868 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9870 rtx reg = gen_reg_rtx (Pmode);
9871 emit_insn (gen_symGOTPLT2reg (reg, func));
9875 func = legitimize_pic_address (func, Pmode, 0);
9878 r0 = gen_rtx_REG (SImode, R0_REG);
9879 r1 = gen_rtx_REG (SImode, R1_REG);
9881 /* Since such a call function may use all call-clobbered
9882 registers, we force a mode switch earlier, so that we don't
9883 run out of registers when adjusting fpscr for the call. */
9884 emit_insn (gen_force_mode_for_call ());
9886 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9888 operands[0] = force_reg (SImode, operands[0]);
9890 emit_move_insn (r0, func);
9891 emit_move_insn (r1, cookie_rtx);
9893 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9894 emit_call_insn (gen_call_pop_compact_rettramp
9895 (operands[0], operands[1], operands[2], operands[3]));
9897 emit_call_insn (gen_call_pop_compact
9898 (operands[0], operands[1], operands[2], operands[3]));
9903 (define_expand "call_value"
9904 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9905 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9906 (match_operand 2 "" "")))
9907 (match_operand 3 "" "")
9908 (use (reg:SI FPSCR_MODES_REG))
9909 (clobber (reg:SI PR_REG))])]
9914 operands[1] = shmedia_prepare_call_address (operands[1], 0);
9915 emit_call_insn (gen_call_value_media (operands[0], operands[1],
9919 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9921 rtx cookie_rtx = operands[3];
9922 long cookie = INTVAL (cookie_rtx);
9923 rtx func = XEXP (operands[1], 0);
9928 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9930 rtx reg = gen_reg_rtx (Pmode);
9932 emit_insn (gen_symGOTPLT2reg (reg, func));
9936 func = legitimize_pic_address (func, Pmode, 0);
9939 r0 = gen_rtx_REG (SImode, R0_REG);
9940 r1 = gen_rtx_REG (SImode, R1_REG);
9942 /* Since such a call function may use all call-clobbered
9943 registers, we force a mode switch earlier, so that we don't
9944 run out of registers when adjusting fpscr for the call. */
9945 emit_insn (gen_force_mode_for_call ());
9948 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9949 operands[1] = force_reg (SImode, operands[1]);
9951 emit_move_insn (r0, func);
9952 emit_move_insn (r1, cookie_rtx);
9954 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9955 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9960 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9961 operands[2], operands[3]));
9965 else if (TARGET_SHCOMPACT && flag_pic
9966 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9967 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9969 rtx reg = gen_reg_rtx (Pmode);
9971 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9972 XEXP (operands[1], 0) = reg;
9974 if (!flag_pic && TARGET_SH2A
9975 && MEM_P (operands[1])
9976 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9978 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9980 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9981 XEXP (operands[1], 0), operands[2]));
9985 if (flag_pic && TARGET_SH2
9986 && MEM_P (operands[1])
9987 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9989 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9994 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9996 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
10000 (define_insn "sibcalli"
10001 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
10002 (match_operand 1 "" ""))
10003 (use (reg:SI FPSCR_MODES_REG))
10007 [(set_attr "needs_delay_slot" "yes")
10008 (set (attr "fp_mode")
10009 (if_then_else (eq_attr "fpu_single" "yes")
10010 (const_string "single") (const_string "double")))
10011 (set_attr "type" "jump_ind")])
10013 (define_insn "sibcalli_pcrel"
10014 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
10015 (match_operand 1 "" ""))
10016 (use (match_operand 2 "" ""))
10017 (use (reg:SI FPSCR_MODES_REG))
10021 return "braf %0" "\n"
10024 [(set_attr "needs_delay_slot" "yes")
10025 (set (attr "fp_mode")
10026 (if_then_else (eq_attr "fpu_single" "yes")
10027 (const_string "single") (const_string "double")))
10028 (set_attr "type" "jump_ind")])
10030 ;; This uses an unspec to describe that the symbol_ref is very close.
10031 (define_insn "sibcalli_thunk"
10032 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
10034 (match_operand 1 "" ""))
10035 (use (reg:SI FPSCR_MODES_REG))
10039 [(set_attr "needs_delay_slot" "yes")
10040 (set (attr "fp_mode")
10041 (if_then_else (eq_attr "fpu_single" "yes")
10042 (const_string "single") (const_string "double")))
10043 (set_attr "type" "jump")
10044 (set_attr "length" "2")])
10046 (define_insn_and_split "sibcall_pcrel"
10047 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
10048 (match_operand 1 "" ""))
10049 (use (reg:SI FPSCR_MODES_REG))
10050 (clobber (match_scratch:SI 2 "=&k"))
10057 rtx lab = PATTERN (gen_call_site ());
10060 sh_expand_sym_label2reg (operands[2], operands[0], lab, true);
10061 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
10063 SIBLING_CALL_P (call_insn) = 1;
10066 [(set_attr "needs_delay_slot" "yes")
10067 (set (attr "fp_mode")
10068 (if_then_else (eq_attr "fpu_single" "yes")
10069 (const_string "single") (const_string "double")))
10070 (set_attr "type" "jump_ind")])
10072 (define_insn "sibcall_compact"
10073 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
10074 (match_operand 1 "" ""))
10076 (use (match_operand:SI 2 "register_operand" "z,x"))
10077 (use (reg:SI R1_REG))
10078 (use (reg:SI FPSCR_MODES_REG))
10079 ;; We want to make sure the `x' above will only match MACH_REG
10080 ;; because sibcall_epilogue may clobber MACL_REG.
10081 (clobber (reg:SI MACL_REG))]
10084 static const char* alt[] =
10091 return alt[which_alternative];
10093 [(set_attr "needs_delay_slot" "yes,no")
10094 (set_attr "length" "2,4")
10095 (set (attr "fp_mode") (const_string "single"))
10096 (set_attr "type" "jump_ind")])
10098 (define_insn "sibcall_media"
10099 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
10100 (match_operand 1 "" ""))
10101 (use (reg:SI PR_MEDIA_REG))
10105 [(set_attr "type" "jump_media")])
10107 (define_expand "sibcall"
10109 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
10110 (match_operand 1 "" ""))
10111 (match_operand 2 "" "")
10112 (use (reg:SI FPSCR_MODES_REG))
10116 if (TARGET_SHMEDIA)
10118 operands[0] = shmedia_prepare_call_address (operands[0], 1);
10119 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
10122 else if (TARGET_SHCOMPACT && operands[2]
10123 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
10125 rtx cookie_rtx = operands[2];
10126 long cookie = INTVAL (cookie_rtx);
10127 rtx func = XEXP (operands[0], 0);
10132 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
10134 rtx reg = gen_reg_rtx (Pmode);
10136 emit_insn (gen_symGOT2reg (reg, func));
10140 func = legitimize_pic_address (func, Pmode, 0);
10143 /* FIXME: if we could tell whether all argument registers are
10144 already taken, we could decide whether to force the use of
10145 MACH_REG or to stick to R0_REG. Unfortunately, there's no
10146 simple way to tell. We could use the CALL_COOKIE, but we
10147 can't currently tell a register used for regular argument
10148 passing from one that is unused. If we leave it up to reload
10149 to decide which register to use, it seems to always choose
10150 R0_REG, which leaves no available registers in SIBCALL_REGS
10151 to hold the address of the trampoline. */
10152 mach = gen_rtx_REG (SImode, MACH_REG);
10153 r1 = gen_rtx_REG (SImode, R1_REG);
10155 /* Since such a call function may use all call-clobbered
10156 registers, we force a mode switch earlier, so that we don't
10157 run out of registers when adjusting fpscr for the call. */
10158 emit_insn (gen_force_mode_for_call ());
10161 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
10162 operands[0] = force_reg (SImode, operands[0]);
10164 /* We don't need a return trampoline, since the callee will
10165 return directly to the upper caller. */
10166 if (cookie & CALL_COOKIE_RET_TRAMP (1))
10168 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
10169 cookie_rtx = GEN_INT (cookie);
10172 emit_move_insn (mach, func);
10173 emit_move_insn (r1, cookie_rtx);
10175 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
10178 else if (TARGET_SHCOMPACT && flag_pic
10179 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
10180 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
10182 rtx reg = gen_reg_rtx (Pmode);
10184 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
10185 XEXP (operands[0], 0) = reg;
10187 if (flag_pic && TARGET_SH2
10188 && MEM_P (operands[0])
10189 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
10190 /* The PLT needs the PIC register, but the epilogue would have
10191 to restore it, so we can only use PC-relative PIC calls for
10192 static functions. */
10193 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
10195 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
10199 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
10201 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
10205 (define_insn "sibcall_valuei"
10206 [(set (match_operand 0 "" "=rf")
10207 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
10208 (match_operand 2 "" "")))
10209 (use (reg:SI FPSCR_MODES_REG))
10213 [(set_attr "needs_delay_slot" "yes")
10214 (set (attr "fp_mode")
10215 (if_then_else (eq_attr "fpu_single" "yes")
10216 (const_string "single") (const_string "double")))
10217 (set_attr "type" "jump_ind")])
10219 (define_insn "sibcall_valuei_pcrel"
10220 [(set (match_operand 0 "" "=rf")
10221 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
10222 (match_operand 2 "" "")))
10223 (use (match_operand 3 "" ""))
10224 (use (reg:SI FPSCR_MODES_REG))
10228 return "braf %1" "\n"
10231 [(set_attr "needs_delay_slot" "yes")
10232 (set (attr "fp_mode")
10233 (if_then_else (eq_attr "fpu_single" "yes")
10234 (const_string "single") (const_string "double")))
10235 (set_attr "type" "jump_ind")])
10237 (define_insn_and_split "sibcall_value_pcrel"
10238 [(set (match_operand 0 "" "=rf")
10239 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
10240 (match_operand 2 "" "")))
10241 (use (reg:SI FPSCR_MODES_REG))
10242 (clobber (match_scratch:SI 3 "=&k"))
10249 rtx lab = PATTERN (gen_call_site ());
10252 sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
10253 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
10257 SIBLING_CALL_P (call_insn) = 1;
10260 [(set_attr "needs_delay_slot" "yes")
10261 (set (attr "fp_mode")
10262 (if_then_else (eq_attr "fpu_single" "yes")
10263 (const_string "single") (const_string "double")))
10264 (set_attr "type" "jump_ind")])
10266 (define_insn "sibcall_value_compact"
10267 [(set (match_operand 0 "" "=rf,rf")
10268 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
10269 (match_operand 2 "" "")))
10271 (use (match_operand:SI 3 "register_operand" "z,x"))
10272 (use (reg:SI R1_REG))
10273 (use (reg:SI FPSCR_MODES_REG))
10274 ;; We want to make sure the `x' above will only match MACH_REG
10275 ;; because sibcall_epilogue may clobber MACL_REG.
10276 (clobber (reg:SI MACL_REG))]
10279 static const char* alt[] =
10286 return alt[which_alternative];
10288 [(set_attr "needs_delay_slot" "yes,no")
10289 (set_attr "length" "2,4")
10290 (set (attr "fp_mode") (const_string "single"))
10291 (set_attr "type" "jump_ind")])
10293 (define_insn "sibcall_value_media"
10294 [(set (match_operand 0 "" "=rf")
10295 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
10296 (match_operand 2 "" "")))
10297 (use (reg:SI PR_MEDIA_REG))
10301 [(set_attr "type" "jump_media")])
10303 (define_expand "sibcall_value"
10305 [(set (match_operand 0 "arith_reg_operand" "")
10306 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
10307 (match_operand 2 "" "")))
10308 (match_operand 3 "" "")
10309 (use (reg:SI FPSCR_MODES_REG))
10313 if (TARGET_SHMEDIA)
10315 operands[1] = shmedia_prepare_call_address (operands[1], 1);
10316 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
10320 else if (TARGET_SHCOMPACT && operands[3]
10321 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
10323 rtx cookie_rtx = operands[3];
10324 long cookie = INTVAL (cookie_rtx);
10325 rtx func = XEXP (operands[1], 0);
10330 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
10332 rtx reg = gen_reg_rtx (Pmode);
10334 emit_insn (gen_symGOT2reg (reg, func));
10338 func = legitimize_pic_address (func, Pmode, 0);
10341 /* FIXME: if we could tell whether all argument registers are
10342 already taken, we could decide whether to force the use of
10343 MACH_REG or to stick to R0_REG. Unfortunately, there's no
10344 simple way to tell. We could use the CALL_COOKIE, but we
10345 can't currently tell a register used for regular argument
10346 passing from one that is unused. If we leave it up to reload
10347 to decide which register to use, it seems to always choose
10348 R0_REG, which leaves no available registers in SIBCALL_REGS
10349 to hold the address of the trampoline. */
10350 mach = gen_rtx_REG (SImode, MACH_REG);
10351 r1 = gen_rtx_REG (SImode, R1_REG);
10353 /* Since such a call function may use all call-clobbered
10354 registers, we force a mode switch earlier, so that we don't
10355 run out of registers when adjusting fpscr for the call. */
10356 emit_insn (gen_force_mode_for_call ());
10359 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
10360 operands[1] = force_reg (SImode, operands[1]);
10362 /* We don't need a return trampoline, since the callee will
10363 return directly to the upper caller. */
10364 if (cookie & CALL_COOKIE_RET_TRAMP (1))
10366 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
10367 cookie_rtx = GEN_INT (cookie);
10370 emit_move_insn (mach, func);
10371 emit_move_insn (r1, cookie_rtx);
10373 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
10374 operands[2], mach));
10377 else if (TARGET_SHCOMPACT && flag_pic
10378 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10379 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
10381 rtx reg = gen_reg_rtx (Pmode);
10383 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
10384 XEXP (operands[1], 0) = reg;
10386 if (flag_pic && TARGET_SH2
10387 && MEM_P (operands[1])
10388 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10389 /* The PLT needs the PIC register, but the epilogue would have
10390 to restore it, so we can only use PC-relative PIC calls for
10391 static functions. */
10392 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
10394 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
10395 XEXP (operands[1], 0),
10400 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
10402 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
10406 (define_insn "call_value_pop_compact"
10407 [(set (match_operand 0 "" "=rf")
10408 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
10409 (match_operand 2 "" "")))
10410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
10411 (match_operand 4 "immediate_operand" "n")))
10412 (match_operand 3 "immediate_operand" "n")
10413 (use (reg:SI R0_REG))
10414 (use (reg:SI R1_REG))
10415 (use (reg:SI FPSCR_MODES_REG))
10416 (clobber (reg:SI PR_REG))]
10417 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
10419 [(set_attr "type" "call")
10420 (set (attr "fp_mode")
10421 (if_then_else (eq_attr "fpu_single" "yes")
10422 (const_string "single") (const_string "double")))
10423 (set_attr "needs_delay_slot" "yes")])
10425 (define_insn "call_value_pop_compact_rettramp"
10426 [(set (match_operand 0 "" "=rf")
10427 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
10428 (match_operand 2 "" "")))
10429 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
10430 (match_operand 4 "immediate_operand" "n")))
10431 (match_operand 3 "immediate_operand" "n")
10432 (use (reg:SI R0_REG))
10433 (use (reg:SI R1_REG))
10434 (use (reg:SI FPSCR_MODES_REG))
10435 (clobber (reg:SI R10_REG))
10436 (clobber (reg:SI PR_REG))]
10437 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
10439 [(set_attr "type" "call")
10440 (set (attr "fp_mode")
10441 (if_then_else (eq_attr "fpu_single" "yes")
10442 (const_string "single") (const_string "double")))
10443 (set_attr "needs_delay_slot" "yes")])
10445 (define_expand "call_value_pop"
10446 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
10447 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
10448 (match_operand 2 "" "")))
10449 (match_operand 3 "" "")
10450 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
10451 (match_operand 4 "" "")))])]
10459 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
10460 cookie_rtx = operands[3];
10461 cookie = INTVAL (cookie_rtx);
10462 func = XEXP (operands[1], 0);
10466 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
10468 rtx reg = gen_reg_rtx (Pmode);
10470 emit_insn (gen_symGOTPLT2reg (reg, func));
10474 func = legitimize_pic_address (func, Pmode, 0);
10477 r0 = gen_rtx_REG (SImode, R0_REG);
10478 r1 = gen_rtx_REG (SImode, R1_REG);
10480 /* Since such a call function may use all call-clobbered
10481 registers, we force a mode switch earlier, so that we don't
10482 run out of registers when adjusting fpscr for the call. */
10483 emit_insn (gen_force_mode_for_call ());
10485 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
10487 operands[1] = force_reg (SImode, operands[1]);
10489 emit_move_insn (r0, func);
10490 emit_move_insn (r1, cookie_rtx);
10492 if (cookie & CALL_COOKIE_RET_TRAMP (1))
10493 emit_call_insn (gen_call_value_pop_compact_rettramp
10494 (operands[0], operands[1], operands[2],
10495 operands[3], operands[4]));
10497 emit_call_insn (gen_call_value_pop_compact
10498 (operands[0], operands[1], operands[2],
10499 operands[3], operands[4]));
10504 (define_expand "sibcall_epilogue"
10508 sh_expand_epilogue (true);
10509 if (TARGET_SHCOMPACT)
10514 /* If epilogue clobbers r0, preserve it in macl. */
10515 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10516 if ((set = single_set (insn))
10517 && REG_P (SET_DEST (set))
10518 && REGNO (SET_DEST (set)) == R0_REG)
10520 rtx r0 = gen_rtx_REG (SImode, R0_REG);
10521 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
10523 /* We can't tell at this point whether the sibcall is a
10524 sibcall_compact and, if it is, whether it uses r0 or
10525 mach as operand 2, so let the instructions that
10526 preserve r0 be optimized away if r0 turns out to be
10528 emit_insn_before (gen_rtx_SET (tmp, r0), insn);
10529 emit_move_insn (r0, tmp);
10536 (define_insn "indirect_jump_compact"
10538 (match_operand:SI 0 "arith_reg_operand" "r"))]
10541 [(set_attr "needs_delay_slot" "yes")
10542 (set_attr "type" "jump_ind")])
10544 (define_expand "indirect_jump"
10546 (match_operand 0 "register_operand" ""))]
10549 if (GET_MODE (operands[0]) != Pmode)
10550 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
10553 ;; The use of operand 1 / 2 helps us distinguish case table jumps
10554 ;; which can be present in structured code from indirect jumps which can not
10555 ;; be present in structured code. This allows -fprofile-arcs to work.
10557 ;; For SH1 processors.
10558 (define_insn "casesi_jump_1"
10560 (match_operand:SI 0 "register_operand" "r"))
10561 (use (label_ref (match_operand 1 "" "")))]
10564 [(set_attr "needs_delay_slot" "yes")
10565 (set_attr "type" "jump_ind")])
10567 ;; For all later processors.
10568 (define_insn "casesi_jump_2"
10569 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
10570 (label_ref (match_operand 1 "" ""))))
10571 (use (label_ref (match_operand 2 "" "")))]
10573 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
10575 [(set_attr "needs_delay_slot" "yes")
10576 (set_attr "type" "jump_ind")])
10578 (define_insn "casesi_jump_media"
10579 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
10580 (use (label_ref (match_operand 1 "" "")))]
10583 [(set_attr "type" "jump_media")])
10585 ;; Call subroutine returning any type.
10586 ;; ??? This probably doesn't work.
10587 (define_expand "untyped_call"
10588 [(parallel [(call (match_operand 0 "" "")
10590 (match_operand 1 "" "")
10591 (match_operand 2 "" "")])]
10592 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
10594 if (! TARGET_SHMEDIA)
10596 /* RA does not know that the call sets the function value registers.
10597 We avoid problems by claiming that those registers are clobbered
10599 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10601 rtx set = XVECEXP (operands[2], 0, i);
10602 emit_clobber (SET_SRC (set));
10606 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10608 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10610 rtx set = XVECEXP (operands[2], 0, i);
10611 emit_move_insn (SET_DEST (set), SET_SRC (set));
10614 /* The optimizer does not know that the call sets the function value
10615 registers we stored in the result block. We avoid problems by
10616 claiming that all hard registers are used and clobbered at this
10618 emit_insn (gen_blockage ());
10623 ;; ------------------------------------------------------------------------
10625 ;; ------------------------------------------------------------------------
10627 (define_insn "dect"
10628 [(set (reg:SI T_REG)
10629 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
10630 (set (match_operand:SI 0 "arith_reg_dest" "=r")
10631 (plus:SI (match_dup 1) (const_int -1)))]
10634 [(set_attr "type" "arith")])
10641 ;; Load address of a label. This is only generated by the casesi expand,
10642 ;; and by machine_dependent_reorg (fixing up fp moves).
10643 ;; This must use unspec, because this only works for labels that are
10645 (define_insn "mova"
10646 [(set (reg:SI R0_REG)
10647 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
10650 [(set_attr "in_delay_slot" "no")
10651 (set_attr "type" "arith")])
10653 ;; machine_dependent_reorg will make this a `mova'.
10654 (define_insn "mova_const"
10655 [(set (reg:SI R0_REG)
10656 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
10659 [(set_attr "in_delay_slot" "no")
10660 (set_attr "type" "arith")])
10662 ;; Loads of the GOTPC relocation values must not be optimized away
10663 ;; by e.g. any kind of CSE and must stay as they are. Although there
10664 ;; are other various ways to ensure this, we use an artificial counter
10665 ;; operand to generate unique symbols.
10666 (define_expand "GOTaddr2picreg"
10667 [(set (reg:SI R0_REG)
10668 (unspec:SI [(const:SI (unspec:SI [(match_dup 2)
10669 (match_operand:SI 0 "" "")]
10670 UNSPEC_PIC))] UNSPEC_MOVA))
10672 (const:SI (unspec:SI [(match_dup 2) (match_dup 0)] UNSPEC_PIC)))
10673 (set (match_dup 1) (plus:SI (match_dup 1) (reg:SI R0_REG)))]
10676 if (TARGET_VXWORKS_RTP)
10678 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
10679 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
10680 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
10684 operands[1] = gen_rtx_REG (Pmode, PIC_REG);
10685 operands[2] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10687 if (TARGET_SHMEDIA)
10689 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10690 rtx pic = operands[1];
10691 rtx lab = PATTERN (gen_call_site ());
10694 equiv = operands[2];
10695 operands[2] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[2], lab),
10696 UNSPEC_PCREL_SYMOFF);
10697 operands[2] = gen_rtx_CONST (Pmode, operands[2]);
10699 if (Pmode == SImode)
10701 emit_insn (gen_movsi_const (pic, operands[2]));
10702 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10706 emit_insn (gen_movdi_const (pic, operands[2]));
10707 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10710 insn = emit_move_insn (operands[1], tr);
10712 set_unique_reg_note (insn, REG_EQUAL, equiv);
10718 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10720 (define_expand "vxworks_picreg"
10721 [(set (reg:SI PIC_REG)
10722 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10723 (set (reg:SI R0_REG)
10724 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10725 (set (reg:SI PIC_REG)
10726 (mem:SI (reg:SI PIC_REG)))
10727 (set (reg:SI PIC_REG)
10728 (mem:SI (plus:SI (reg:SI PIC_REG)
10729 (reg:SI R0_REG))))]
10730 "TARGET_VXWORKS_RTP")
10732 (define_insn "*ptb"
10733 [(set (match_operand 0 "target_reg_operand" "=b")
10734 (const (unspec [(match_operand 1 "" "Csy")]
10735 UNSPEC_DATALABEL)))]
10736 "TARGET_SHMEDIA && flag_pic
10737 && satisfies_constraint_Csy (operands[1])"
10738 "ptb/u datalabel %1, %0"
10739 [(set_attr "type" "ptabs_media")
10740 (set_attr "length" "*")])
10742 (define_insn "ptrel_si"
10743 [(set (match_operand:SI 0 "target_reg_operand" "=b")
10744 (plus:SI (match_operand:SI 1 "register_operand" "r")
10746 (match_operand:SI 2 "" "")]
10748 "%O2: ptrel/u %1, %0"
10749 [(set_attr "type" "ptabs_media")])
10751 (define_insn "ptrel_di"
10752 [(set (match_operand:DI 0 "target_reg_operand" "=b")
10753 (plus:DI (match_operand:DI 1 "register_operand" "r")
10755 (match_operand:DI 2 "" "")]
10757 "%O2: ptrel/u %1, %0"
10758 [(set_attr "type" "ptabs_media")])
10760 (define_expand "builtin_setjmp_receiver"
10761 [(match_operand 0 "" "")]
10764 emit_insn (gen_GOTaddr2picreg (const0_rtx));
10768 (define_expand "call_site"
10769 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10772 static HOST_WIDE_INT i = 0;
10773 operands[0] = GEN_INT (i);
10777 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
10778 ;; in symGOT_load expand.
10779 (define_insn_and_split "chk_guard_add"
10780 [(set (match_operand:SI 0 "register_operand" "=&r")
10781 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10786 "TARGET_SH1 && reload_completed"
10787 [(set (match_dup 0) (reg:SI PIC_REG))
10788 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10790 [(set_attr "type" "arith")])
10792 (define_expand "sym_label2reg"
10793 [(set (match_operand:SI 0 "" "")
10794 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10795 (const (plus:SI (match_operand:SI 2 "" "")
10800 (define_expand "symPCREL_label2reg"
10801 [(set (match_operand:SI 0 "" "")
10804 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PCREL))
10805 (const:SI (plus:SI (match_operand:SI 2 "" "")
10806 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))]
10810 (define_expand "symGOT_load"
10811 [(set (match_dup 2) (match_operand 1 "" ""))
10812 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10813 (set (match_operand 0 "" "") (mem (match_dup 3)))]
10817 bool stack_chk_guard_p = false;
10819 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10820 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10822 if (!TARGET_SHMEDIA
10823 && flag_stack_protect
10824 && GET_CODE (operands[1]) == CONST
10825 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10826 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10827 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10828 "__stack_chk_guard") == 0)
10829 stack_chk_guard_p = true;
10831 if (TARGET_SHMEDIA)
10833 rtx reg = operands[2];
10835 if (Pmode == DImode)
10838 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10840 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10845 emit_insn (gen_movsi_const (reg, operands[1]));
10847 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10851 emit_move_insn (operands[2], operands[1]);
10853 /* When stack protector inserts codes after the result is set to
10854 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
10855 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10856 when rX is a GOT address for the guard symbol. Ugly but doesn't
10857 matter because this is a rare situation. */
10858 if (stack_chk_guard_p)
10859 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10861 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10862 gen_rtx_REG (Pmode, PIC_REG)));
10864 /* N.B. This is not constant for a GOTPLT relocation. */
10865 mem = gen_rtx_MEM (Pmode, operands[3]);
10866 MEM_NOTRAP_P (mem) = 1;
10867 /* ??? Should we have a special alias set for the GOT? */
10868 emit_move_insn (operands[0], mem);
10873 (define_expand "sym2GOT"
10874 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10878 (define_expand "symGOT2reg"
10879 [(match_operand 0 "" "") (match_operand 1 "" "")]
10884 gotsym = gen_sym2GOT (operands[1]);
10885 PUT_MODE (gotsym, Pmode);
10886 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10888 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10893 (define_expand "symGOTPLT2reg"
10894 [(match_operand 0 "" "") (match_operand 1 "" "")]
10897 rtx pltsym = gen_rtx_CONST (Pmode,
10898 gen_rtx_UNSPEC (Pmode,
10899 gen_rtvec (1, operands[1]),
10901 emit_insn (gen_symGOT_load (operands[0], pltsym));
10905 (define_expand "sym2GOTOFF"
10906 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10910 (define_expand "symGOTOFF2reg"
10911 [(match_operand 0 "" "") (match_operand 1 "" "")]
10914 rtx gotoffsym, insn;
10915 rtx t = (!can_create_pseudo_p ()
10917 : gen_reg_rtx (GET_MODE (operands[0])));
10919 gotoffsym = gen_sym2GOTOFF (operands[1]);
10920 PUT_MODE (gotoffsym, Pmode);
10921 emit_move_insn (t, gotoffsym);
10922 insn = emit_move_insn (operands[0],
10923 gen_rtx_PLUS (Pmode, t,
10924 gen_rtx_REG (Pmode, PIC_REG)));
10926 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10931 (define_expand "symPLT_label2reg"
10932 [(set (match_operand:SI 0 "" "")
10935 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10936 (const:SI (plus:SI (match_operand:SI 2 "" "")
10937 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10938 ;; Even though the PIC register is not really used by the call
10939 ;; sequence in which this is expanded, the PLT code assumes the PIC
10940 ;; register is set, so we must not skip its initialization. Since
10941 ;; we only use this expand as part of calling sequences, and never
10942 ;; to take the address of a function, this is the best point to
10943 ;; insert the (use). Using the PLT to take the address of a
10944 ;; function would be wrong, not only because the PLT entry could
10945 ;; then be called from a function that doesn't initialize the PIC
10946 ;; register to the proper GOT, but also because pointers to the
10947 ;; same function might not compare equal, should they be set by
10948 ;; different shared libraries.
10949 (use (reg:SI PIC_REG))]
10953 (define_expand "sym2PIC"
10954 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10958 ;; -------------------------------------------------------------------------
10959 ;; TLS code generation.
10961 ;; FIXME: The multi-insn asm blocks should be converted to use
10962 ;; define_insn_and_split.
10963 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10964 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10967 (define_insn "tls_global_dynamic"
10968 [(set (match_operand:SI 0 "register_operand" "=&z")
10969 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10972 (use (reg:SI FPSCR_MODES_REG))
10973 (use (reg:SI PIC_REG))
10974 (clobber (reg:SI PR_REG))
10975 (clobber (scratch:SI))]
10978 return "mov.l 1f,r4" "\n"
10980 " mov.l 2f,r1" "\n"
10987 "1: .long %a1@TLSGD" "\n"
10988 "2: .long __tls_get_addr@PLT" "\n"
10991 [(set_attr "type" "tls_load")
10992 (set_attr "length" "26")])
10994 (define_insn "tls_local_dynamic"
10995 [(set (match_operand:SI 0 "register_operand" "=&z")
10996 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10999 (use (reg:SI FPSCR_MODES_REG))
11000 (use (reg:SI PIC_REG))
11001 (clobber (reg:SI PR_REG))
11002 (clobber (scratch:SI))]
11005 return "mov.l 1f,r4" "\n"
11007 " mov.l 2f,r1" "\n"
11014 "1: .long %a1@TLSLDM" "\n"
11015 "2: .long __tls_get_addr@PLT" "\n"
11018 [(set_attr "type" "tls_load")
11019 (set_attr "length" "26")])
11021 (define_expand "sym2DTPOFF"
11022 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
11026 (define_expand "symDTPOFF2reg"
11027 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
11031 rtx t = (!can_create_pseudo_p ()
11033 : gen_reg_rtx (GET_MODE (operands[0])));
11035 dtpoffsym = gen_sym2DTPOFF (operands[1]);
11036 PUT_MODE (dtpoffsym, Pmode);
11037 emit_move_insn (t, dtpoffsym);
11038 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
11042 (define_expand "sym2GOTTPOFF"
11043 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
11047 (define_insn "tls_initial_exec"
11048 [(set (match_operand:SI 0 "register_operand" "=&r")
11049 (unspec:SI [(match_operand:SI 1 "" "")]
11051 (use (reg:SI GBR_REG))
11052 (use (reg:SI PIC_REG))
11053 (clobber (reg:SI R0_REG))]
11056 return "mov.l 1f,r0" "\n"
11058 " mov.l @(r0,r12),r0" "\n"
11062 "1: .long %a1" "\n"
11065 [(set_attr "type" "tls_load")
11066 (set_attr "length" "16")])
11068 (define_expand "sym2TPOFF"
11069 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
11073 (define_expand "symTPOFF2reg"
11074 [(match_operand 0 "" "") (match_operand 1 "" "")]
11079 tpoffsym = gen_sym2TPOFF (operands[1]);
11080 PUT_MODE (tpoffsym, Pmode);
11081 emit_move_insn (operands[0], tpoffsym);
11085 ;;------------------------------------------------------------------------------
11086 ;; Thread pointer getter and setter.
11088 ;; On SH the thread pointer is kept in the GBR.
11089 ;; These patterns are usually expanded from the respective built-in functions.
11090 (define_expand "get_thread_pointersi"
11091 [(set (match_operand:SI 0 "arith_reg_dest") (reg:SI GBR_REG))]
11094 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
11095 (define_insn "store_gbr"
11096 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (reg:SI GBR_REG))]
11099 [(set_attr "type" "tls_load")])
11101 (define_expand "set_thread_pointersi"
11102 [(set (reg:SI GBR_REG)
11103 (unspec_volatile:SI [(match_operand:SI 0 "arith_reg_operand")]
11107 (define_insn "load_gbr"
11108 [(set (reg:SI GBR_REG)
11109 (unspec_volatile:SI [(match_operand:SI 0 "arith_reg_operand" "r")]
11113 [(set_attr "type" "move")])
11115 ;;------------------------------------------------------------------------------
11116 ;; Thread pointer relative memory loads and stores.
11118 ;; On SH there are GBR displacement address modes which can be utilized to
11119 ;; access memory behind the thread pointer.
11120 ;; Since we do not allow using GBR for general purpose memory accesses, these
11121 ;; GBR addressing modes are formed by the combine pass.
11122 ;; This could be done with fewer patterns than below by using a mem predicate
11123 ;; for the GBR mem, but then reload would try to reload addresses with a
11124 ;; zero displacement for some strange reason.
11126 (define_insn "*mov<mode>_gbr_load"
11127 [(set (match_operand:QIHISI 0 "arith_reg_dest" "=z")
11128 (mem:QIHISI (plus:SI (reg:SI GBR_REG)
11129 (match_operand:QIHISI 1 "gbr_displacement"))))]
11131 "mov.<bwl> @(%O1,gbr),%0"
11132 [(set_attr "type" "load")])
11134 (define_insn "*mov<mode>_gbr_load"
11135 [(set (match_operand:QIHISI 0 "arith_reg_dest" "=z")
11136 (mem:QIHISI (reg:SI GBR_REG)))]
11138 "mov.<bwl> @(0,gbr),%0"
11139 [(set_attr "type" "load")])
11141 (define_insn "*mov<mode>_gbr_load"
11142 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11144 (mem:QIHI (plus:SI (reg:SI GBR_REG)
11145 (match_operand:QIHI 1 "gbr_displacement")))))]
11147 "mov.<bw> @(%O1,gbr),%0"
11148 [(set_attr "type" "load")])
11150 (define_insn "*mov<mode>_gbr_load"
11151 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11152 (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
11154 "mov.<bw> @(0,gbr),%0"
11155 [(set_attr "type" "load")])
11157 (define_insn "*mov<mode>_gbr_store"
11158 [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
11159 (match_operand:QIHISI 0 "gbr_displacement")))
11160 (match_operand:QIHISI 1 "register_operand" "z"))]
11162 "mov.<bwl> %1,@(%O0,gbr)"
11163 [(set_attr "type" "store")])
11165 (define_insn "*mov<mode>_gbr_store"
11166 [(set (mem:QIHISI (reg:SI GBR_REG))
11167 (match_operand:QIHISI 0 "register_operand" "z"))]
11169 "mov.<bwl> %0,@(0,gbr)"
11170 [(set_attr "type" "store")])
11172 ;; DImode memory accesses have to be split in two SImode accesses.
11173 ;; Split them before reload, so that it gets a better chance to figure out
11174 ;; how to deal with the R0 restriction for the individual SImode accesses.
11175 ;; Do not match this insn during or after reload because it can't be split
11177 (define_insn_and_split "*movdi_gbr_load"
11178 [(set (match_operand:DI 0 "arith_reg_dest")
11179 (match_operand:DI 1 "gbr_address_mem"))]
11180 "TARGET_SH1 && can_create_pseudo_p ()"
11183 [(set (match_dup 3) (match_dup 5))
11184 (set (match_dup 4) (match_dup 6))]
11186 /* Swap low/high part load order on little endian, so that the result reg
11187 of the second load can be used better. */
11188 int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
11189 operands[3 + off] = gen_lowpart (SImode, operands[0]);
11190 operands[5 + off] = gen_lowpart (SImode, operands[1]);
11191 operands[4 - off] = gen_highpart (SImode, operands[0]);
11192 operands[6 - off] = gen_highpart (SImode, operands[1]);
11195 (define_insn_and_split "*movdi_gbr_store"
11196 [(set (match_operand:DI 0 "gbr_address_mem")
11197 (match_operand:DI 1 "register_operand"))]
11198 "TARGET_SH1 && can_create_pseudo_p ()"
11201 [(set (match_dup 3) (match_dup 5))
11202 (set (match_dup 4) (match_dup 6))]
11204 /* Swap low/high part store order on big endian, so that stores of function
11205 call results can save a reg copy. */
11206 int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
11207 operands[3 + off] = gen_lowpart (SImode, operands[0]);
11208 operands[5 + off] = gen_lowpart (SImode, operands[1]);
11209 operands[4 - off] = gen_highpart (SImode, operands[0]);
11210 operands[6 - off] = gen_highpart (SImode, operands[1]);
11213 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
11214 ;; in particular when the displacements are in the range of the regular move
11215 ;; insns. Thus, in the first split pass after the combine pass we search
11216 ;; for missed opportunities and try to fix them up ourselves.
11217 ;; If an equivalent GBR address can be determined the load / store is split
11218 ;; into one of the GBR load / store patterns.
11219 ;; All of that must happen before reload (GBR address modes use R0 as the
11220 ;; other operand) and there's no point of doing it if the GBR is not
11221 ;; referenced in a function at all.
11223 [(set (match_operand:QIHISIDI 0 "register_operand")
11224 (match_operand:QIHISIDI 1 "memory_operand"))]
11225 "TARGET_SH1 && !reload_in_progress && !reload_completed
11226 && df_regs_ever_live_p (GBR_REG)"
11227 [(set (match_dup 0) (match_dup 1))]
11229 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
11230 if (gbr_mem != NULL_RTX)
11231 operands[1] = replace_equiv_address (operands[1], gbr_mem);
11237 [(set (match_operand:SI 0 "register_operand")
11238 (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
11239 "TARGET_SH1 && !reload_in_progress && !reload_completed
11240 && df_regs_ever_live_p (GBR_REG)"
11241 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
11243 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
11244 if (gbr_mem != NULL_RTX)
11245 operands[1] = replace_equiv_address (operands[1], gbr_mem);
11250 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
11251 ;; Split those so that a GBR load can be used.
11253 [(set (match_operand:SI 0 "register_operand")
11254 (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
11255 "TARGET_SH2A && !reload_in_progress && !reload_completed
11256 && df_regs_ever_live_p (GBR_REG)"
11257 [(set (match_dup 2) (match_dup 1))
11258 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11260 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
11261 if (gbr_mem != NULL_RTX)
11263 operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
11264 operands[1] = replace_equiv_address (operands[1], gbr_mem);
11271 [(set (match_operand:QIHISIDI 0 "memory_operand")
11272 (match_operand:QIHISIDI 1 "register_operand"))]
11273 "TARGET_SH1 && !reload_in_progress && !reload_completed
11274 && df_regs_ever_live_p (GBR_REG)"
11275 [(set (match_dup 0) (match_dup 1))]
11277 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
11278 if (gbr_mem != NULL_RTX)
11279 operands[0] = replace_equiv_address (operands[0], gbr_mem);
11284 ;;------------------------------------------------------------------------------
11285 ;; case instruction for switch statements.
11287 ;; operand 0 is index
11288 ;; operand 1 is the minimum bound
11289 ;; operand 2 is the maximum bound - minimum bound + 1
11290 ;; operand 3 is CODE_LABEL for the table;
11291 ;; operand 4 is the CODE_LABEL to go to if index out of range.
11292 (define_expand "casesi"
11293 [(match_operand:SI 0 "arith_reg_operand" "")
11294 (match_operand:SI 1 "arith_reg_operand" "")
11295 (match_operand:SI 2 "arith_reg_operand" "")
11296 (match_operand 3 "" "") (match_operand 4 "" "")]
11299 rtx reg = gen_reg_rtx (SImode);
11300 rtx reg2 = gen_reg_rtx (SImode);
11301 if (TARGET_SHMEDIA)
11303 rtx reg = gen_reg_rtx (DImode);
11304 rtx reg2 = gen_reg_rtx (DImode);
11305 rtx reg3 = gen_reg_rtx (Pmode);
11306 rtx reg4 = gen_reg_rtx (Pmode);
11307 rtx reg5 = gen_reg_rtx (Pmode);
11310 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
11311 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
11312 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
11314 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
11315 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0],
11317 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
11318 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
11319 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
11320 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
11321 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
11322 (Pmode, operands[3])));
11323 /* Messy: can we subreg to clean this up? */
11324 if (Pmode == DImode)
11325 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
11327 load = gen_casesi_load_media (reg4,
11328 gen_rtx_SUBREG (DImode, reg3, 0),
11329 reg2, operands[3]);
11330 PUT_MODE (SET_SRC (load), Pmode);
11332 /* ??? The following add could be eliminated if we used ptrel. */
11333 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
11334 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
11338 operands[1] = copy_to_mode_reg (SImode, operands[1]);
11339 operands[2] = copy_to_mode_reg (SImode, operands[2]);
11340 /* If optimizing, casesi_worker depends on the mode of the instruction
11341 before label it 'uses' - operands[3]. */
11342 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
11344 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
11346 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
11348 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
11349 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
11350 operands[3], but to lab. We will fix this up in
11351 machine_dependent_reorg. */
11356 (define_expand "casesi_0"
11357 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
11358 (set (match_dup 4) (minus:SI (match_dup 4)
11359 (match_operand:SI 1 "arith_operand" "")))
11360 (set (reg:SI T_REG)
11361 (gtu:SI (match_dup 4)
11362 (match_operand:SI 2 "arith_reg_operand" "")))
11364 (if_then_else (ne (reg:SI T_REG)
11366 (label_ref (match_operand 3 "" ""))
11371 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
11372 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
11373 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
11374 (define_insn "casesi_worker_0"
11375 [(set (match_operand:SI 0 "register_operand" "=r,r")
11376 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
11377 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
11378 (clobber (match_scratch:SI 3 "=X,1"))
11379 (clobber (match_scratch:SI 4 "=&z,z"))]
11384 [(set (match_operand:SI 0 "register_operand" "")
11385 (unspec:SI [(match_operand:SI 1 "register_operand" "")
11386 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
11387 (clobber (match_scratch:SI 3 ""))
11388 (clobber (match_scratch:SI 4 ""))]
11389 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
11390 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
11391 (parallel [(set (match_dup 0)
11392 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
11393 (label_ref (match_dup 2))] UNSPEC_CASESI))
11394 (clobber (match_dup 3))])
11395 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
11397 if (GET_CODE (operands[2]) == CODE_LABEL)
11398 LABEL_NUSES (operands[2])++;
11402 [(set (match_operand:SI 0 "register_operand" "")
11403 (unspec:SI [(match_operand:SI 1 "register_operand" "")
11404 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
11405 (clobber (match_scratch:SI 3 ""))
11406 (clobber (match_scratch:SI 4 ""))]
11407 "TARGET_SH2 && reload_completed"
11408 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
11409 (parallel [(set (match_dup 0)
11410 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
11411 (label_ref (match_dup 2))] UNSPEC_CASESI))
11412 (clobber (match_dup 3))])]
11414 if (GET_CODE (operands[2]) == CODE_LABEL)
11415 LABEL_NUSES (operands[2])++;
11418 ;; This may be replaced with casesi_worker_2 in sh_reorg for PIC.
11419 ;; The insn length is set to 8 for that case.
11420 (define_insn "casesi_worker_1"
11421 [(set (match_operand:SI 0 "register_operand" "=r,r")
11422 (unspec:SI [(reg:SI R0_REG)
11423 (match_operand:SI 1 "register_operand" "0,r")
11424 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
11425 (clobber (match_scratch:SI 3 "=X,1"))]
11428 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
11430 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11432 switch (GET_MODE (diff_vec))
11435 return "shll2 %1" "\n"
11436 " mov.l @(r0,%1),%0";
11438 return "add %1,%1" "\n"
11439 " mov.w @(r0,%1),%0";
11441 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11442 return "mov.b @(r0,%1),%0" "\n"
11445 return "mov.b @(r0,%1),%0";
11448 gcc_unreachable ();
11451 [(set_attr_alternative "length"
11452 [(if_then_else (match_test "flag_pic") (const_int 8) (const_int 4))
11453 (if_then_else (match_test "flag_pic") (const_int 8) (const_int 4))])])
11455 (define_insn "casesi_worker_2"
11456 [(set (match_operand:SI 0 "register_operand" "=r,r")
11457 (unspec:SI [(reg:SI R0_REG)
11458 (match_operand:SI 1 "register_operand" "0,r")
11459 (label_ref (match_operand 2 "" ""))
11460 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
11461 (clobber (match_operand:SI 4 "" "=X,1"))]
11462 "TARGET_SH2 && reload_completed && flag_pic"
11464 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
11465 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11467 switch (GET_MODE (diff_vec))
11470 return "shll2 %1" "\n"
11472 " mova %O3,r0" "\n"
11473 " mov.l @(r0,%1),%0";
11475 return "add %1,%1" "\n"
11477 " mova %O3,r0" "\n"
11478 " mov.w @(r0,%1),%0";
11480 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11481 return "add r0,%1" "\n"
11482 " mova %O3,r0" "\n"
11483 " mov.b @(r0,%1),%0" "\n"
11486 return "add r0,%1" "\n"
11487 " mova %O3,r0" "\n"
11488 " mov.b @(r0,%1),%0";
11490 gcc_unreachable ();
11493 [(set_attr "length" "8")])
11495 (define_insn "casesi_shift_media"
11496 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11497 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
11498 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
11502 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
11504 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11506 switch (GET_MODE (diff_vec))
11509 return "shlli %1, 2, %0";
11511 return "shlli %1, 1, %0";
11513 if (rtx_equal_p (operands[0], operands[1]))
11515 return "add %1, r63, %0";
11517 gcc_unreachable ();
11520 [(set_attr "type" "arith_media")])
11522 (define_insn "casesi_load_media"
11523 [(set (match_operand 0 "any_arith_reg_dest" "=r")
11524 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
11525 (match_operand:DI 2 "arith_reg_operand" "r")
11526 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
11529 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[3])));
11531 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
11533 switch (GET_MODE (diff_vec))
11536 return "ldx.l %1, %2, %0";
11539 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11540 return "ldx.uw %1, %2, %0";
11542 return "ldx.w %1, %2, %0";
11544 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
11545 return "ldx.ub %1, %2, %0";
11546 return "ldx.b %1, %2, %0";
11548 gcc_unreachable ();
11551 [(set_attr "type" "load_media")])
11553 (define_expand "simple_return"
11555 "sh_can_use_simple_return_p ()")
11557 (define_expand "return"
11559 "reload_completed && epilogue_completed"
11561 if (TARGET_SHMEDIA)
11563 emit_jump_insn (gen_return_media ());
11567 if (TARGET_SHCOMPACT
11568 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
11570 emit_jump_insn (gen_shcompact_return_tramp ());
11575 (define_insn "*<code>_i"
11577 "TARGET_SH1 && ! (TARGET_SHCOMPACT
11578 && (crtl->args.info.call_cookie
11579 & CALL_COOKIE_RET_TRAMP (1)))
11580 && reload_completed
11581 && ! sh_cfun_trap_exit_p ()"
11583 if (TARGET_SH2A && (dbr_sequence_length () == 0)
11584 && !current_function_interrupt)
11589 [(set_attr "type" "return")
11590 (set_attr "needs_delay_slot" "yes")])
11592 ;; trapa has no delay slot.
11593 (define_insn "*return_trapa"
11595 "TARGET_SH1 && !TARGET_SHCOMPACT
11596 && reload_completed"
11598 [(set_attr "type" "return")])
11600 (define_expand "shcompact_return_tramp"
11603 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
11605 rtx reg = gen_rtx_REG (Pmode, R0_REG);
11607 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
11608 emit_jump_insn (gen_shcompact_return_tramp_i ());
11612 (define_insn "shcompact_return_tramp_i"
11613 [(parallel [(return) (use (reg:SI R0_REG))])]
11615 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
11617 [(set_attr "type" "jump_ind")
11618 (set_attr "needs_delay_slot" "yes")])
11620 (define_insn "return_media_i"
11621 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
11622 "TARGET_SHMEDIA && reload_completed"
11624 [(set_attr "type" "jump_media")])
11626 (define_insn "return_media_rte"
11628 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
11630 [(set_attr "type" "jump_media")])
11632 (define_expand "return_media"
11634 "TARGET_SHMEDIA && reload_completed"
11636 int tr_regno = sh_media_register_for_return ();
11639 if (current_function_interrupt)
11641 emit_jump_insn (gen_return_media_rte ());
11646 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
11648 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
11649 tr_regno = TR0_REG;
11650 tr = gen_rtx_REG (Pmode, tr_regno);
11651 emit_move_insn (tr, r18);
11654 tr = gen_rtx_REG (Pmode, tr_regno);
11656 emit_jump_insn (gen_return_media_i (tr));
11660 (define_insn "shcompact_preserve_incoming_args"
11661 [(set (match_operand:SI 0 "register_operand" "+r")
11662 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
11665 [(set_attr "length" "0")])
11667 (define_insn "shcompact_incoming_args"
11668 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
11669 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
11670 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
11671 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
11672 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
11673 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
11674 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
11675 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
11676 (set (mem:BLK (reg:SI MACL_REG))
11677 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
11678 (use (reg:SI R0_REG))
11679 (clobber (reg:SI R0_REG))
11680 (clobber (reg:SI MACL_REG))
11681 (clobber (reg:SI MACH_REG))
11682 (clobber (reg:SI PR_REG))]
11685 [(set_attr "needs_delay_slot" "yes")])
11687 (define_insn "shmedia_save_restore_regs_compact"
11688 [(set (reg:SI SP_REG)
11689 (plus:SI (reg:SI SP_REG)
11690 (match_operand:SI 0 "immediate_operand" "i")))
11691 (use (reg:SI R0_REG))
11692 (clobber (reg:SI PR_REG))]
11694 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
11695 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
11697 [(set_attr "needs_delay_slot" "yes")])
11699 (define_expand "prologue"
11703 sh_expand_prologue ();
11707 (define_expand "epilogue"
11711 sh_expand_epilogue (false);
11713 || (TARGET_SHCOMPACT
11714 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11716 emit_jump_insn (gen_return ());
11721 (define_expand "eh_return"
11722 [(use (match_operand 0 "register_operand" ""))]
11725 rtx ra = operands[0];
11727 if (TARGET_SHMEDIA64)
11728 emit_insn (gen_eh_set_ra_di (ra));
11730 emit_insn (gen_eh_set_ra_si (ra));
11735 ;; Clobber the return address on the stack. We can't expand this
11736 ;; until we know where it will be put in the stack frame.
11738 (define_insn "eh_set_ra_si"
11739 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11741 (clobber (match_scratch:SI 1 "=&r"))]
11742 "! TARGET_SHMEDIA64"
11745 (define_insn "eh_set_ra_di"
11746 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11748 (clobber (match_scratch:DI 1 "=&r"))]
11753 [(unspec_volatile [(match_operand 0 "register_operand" "")]
11755 (clobber (match_scratch 1 ""))]
11759 sh_set_return_address (operands[0], operands[1]);
11763 (define_insn "blockage"
11764 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11767 [(set_attr "length" "0")])
11769 ;; Define movml instructions for SH2A target. Currently they are
11770 ;; used to push and pop all banked registers only.
11772 (define_insn "movml_push_banked"
11773 [(set (match_operand:SI 0 "register_operand" "=r")
11774 (plus (match_dup 0) (const_int -32)))
11775 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11776 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11777 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11778 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11779 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11780 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11781 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11782 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11783 "TARGET_SH2A && REGNO (operands[0]) == 15"
11785 [(set_attr "in_delay_slot" "no")])
11787 (define_insn "movml_pop_banked"
11788 [(set (match_operand:SI 0 "register_operand" "=r")
11789 (plus (match_dup 0) (const_int 32)))
11790 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11791 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11792 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11793 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11794 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11795 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11796 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11797 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11798 "TARGET_SH2A && REGNO (operands[0]) == 15"
11800 [(set_attr "in_delay_slot" "no")])
11802 ;; ------------------------------------------------------------------------
11803 ;; Scc instructions
11804 ;; ------------------------------------------------------------------------
11806 (define_insn "movt"
11807 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11808 (match_operand:SI 1 "t_reg_operand"))]
11811 [(set_attr "type" "arith")])
11813 (define_insn "movrt"
11814 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11815 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11818 [(set_attr "type" "arith")])
11820 (define_expand "cstore4_media"
11821 [(set (match_operand:SI 0 "register_operand" "=r")
11822 (match_operator:SI 1 "sh_float_comparison_operator"
11823 [(match_operand 2 "logical_operand" "")
11824 (match_operand 3 "cmp_operand" "")]))]
11827 machine_mode mode = GET_MODE (operands[2]);
11828 enum rtx_code code = GET_CODE (operands[1]);
11830 if (mode == VOIDmode)
11831 mode = GET_MODE (operands[3]);
11832 if (operands[2] == const0_rtx)
11834 if (code == EQ || code == NE)
11835 operands[2] = operands[3], operands[3] = const0_rtx;
11838 operands[2] = force_reg (mode, operands[2]);
11839 if (operands[3] != const0_rtx)
11840 operands[3] = force_reg (mode, operands[3]);
11846 swap = invert = !FLOAT_MODE_P (mode);
11851 swap = FLOAT_MODE_P (mode), invert = !swap;
11856 swap = true, invert = false;
11863 swap = invert = false;
11867 swap = invert = true;
11871 gcc_unreachable ();
11876 std::swap (operands[2], operands[3]);
11877 code = swap_condition (code);
11882 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11883 code = reverse_condition (code);
11884 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11885 emit_insn (gen_cstore4_media (tem, operands[1],
11886 operands[2], operands[3]));
11889 operands[3] = const0_rtx;
11892 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11895 (define_expand "cstoresi4"
11896 [(set (match_operand:SI 0 "register_operand" "=r")
11897 (match_operator:SI 1 "comparison_operator"
11898 [(match_operand:SI 2 "cmpsi_operand" "")
11899 (match_operand:SI 3 "arith_operand" "")]))]
11900 "TARGET_SH1 || TARGET_SHMEDIA"
11902 if (TARGET_SHMEDIA)
11904 emit_insn (gen_cstore4_media (operands[0], operands[1],
11905 operands[2], operands[3]));
11909 if (sh_expand_t_scc (operands))
11912 if (! currently_expanding_to_rtl)
11915 sh_emit_compare_and_set (operands, SImode);
11919 (define_expand "cstoredi4"
11920 [(set (match_operand:SI 0 "register_operand" "=r")
11921 (match_operator:SI 1 "comparison_operator"
11922 [(match_operand:DI 2 "arith_operand" "")
11923 (match_operand:DI 3 "arith_operand" "")]))]
11924 "TARGET_SH2 || TARGET_SHMEDIA"
11926 if (TARGET_SHMEDIA)
11928 emit_insn (gen_cstore4_media (operands[0], operands[1],
11929 operands[2], operands[3]));
11933 if (sh_expand_t_scc (operands))
11936 if (! currently_expanding_to_rtl)
11939 sh_emit_compare_and_set (operands, DImode);
11943 ;; Move the complement of the T reg to a reg.
11944 ;; On SH2A the movrt insn can be used.
11945 ;; On anything else than SH2A this has to be done with multiple instructions.
11946 ;; One obvious way would be:
11951 ;; However, this puts pressure on r0 in most cases and thus the following is
11957 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11958 ;; becomes a one instruction operation. Moreover, care must be taken that
11959 ;; the insn can still be combined with inverted compare and branch code
11960 ;; around it. On the other hand, if a function returns the complement of
11961 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11962 ;; lead to better code.
11963 (define_expand "movnegt"
11964 [(set (match_operand:SI 0 "arith_reg_dest" "")
11965 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11969 emit_insn (gen_movrt (operands[0], operands[1]));
11972 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11973 emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11978 (define_insn_and_split "movrt_negc"
11979 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11980 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11981 (set (reg:SI T_REG) (const_int 1))
11982 (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11985 "&& !sh_in_recog_treg_set_expr ()"
11988 if (sh_split_movrt_negc_to_movt_xor (curr_insn, operands))
11993 [(set_attr "type" "arith")])
11995 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11996 ;; pattern can be used by the combine pass. Using a scratch reg for the
11997 ;; -1 constant results in slightly better register allocations compared to
11998 ;; generating a pseudo reg before reload.
11999 (define_insn_and_split "*movrt_negc"
12000 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12001 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
12002 (clobber (match_scratch:SI 2 "=r"))
12003 (clobber (reg:SI T_REG))]
12004 "TARGET_SH1 && ! TARGET_SH2A"
12006 "&& !sh_in_recog_treg_set_expr ()"
12009 if (sh_split_movrt_negc_to_movt_xor (curr_insn, operands))
12011 else if (reload_completed)
12013 emit_move_insn (operands[2], gen_int_mode (-1, SImode));
12014 emit_insn (gen_movrt_negc (operands[0], operands[1], operands[2]));
12021 ;; Store the negated T bit in a reg using r0 and xor. This one doesn't
12022 ;; clobber the T bit, which is useful when storing the T bit and the
12023 ;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
12024 ;; Usually we don't want this insn to be matched, except for cases where the
12025 ;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
12026 (define_insn_and_split "movrt_xor"
12027 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
12028 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
12029 (use (reg:SI T_REG))]
12032 "&& reload_completed"
12033 [(set (match_dup 0) (reg:SI T_REG))
12034 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
12037 ;; 0x7fffffff + (1-T) = 0 - 0x80000000 - T
12039 ;; Notice that 0 - 0x80000000 = 0x80000000.
12041 ;; Single bit tests are usually done with zero_extract. On non-SH2A this
12042 ;; will use a tst-negc sequence. On SH2A it will use a bld-addc sequence.
12043 ;; The zeroth bit requires a special pattern, otherwise we get a shlr-addc.
12044 ;; This is a special case of the generic treg_set_expr pattern and thus has
12045 ;; to come first or it will never match.
12046 (define_insn_and_split "*mov_t_msb_neg"
12047 [(set (match_operand:SI 0 "arith_reg_dest")
12048 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
12050 (const_int 2147483647)))
12051 (clobber (reg:SI T_REG))]
12054 "&& can_create_pseudo_p ()"
12055 [(parallel [(set (match_dup 0)
12056 (plus:SI (zero_extract:SI (match_dup 1)
12057 (const_int 1) (const_int 0))
12058 (const_int 2147483647)))
12059 (clobber (reg:SI T_REG))])])
12061 (define_insn_and_split "*mov_t_msb_neg"
12062 [(set (match_operand:SI 0 "arith_reg_dest")
12063 (plus:SI (match_operand 1 "treg_set_expr")
12064 (const_int 2147483647))) ;; 0x7fffffff
12065 (clobber (reg:SI T_REG))]
12068 "&& can_create_pseudo_p ()"
12071 if (negt_reg_operand (operands[1], VOIDmode))
12073 emit_insn (gen_negc (operands[0],
12074 force_reg (SImode, GEN_INT (-2147483648LL))));
12078 sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
12079 if (ti.remove_trailing_nott ())
12080 emit_insn (gen_negc (operands[0],
12081 force_reg (SImode, GEN_INT (-2147483648LL))));
12083 emit_insn (gen_addc (operands[0],
12084 force_reg (SImode, const0_rtx),
12085 force_reg (SImode, GEN_INT (2147483647))));
12089 (define_insn_and_split "*mov_t_msb_neg"
12090 [(set (match_operand:SI 0 "arith_reg_dest")
12091 (if_then_else:SI (match_operand 1 "treg_set_expr")
12092 (match_operand 2 "const_int_operand")
12093 (match_operand 3 "const_int_operand")))
12094 (clobber (reg:SI T_REG))]
12095 "TARGET_SH1 && can_create_pseudo_p ()
12096 && ((INTVAL (operands[2]) == -2147483648LL
12097 && INTVAL (operands[3]) == 2147483647LL)
12098 || (INTVAL (operands[2]) == 2147483647LL
12099 && INTVAL (operands[3]) == -2147483648LL))"
12104 sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
12106 if (INTVAL (operands[2]) == -2147483648LL)
12108 if (ti.remove_trailing_nott ())
12109 emit_insn (gen_negc (operands[0],
12110 force_reg (SImode, GEN_INT (-2147483648LL))));
12112 emit_insn (gen_addc (operands[0],
12113 force_reg (SImode, const0_rtx),
12114 force_reg (SImode, operands[3])));
12117 else if (INTVAL (operands[2]) == 2147483647LL)
12119 if (ti.remove_trailing_nott ())
12120 emit_insn (gen_addc (operands[0],
12121 force_reg (SImode, const0_rtx),
12122 force_reg (SImode, GEN_INT (2147483647LL))));
12124 emit_insn (gen_negc (operands[0],
12125 force_reg (SImode, GEN_INT (-2147483648LL))));
12129 gcc_unreachable ();
12132 ;; The *negnegt pattern helps the combine pass to figure out how to fold
12133 ;; an explicit double T bit negation.
12134 (define_insn_and_split "*negnegt"
12135 [(set (reg:SI T_REG)
12136 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
12142 ;; Store (negated) T bit as all zeros or ones in a reg.
12143 ;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
12144 ;; not Rn,Rn ! Rn = 0 - Rn
12145 (define_insn_and_split "mov_neg_si_t"
12146 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12147 (neg:SI (match_operand 1 "treg_set_expr")))]
12150 gcc_assert (t_reg_operand (operands[1], VOIDmode));
12151 return "subc %0,%0";
12153 "&& can_create_pseudo_p () && !t_reg_operand (operands[1], VOIDmode)"
12156 sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
12157 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
12159 if (ti.remove_trailing_nott ())
12160 emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
12164 [(set_attr "type" "arith")])
12166 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
12167 (define_insn_and_split "*movtt"
12168 [(set (reg:SI T_REG)
12169 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
12175 ;; Invert the T bit.
12176 ;; On SH2A we can use the nott insn. On anything else this must be done with
12177 ;; multiple insns like:
12180 ;; This requires an additional pseudo. The SH specific sh_treg_combine RTL
12181 ;; pass will look for this insn. Disallow using it if pseudos can't be
12183 ;; Don't split the nott inside the splitting of a treg_set_expr, or else
12184 ;; surrounding insns might not see and recombine it. Defer the splitting
12185 ;; of the nott until after the whole insn containing the treg_set_expr
12187 (define_insn_and_split "nott"
12188 [(set (reg:SI T_REG)
12189 (xor:SI (match_operand:SI 0 "t_reg_operand") (const_int 1)))]
12190 "TARGET_SH2A || (TARGET_SH1 && can_create_pseudo_p ())"
12192 gcc_assert (TARGET_SH2A);
12195 "!TARGET_SH2A && can_create_pseudo_p () && !sh_in_recog_treg_set_expr ()"
12196 [(set (match_dup 0) (reg:SI T_REG))
12197 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
12199 operands[0] = gen_reg_rtx (SImode);
12202 ;; Store T bit as MSB in a reg.
12203 ;; T = 0: 0x00000000 -> reg
12204 ;; T = 1: 0x80000000 -> reg
12205 (define_insn_and_split "*movt_msb"
12206 [(set (match_operand:SI 0 "arith_reg_dest")
12207 (mult:SI (match_operand:SI 1 "t_reg_operand")
12208 (const_int -2147483648))) ;; 0xffffffff80000000
12209 (clobber (reg:SI T_REG))]
12213 [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
12215 ;; Store inverted T bit as MSB in a reg.
12216 ;; T = 0: 0x80000000 -> reg
12217 ;; T = 1: 0x00000000 -> reg
12218 ;; On SH2A we can get away without clobbering the T_REG using the movrt insn.
12219 ;; On non SH2A we resort to the following sequence:
12223 ;; The T bit value will be modified during the sequence, but the rotcr insn
12224 ;; will restore its original value.
12225 (define_insn_and_split "*negt_msb"
12226 [(set (match_operand:SI 0 "arith_reg_dest")
12227 (match_operand:SI 1 "negt_reg_shl31_operand"))]
12230 "&& can_create_pseudo_p ()"
12233 rtx tmp = gen_reg_rtx (SImode);
12237 emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
12238 emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
12242 emit_move_insn (tmp, get_t_reg_rtx ());
12243 emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
12244 emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
12249 ;; The *cset_zero patterns convert optimizations such as
12250 ;; "if (test) x = 0;"
12252 ;; "x &= -(test == 0);"
12253 ;; back to conditional branch sequences if zero-displacement branches
12255 ;; FIXME: These patterns can be removed when conditional execution patterns
12256 ;; are implemented, since ifcvt will not perform these optimizations if
12257 ;; conditional execution is supported.
12258 (define_insn "*cset_zero"
12259 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12260 (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
12262 (match_operand:SI 2 "arith_reg_operand" "0")))]
12263 "TARGET_SH1 && TARGET_ZDCBRANCH"
12265 return "bf 0f" "\n"
12269 [(set_attr "type" "arith") ;; poor approximation
12270 (set_attr "length" "4")])
12272 (define_insn "*cset_zero"
12273 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12274 (if_then_else:SI (match_operand:SI 1 "cbranch_treg_value")
12275 (match_operand:SI 2 "arith_reg_operand" "0")
12277 "TARGET_SH1 && TARGET_ZDCBRANCH"
12279 int tval = sh_eval_treg_value (operands[1]);
12281 return "bt 0f" "\n"
12284 else if (tval == false)
12285 return "bf 0f" "\n"
12289 gcc_unreachable ();
12291 [(set_attr "type" "arith") ;; poor approximation
12292 (set_attr "length" "4")])
12294 (define_expand "cstoresf4"
12295 [(set (match_operand:SI 0 "register_operand" "=r")
12296 (match_operator:SI 1 "sh_float_comparison_operator"
12297 [(match_operand:SF 2 "arith_operand" "")
12298 (match_operand:SF 3 "arith_operand" "")]))]
12299 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12301 if (TARGET_SHMEDIA)
12303 emit_insn (gen_cstore4_media (operands[0], operands[1],
12304 operands[2], operands[3]));
12308 if (! currently_expanding_to_rtl)
12311 sh_emit_compare_and_set (operands, SFmode);
12315 (define_expand "cstoredf4"
12316 [(set (match_operand:SI 0 "register_operand" "=r")
12317 (match_operator:SI 1 "sh_float_comparison_operator"
12318 [(match_operand:DF 2 "arith_operand" "")
12319 (match_operand:DF 3 "arith_operand" "")]))]
12320 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12322 if (TARGET_SHMEDIA)
12324 emit_insn (gen_cstore4_media (operands[0], operands[1],
12325 operands[2], operands[3]));
12329 if (! currently_expanding_to_rtl)
12332 sh_emit_compare_and_set (operands, DFmode);
12336 ;; Sometimes the T bit result of insns is needed in normal registers.
12337 ;; Instead of open coding all the pattern variations, use the treg_set_expr
12338 ;; predicate to match any T bit output insn and split it out after.
12339 ;; This pattern should be below all other related patterns so that it is
12340 ;; considered as a last resort option during matching. This allows
12341 ;; overriding it with special case patterns.
12342 (define_insn_and_split "any_treg_expr_to_reg"
12343 [(set (match_operand:SI 0 "arith_reg_dest")
12344 (match_operand 1 "treg_set_expr"))
12345 (clobber (reg:SI T_REG))]
12346 "TARGET_SH1 && can_create_pseudo_p ()"
12348 "&& !sh_in_recog_treg_set_expr ()"
12352 fprintf (dump_file, "splitting any_treg_expr_to_reg\n");
12354 if (t_reg_operand (operands[1], VOIDmode))
12357 fprintf (dump_file, "t_reg_operand: emitting movt\n");
12358 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
12361 if (negt_reg_operand (operands[1], VOIDmode))
12364 fprintf (dump_file, "negt_reg_operand: emitting movrt\n");
12365 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
12369 /* If the split out insns ended with a nott, emit a movrt sequence,
12370 otherwise a normal movt. */
12371 sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
12372 rtx_insn* i = NULL;
12373 if (ti.remove_trailing_nott ())
12375 /* Emit this same insn_and_split again. However, the next time it
12376 is split, it will emit the actual negc/movrt insn. This gives
12377 other surrounding insns the chance to see the trailing movrt. */
12379 fprintf (dump_file,
12380 "any_treg_expr_to_reg: replacing trailing nott with movrt\n");
12381 i = emit_insn (gen_any_treg_expr_to_reg (
12382 operands[0], gen_rtx_XOR (SImode, get_t_reg_rtx (),
12387 i = emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
12389 fprintf (dump_file, "any_treg_expr_to_reg: appending movt\n");
12392 add_reg_note (i, REG_UNUSED, get_t_reg_rtx ());
12396 ;; -------------------------------------------------------------------------
12397 ;; Instructions to cope with inline literal tables
12398 ;; -------------------------------------------------------------------------
12400 ;; 2 byte integer in line
12401 (define_insn "consttable_2"
12402 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
12403 (match_operand 1 "" "")]
12407 if (operands[1] != const0_rtx)
12408 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
12411 [(set_attr "length" "2")
12412 (set_attr "in_delay_slot" "no")])
12414 ;; 4 byte integer in line
12415 (define_insn "consttable_4"
12416 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
12417 (match_operand 1 "" "")]
12421 if (operands[1] != const0_rtx)
12423 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
12424 mark_symbol_refs_as_used (operands[0]);
12428 [(set_attr "length" "4")
12429 (set_attr "in_delay_slot" "no")])
12431 ;; 8 byte integer in line
12432 (define_insn "consttable_8"
12433 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
12434 (match_operand 1 "" "")]
12438 if (operands[1] != const0_rtx)
12439 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
12442 [(set_attr "length" "8")
12443 (set_attr "in_delay_slot" "no")])
12445 ;; 4 byte floating point
12446 (define_insn "consttable_sf"
12447 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
12448 (match_operand 1 "" "")]
12452 if (operands[1] != const0_rtx)
12453 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
12454 SFmode, GET_MODE_ALIGNMENT (SFmode));
12457 [(set_attr "length" "4")
12458 (set_attr "in_delay_slot" "no")])
12460 ;; 8 byte floating point
12461 (define_insn "consttable_df"
12462 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
12463 (match_operand 1 "" "")]
12467 if (operands[1] != const0_rtx)
12468 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
12469 DFmode, GET_MODE_ALIGNMENT (DFmode));
12472 [(set_attr "length" "8")
12473 (set_attr "in_delay_slot" "no")])
12475 ;; Alignment is needed for some constant tables; it may also be added for
12476 ;; Instructions at the start of loops, or after unconditional branches.
12477 ;; ??? We would get more accurate lengths if we did instruction
12478 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
12479 ;; here is too conservative.
12481 ;; align to a two byte boundary
12482 (define_expand "align_2"
12483 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
12487 ;; Align to a four byte boundary.
12488 ;; align_4 and align_log are instructions for the starts of loops, or
12489 ;; after unconditional branches, which may take up extra room.
12490 (define_expand "align_4"
12491 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
12495 ;; Align to a cache line boundary.
12496 (define_insn "align_log"
12497 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
12500 [(set_attr "length" "0")
12501 (set_attr "in_delay_slot" "no")])
12503 ;; Emitted at the end of the literal table, used to emit the
12504 ;; 32bit branch labels if needed.
12505 (define_insn "consttable_end"
12506 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
12509 return output_jump_label_table ();
12511 [(set_attr "in_delay_slot" "no")])
12513 ;; Emitted at the end of the window in the literal table.
12514 (define_insn "consttable_window_end"
12515 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
12518 [(set_attr "length" "0")
12519 (set_attr "in_delay_slot" "no")])
12521 ;; -------------------------------------------------------------------------
12522 ;; Minimum / maximum operations.
12523 ;; -------------------------------------------------------------------------
12525 ;; The SH2A clips.b and clips.w insns do a signed min-max function. If smin
12526 ;; and smax standard name patterns are defined, they will be used during
12527 ;; initial expansion and combine will then be able to form the actual min-max
12529 ;; The clips.b and clips.w set the SR.CS bit if the value in the register is
12530 ;; clipped, but there is currently no way of making use of this information.
12531 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
12532 (define_expand "<code>si3"
12533 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
12534 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
12535 (match_operand 2 "const_int_operand")))
12536 (clobber (reg:SI T_REG))])]
12539 /* Force the comparison value into a register, because greater-than
12540 comparisons can work only on registers. Combine will be able to pick up
12541 the constant value from the REG_EQUAL note when trying to form a min-max
12543 operands[2] = force_reg (SImode, operands[2]);
12547 ;; smax (smin (...))
12549 ;; smin (smax (...))
12550 (define_insn_and_split "*clips"
12551 [(set (match_operand:SI 0 "arith_reg_dest")
12552 (smax:SI (smin:SI (match_operand:SI 1 "arith_reg_operand")
12553 (match_operand 2 "clips_max_const_int"))
12554 (match_operand 3 "clips_min_const_int")))]
12558 [(set (match_dup 0)
12559 (smin:SI (smax:SI (match_dup 1) (match_dup 3)) (match_dup 2)))])
12561 (define_insn "*clips"
12562 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12563 (smin:SI (smax:SI (match_operand:SI 1 "arith_reg_operand" "0")
12564 (match_operand 2 "clips_min_const_int"))
12565 (match_operand 3 "clips_max_const_int")))]
12568 if (INTVAL (operands[3]) == 127)
12569 return "clips.b %0";
12570 else if (INTVAL (operands[3]) == 32767)
12571 return "clips.w %0";
12573 gcc_unreachable ();
12575 [(set_attr "type" "arith")])
12577 ;; If the expanded smin or smax patterns were not combined, split them into
12578 ;; a compare and branch sequence, because there are no real smin or smax
12580 (define_insn_and_split "*<code>si3"
12581 [(set (match_operand:SI 0 "arith_reg_dest")
12582 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
12583 (match_operand:SI 2 "arith_reg_or_0_or_1_operand")))
12584 (clobber (reg:SI T_REG))]
12585 "TARGET_SH2A && can_create_pseudo_p ()"
12590 rtx skip_label = gen_label_rtx ();
12591 emit_move_insn (operands[0], operands[1]);
12593 rtx cmp_val = operands[2];
12594 if (satisfies_constraint_M (cmp_val))
12595 cmp_val = const0_rtx;
12597 emit_insn (gen_cmpgtsi_t (operands[0], cmp_val));
12598 emit_jump_insn (<CODE> == SMIN
12599 ? gen_branch_false (skip_label)
12600 : gen_branch_true (skip_label));
12602 emit_label_after (skip_label, emit_move_insn (operands[0], operands[2]));
12606 ;; The SH2A clipu.b and clipu.w insns can be used to implement a min function
12607 ;; with a register and a constant.
12608 ;; The clipu.b and clipu.w set the SR.CS bit if the value in the register is
12609 ;; clipped, but there is currently no way of making use of this information.
12610 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
12611 (define_expand "uminsi3"
12612 [(set (match_operand:SI 0 "arith_reg_dest")
12613 (umin:SI (match_operand:SI 1 "arith_reg_operand")
12614 (match_operand 2 "const_int_operand")))]
12617 if (INTVAL (operands[2]) == 1)
12619 emit_insn (gen_clipu_one (operands[0], operands[1]));
12622 else if (! clipu_max_const_int (operands[2], VOIDmode))
12626 (define_insn "*clipu"
12627 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12628 (umin:SI (match_operand:SI 1 "arith_reg_operand" "0")
12629 (match_operand 2 "clipu_max_const_int")))]
12632 if (INTVAL (operands[2]) == 255)
12633 return "clipu.b %0";
12634 else if (INTVAL (operands[2]) == 65535)
12635 return "clipu.w %0";
12637 gcc_unreachable ();
12639 [(set_attr "type" "arith")])
12641 (define_insn_and_split "clipu_one"
12642 [(set (match_operand:SI 0 "arith_reg_dest")
12643 (umin:SI (match_operand:SI 1 "arith_reg_operand") (const_int 1)))
12644 (clobber (reg:SI T_REG))]
12647 "&& can_create_pseudo_p ()"
12650 emit_insn (gen_cmpeqsi_t (operands[1], const0_rtx));
12651 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
12655 ;; -------------------------------------------------------------------------
12657 ;; -------------------------------------------------------------------------
12659 ;; String/block move insn.
12661 (define_expand "movmemsi"
12662 [(parallel [(set (mem:BLK (match_operand:BLK 0))
12663 (mem:BLK (match_operand:BLK 1)))
12664 (use (match_operand:SI 2 "nonmemory_operand"))
12665 (use (match_operand:SI 3 "immediate_operand"))
12666 (clobber (reg:SI PR_REG))
12667 (clobber (reg:SI R4_REG))
12668 (clobber (reg:SI R5_REG))
12669 (clobber (reg:SI R0_REG))])]
12670 "TARGET_SH1 && ! TARGET_SH5"
12672 if (expand_block_move (operands))
12678 (define_insn "block_move_real"
12679 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12680 (mem:BLK (reg:SI R5_REG)))
12681 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12682 (clobber (reg:SI PR_REG))
12683 (clobber (reg:SI R0_REG))])]
12684 "TARGET_SH1 && ! TARGET_HARD_SH4"
12686 [(set_attr "type" "sfunc")
12687 (set_attr "needs_delay_slot" "yes")])
12689 (define_insn "block_lump_real"
12690 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12691 (mem:BLK (reg:SI R5_REG)))
12692 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12693 (use (reg:SI R6_REG))
12694 (clobber (reg:SI PR_REG))
12695 (clobber (reg:SI T_REG))
12696 (clobber (reg:SI R4_REG))
12697 (clobber (reg:SI R5_REG))
12698 (clobber (reg:SI R6_REG))
12699 (clobber (reg:SI R0_REG))])]
12700 "TARGET_SH1 && ! TARGET_HARD_SH4"
12702 [(set_attr "type" "sfunc")
12703 (set_attr "needs_delay_slot" "yes")])
12705 (define_insn "block_move_real_i4"
12706 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12707 (mem:BLK (reg:SI R5_REG)))
12708 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12709 (clobber (reg:SI PR_REG))
12710 (clobber (reg:SI R0_REG))
12711 (clobber (reg:SI R1_REG))
12712 (clobber (reg:SI R2_REG))])]
12715 [(set_attr "type" "sfunc")
12716 (set_attr "needs_delay_slot" "yes")])
12718 (define_insn "block_lump_real_i4"
12719 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12720 (mem:BLK (reg:SI R5_REG)))
12721 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12722 (use (reg:SI R6_REG))
12723 (clobber (reg:SI PR_REG))
12724 (clobber (reg:SI T_REG))
12725 (clobber (reg:SI R4_REG))
12726 (clobber (reg:SI R5_REG))
12727 (clobber (reg:SI R6_REG))
12728 (clobber (reg:SI R0_REG))
12729 (clobber (reg:SI R1_REG))
12730 (clobber (reg:SI R2_REG))
12731 (clobber (reg:SI R3_REG))])]
12734 [(set_attr "type" "sfunc")
12735 (set_attr "needs_delay_slot" "yes")])
12737 ;; byte compare pattern
12739 ;; !((temp & 0xF000) && (temp & 0x0F00) && (temp & 0x00F0) && (temp & 0x000F))
12740 (define_insn "cmpstr_t"
12741 [(set (reg:SI T_REG)
12746 (xor:SI (match_operand:SI 0 "arith_reg_operand" "r")
12747 (match_operand:SI 1 "arith_reg_operand" "r"))
12748 (const_int 8) (const_int 0))
12749 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12750 (const_int 8) (const_int 8)))
12751 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12752 (const_int 8) (const_int 16)))
12753 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12754 (const_int 8) (const_int 24)))
12758 [(set_attr "type" "mt_group")])
12760 (define_expand "cmpstrsi"
12761 [(set (match_operand:SI 0 "register_operand")
12762 (compare:SI (match_operand:BLK 1 "memory_operand")
12763 (match_operand:BLK 2 "memory_operand")))
12764 (use (match_operand 3 "immediate_operand"))]
12765 "TARGET_SH1 && optimize"
12767 if (! optimize_insn_for_size_p () && sh_expand_cmpstr (operands))
12773 (define_expand "cmpstrnsi"
12774 [(set (match_operand:SI 0 "register_operand")
12775 (compare:SI (match_operand:BLK 1 "memory_operand")
12776 (match_operand:BLK 2 "memory_operand")))
12777 (use (match_operand:SI 3 "nonmemory_operand"))
12778 (use (match_operand:SI 4 "immediate_operand"))]
12779 "TARGET_SH1 && optimize"
12781 if (! optimize_insn_for_size_p () && sh_expand_cmpnstr (operands))
12787 (define_expand "strlensi"
12788 [(set (match_operand:SI 0 "register_operand")
12789 (unspec:SI [(match_operand:BLK 1 "memory_operand")
12790 (match_operand:SI 2 "immediate_operand")
12791 (match_operand:SI 3 "immediate_operand")]
12792 UNSPEC_BUILTIN_STRLEN))]
12793 "TARGET_SH1 && optimize"
12795 if (! optimize_insn_for_size_p () && sh_expand_strlen (operands))
12801 (define_expand "setmemqi"
12802 [(parallel [(set (match_operand:BLK 0 "memory_operand")
12803 (match_operand 2 "const_int_operand"))
12804 (use (match_operand:QI 1 "const_int_operand"))
12805 (use (match_operand:QI 3 "const_int_operand"))])]
12806 "TARGET_SH1 && optimize"
12808 if (optimize_insn_for_size_p ())
12811 sh_expand_setmem (operands);
12816 ;; -------------------------------------------------------------------------
12817 ;; Floating point instructions.
12818 ;; -------------------------------------------------------------------------
12820 ;; FIXME: For now we disallow any memory operands for fpscr loads/stores,
12821 ;; except for post-inc loads and pre-dec stores for push/pop purposes.
12822 ;; This avoids problems with reload. As a consequence, user initiated fpscr
12823 ;; stores to memory will always be ferried through a general register.
12824 ;; User initiated fpscr loads always have to undergo bit masking to preserve
12825 ;; the current fpu mode settings for the compiler generated code. Thus such
12826 ;; fpscr loads will always have to go through general registers anyways.
12827 (define_insn "lds_fpscr"
12828 [(set (reg:SI FPSCR_REG)
12829 (match_operand:SI 0 "fpscr_movsrc_operand" "r,>"))
12830 (set (reg:SI FPSCR_STAT_REG)
12831 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_STAT))
12832 (set (reg:SI FPSCR_MODES_REG)
12833 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12838 [(set_attr "type" "gp_fpscr,mem_fpscr")])
12840 ;; A move fpscr -> reg schedules like a move mac -> reg. Thus we use mac_gp
12842 (define_insn "sts_fpscr"
12843 [(set (match_operand:SI 0 "fpscr_movdst_operand" "=r,<")
12844 (reg:SI FPSCR_REG))
12845 (use (reg:SI FPSCR_STAT_REG))
12846 (use (reg:SI FPSCR_MODES_REG))]
12851 [(set_attr "type" "mac_gp,fstore")])
12853 (define_expand "set_fpscr"
12854 [(parallel [(set (reg:SI FPSCR_REG)
12855 (match_operand:SI 0 "general_operand"))
12856 (set (reg:SI FPSCR_STAT_REG)
12857 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))])]
12860 /* We have to mask out the FR, SZ and PR bits. To do that, we need to
12861 get the current FPSCR value first.
12862 (a & ~mask) | (b & mask) = a ^ ((a ^ b) & mask) */
12864 rtx mask = force_reg (SImode, GEN_INT (FPSCR_FR | FPSCR_SZ | FPSCR_PR));
12866 rtx a = force_reg (SImode, operands[0]);
12868 rtx b = gen_reg_rtx (SImode);
12869 emit_insn (gen_sts_fpscr (b));
12871 rtx a_xor_b = gen_reg_rtx (SImode);
12872 emit_insn (gen_xorsi3 (a_xor_b, a, b));
12874 rtx a_xor_b_and_mask = gen_reg_rtx (SImode);
12875 emit_insn (gen_andsi3 (a_xor_b_and_mask, a_xor_b, mask));
12877 rtx r = gen_reg_rtx (SImode);
12878 emit_insn (gen_xorsi3 (r, a_xor_b_and_mask, a));
12879 emit_insn (gen_lds_fpscr (r));
12884 ;; ??? This uses the fp unit, but has no type indicating that.
12885 ;; If we did that, this would either give a bogus latency or introduce
12886 ;; a bogus FIFO constraint.
12887 ;; Since this insn is currently only used for prologues/epilogues,
12888 ;; it is probably best to claim no function unit, which matches the
12889 ;; current setting.
12890 (define_insn "toggle_sz"
12891 [(set (reg:SI FPSCR_REG)
12892 (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_SZ)))
12893 (set (reg:SI FPSCR_MODES_REG)
12894 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12895 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12897 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
12899 ;; Toggle FPU precision PR mode.
12901 (define_insn "toggle_pr"
12902 [(set (reg:SI FPSCR_REG)
12903 (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_PR)))
12904 (set (reg:SI FPSCR_MODES_REG)
12905 (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))]
12908 [(set_attr "type" "fpscr_toggle")])
12910 (define_expand "addsf3"
12911 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12912 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand")
12913 (match_operand:SF 2 "fp_arith_reg_operand")))]
12914 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12918 emit_insn (gen_addsf3_i (operands[0], operands[1], operands[2]));
12923 (define_insn "*addsf3_media"
12924 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12925 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12926 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12927 "TARGET_SHMEDIA_FPU"
12928 "fadd.s %1, %2, %0"
12929 [(set_attr "type" "fparith_media")])
12931 (define_insn_and_split "unary_sf_op"
12932 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12937 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
12938 (match_operator:SF 2 "unary_float_operator"
12939 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12940 (parallel [(match_operand 4
12941 "const_int_operand" "n")]))]))
12942 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
12943 "TARGET_SHMEDIA_FPU"
12945 "TARGET_SHMEDIA_FPU && reload_completed"
12946 [(set (match_dup 5) (match_dup 6))]
12948 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12949 rtx op1 = gen_rtx_REG (SFmode,
12950 (true_regnum (operands[1])
12951 + (INTVAL (operands[4]) ^ endian)));
12953 operands[7] = gen_rtx_REG (SFmode,
12954 (true_regnum (operands[0])
12955 + (INTVAL (operands[3]) ^ endian)));
12956 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
12958 [(set_attr "type" "fparith_media")])
12960 (define_insn_and_split "binary_sf_op0"
12961 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12963 (match_operator:SF 3 "binary_float_operator"
12964 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12965 (parallel [(const_int 0)]))
12966 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12967 (parallel [(const_int 0)]))])
12970 (parallel [(const_int 1)]))))]
12971 "TARGET_SHMEDIA_FPU"
12973 "&& reload_completed"
12974 [(set (match_dup 4) (match_dup 5))]
12976 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12977 rtx op1 = gen_rtx_REG (SFmode,
12978 true_regnum (operands[1]) + endian);
12979 rtx op2 = gen_rtx_REG (SFmode,
12980 true_regnum (operands[2]) + endian);
12982 operands[4] = gen_rtx_REG (SFmode,
12983 true_regnum (operands[0]) + endian);
12984 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12986 [(set_attr "type" "fparith_media")])
12988 (define_insn_and_split "binary_sf_op1"
12989 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12993 (parallel [(const_int 0)]))
12994 (match_operator:SF 3 "binary_float_operator"
12995 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12996 (parallel [(const_int 1)]))
12997 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12998 (parallel [(const_int 1)]))])))]
12999 "TARGET_SHMEDIA_FPU"
13001 "&& reload_completed"
13002 [(set (match_dup 4) (match_dup 5))]
13004 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
13005 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
13006 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
13008 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
13009 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
13011 [(set_attr "type" "fparith_media")])
13013 (define_insn "addsf3_i"
13014 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13015 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
13016 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
13017 (clobber (reg:SI FPSCR_STAT_REG))
13018 (use (reg:SI FPSCR_MODES_REG))]
13021 [(set_attr "type" "fp")
13022 (set_attr "fp_mode" "single")])
13024 (define_expand "subsf3"
13025 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
13026 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
13027 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
13028 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13032 emit_insn (gen_subsf3_i (operands[0], operands[1], operands[2]));
13037 (define_insn "*subsf3_media"
13038 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13039 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
13040 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13041 "TARGET_SHMEDIA_FPU"
13042 "fsub.s %1, %2, %0"
13043 [(set_attr "type" "fparith_media")])
13045 (define_insn "subsf3_i"
13046 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13047 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
13048 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
13049 (clobber (reg:SI FPSCR_STAT_REG))
13050 (use (reg:SI FPSCR_MODES_REG))]
13053 [(set_attr "type" "fp")
13054 (set_attr "fp_mode" "single")])
13056 (define_expand "mulsf3"
13057 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
13058 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
13059 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
13060 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13064 emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2]));
13069 (define_insn "*mulsf3_media"
13070 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13071 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
13072 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13073 "TARGET_SHMEDIA_FPU"
13074 "fmul.s %1, %2, %0"
13075 [(set_attr "type" "fparith_media")])
13077 (define_insn "mulsf3_i"
13078 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13079 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
13080 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
13081 (clobber (reg:SI FPSCR_STAT_REG))
13082 (use (reg:SI FPSCR_MODES_REG))]
13085 [(set_attr "type" "fp")
13086 (set_attr "fp_mode" "single")])
13088 ;; FMA (fused multiply-add) patterns
13089 (define_expand "fmasf4"
13090 [(set (match_operand:SF 0 "fp_arith_reg_operand")
13091 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand")
13092 (match_operand:SF 2 "fp_arith_reg_operand")
13093 (match_operand:SF 3 "fp_arith_reg_operand")))]
13094 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13098 emit_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
13104 (define_insn "fmasf4_i"
13105 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13106 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
13107 (match_operand:SF 2 "fp_arith_reg_operand" "f")
13108 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
13109 (clobber (reg:SI FPSCR_STAT_REG))
13110 (use (reg:SI FPSCR_MODES_REG))]
13113 [(set_attr "type" "fp")
13114 (set_attr "fp_mode" "single")])
13116 (define_insn "fmasf4_media"
13117 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13118 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
13119 (match_operand:SF 2 "fp_arith_reg_operand" "f")
13120 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
13121 "TARGET_SHMEDIA_FPU"
13122 "fmac.s %1, %2, %0"
13123 [(set_attr "type" "fparith_media")])
13125 ;; For some cases such as 'a * b + a' the FMA pattern is not generated by
13126 ;; previous transformations. If FMA is generally allowed, let the combine
13127 ;; pass utilize it.
13128 (define_insn_and_split "*fmasf4"
13129 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13130 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
13131 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
13132 (match_operand:SF 3 "arith_reg_operand" "0")))
13133 (clobber (reg:SI FPSCR_STAT_REG))
13134 (use (reg:SI FPSCR_MODES_REG))]
13135 "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF"
13137 "&& can_create_pseudo_p ()"
13138 [(parallel [(set (match_dup 0)
13139 (fma:SF (match_dup 1) (match_dup 2) (match_dup 3)))
13140 (clobber (reg:SI FPSCR_STAT_REG))
13141 (use (reg:SI FPSCR_MODES_REG))])]
13143 /* Change 'b * a + a' into 'a * b + a'.
13144 This is better for register allocation. */
13145 if (REGNO (operands[2]) == REGNO (operands[3]))
13146 std::swap (operands[1], operands[2]);
13148 [(set_attr "type" "fp")
13149 (set_attr "fp_mode" "single")])
13151 (define_insn "*fmasf4_media"
13152 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13153 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
13154 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
13155 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
13156 "TARGET_SHMEDIA_FPU && flag_fp_contract_mode != FP_CONTRACT_OFF"
13157 "fmac.s %1, %2, %0"
13158 [(set_attr "type" "fparith_media")])
13160 (define_expand "divsf3"
13161 [(set (match_operand:SF 0 "fp_arith_reg_operand")
13162 (div:SF (match_operand:SF 1 "fp_arith_reg_operand")
13163 (match_operand:SF 2 "fp_arith_reg_operand")))]
13164 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13168 emit_insn (gen_divsf3_i (operands[0], operands[1], operands[2]));
13173 (define_insn "*divsf3_media"
13174 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13175 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
13176 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13177 "TARGET_SHMEDIA_FPU"
13178 "fdiv.s %1, %2, %0"
13179 [(set_attr "type" "fdiv_media")])
13181 (define_insn "divsf3_i"
13182 [(set (match_operand:SF 0 "fp_arith_reg_dest" "=f")
13183 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
13184 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
13185 (clobber (reg:SI FPSCR_STAT_REG))
13186 (use (reg:SI FPSCR_MODES_REG))]
13189 [(set_attr "type" "fdiv")
13190 (set_attr "fp_mode" "single")])
13192 (define_insn "floatdisf2"
13193 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13194 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
13195 "TARGET_SHMEDIA_FPU"
13197 [(set_attr "type" "fpconv_media")])
13199 (define_expand "floatsisf2"
13200 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
13201 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
13202 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13204 if (!TARGET_SHMEDIA_FPU)
13206 emit_insn (gen_floatsisf2_i4 (operands[0], operands[1]));
13211 (define_insn "*floatsisf2_media"
13212 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13213 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
13214 "TARGET_SHMEDIA_FPU"
13216 [(set_attr "type" "fpconv_media")])
13218 (define_insn "floatsisf2_i4"
13219 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13220 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
13221 (clobber (reg:SI FPSCR_STAT_REG))
13222 (use (reg:SI FPSCR_MODES_REG))]
13225 [(set_attr "type" "fp")
13226 (set_attr "fp_mode" "single")])
13228 (define_insn "fix_truncsfdi2"
13229 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
13230 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13231 "TARGET_SHMEDIA_FPU"
13233 [(set_attr "type" "fpconv_media")])
13235 (define_expand "fix_truncsfsi2"
13236 [(set (match_operand:SI 0 "fpul_operand" "=y")
13237 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13238 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13240 if (!TARGET_SHMEDIA_FPU)
13242 emit_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1]));
13247 (define_insn "*fix_truncsfsi2_media"
13248 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
13249 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13250 "TARGET_SHMEDIA_FPU"
13252 [(set_attr "type" "fpconv_media")])
13254 (define_insn "fix_truncsfsi2_i4"
13255 [(set (match_operand:SI 0 "fpul_operand" "=y")
13256 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
13257 (clobber (reg:SI FPSCR_STAT_REG))
13258 (use (reg:SI FPSCR_MODES_REG))]
13261 [(set_attr "type" "ftrc_s")
13262 (set_attr "fp_mode" "single")])
13264 (define_insn "cmpgtsf_t"
13265 [(set (reg:SI T_REG)
13266 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
13267 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
13268 (clobber (reg:SI FPSCR_STAT_REG))
13269 (use (reg:SI FPSCR_MODES_REG))]
13270 "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE"
13272 [(set_attr "type" "fp_cmp")
13273 (set_attr "fp_mode" "single")])
13275 (define_insn "cmpeqsf_t"
13276 [(set (reg:SI T_REG)
13277 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
13278 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
13279 (clobber (reg:SI FPSCR_STAT_REG))
13280 (use (reg:SI FPSCR_MODES_REG))]
13281 "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE"
13283 [(set_attr "type" "fp_cmp")
13284 (set_attr "fp_mode" "single")])
13286 (define_insn "ieee_ccmpeqsf_t"
13287 [(set (reg:SI T_REG)
13288 (ior:SI (reg:SI T_REG)
13289 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
13290 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
13291 (clobber (reg:SI FPSCR_STAT_REG))
13292 (use (reg:SI FPSCR_MODES_REG))]
13293 "TARGET_IEEE && TARGET_SH2E"
13295 return output_ieee_ccmpeq (insn, operands);
13297 [(set_attr "length" "4")
13298 (set_attr "fp_mode" "single")])
13300 (define_insn "cmpeqsf_media"
13301 [(set (match_operand:SI 0 "register_operand" "=r")
13302 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
13303 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13304 "TARGET_SHMEDIA_FPU"
13305 "fcmpeq.s %1, %2, %0"
13306 [(set_attr "type" "fcmp_media")])
13308 (define_insn "cmpgtsf_media"
13309 [(set (match_operand:SI 0 "register_operand" "=r")
13310 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
13311 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13312 "TARGET_SHMEDIA_FPU"
13313 "fcmpgt.s %1, %2, %0"
13314 [(set_attr "type" "fcmp_media")])
13316 (define_insn "cmpgesf_media"
13317 [(set (match_operand:SI 0 "register_operand" "=r")
13318 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
13319 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13320 "TARGET_SHMEDIA_FPU"
13321 "fcmpge.s %1, %2, %0"
13322 [(set_attr "type" "fcmp_media")])
13324 (define_insn "cmpunsf_media"
13325 [(set (match_operand:SI 0 "register_operand" "=r")
13326 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
13327 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
13328 "TARGET_SHMEDIA_FPU"
13329 "fcmpun.s %1, %2, %0"
13330 [(set_attr "type" "fcmp_media")])
13332 (define_expand "cbranchsf4"
13334 (if_then_else (match_operator 0 "sh_float_comparison_operator"
13335 [(match_operand:SF 1 "arith_operand" "")
13336 (match_operand:SF 2 "arith_operand" "")])
13337 (match_operand 3 "" "")
13339 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
13341 if (TARGET_SHMEDIA)
13342 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
13345 sh_emit_compare_and_branch (operands, SFmode);
13349 (define_expand "negsf2"
13350 [(set (match_operand:SF 0 "fp_arith_reg_operand")
13351 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand")))]
13352 "TARGET_SH2E || TARGET_SHMEDIA_FPU")
13354 (define_insn "*negsf2_media"
13355 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13356 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13357 "TARGET_SHMEDIA_FPU"
13359 [(set_attr "type" "fmove_media")])
13361 (define_insn "*negsf2_i"
13362 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13363 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))]
13366 [(set_attr "type" "fmove")])
13368 (define_expand "sqrtsf2"
13369 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
13370 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
13371 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
13375 emit_insn (gen_sqrtsf2_i (operands[0], operands[1]));
13380 (define_insn "*sqrtsf2_media"
13381 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13382 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13383 "TARGET_SHMEDIA_FPU"
13385 [(set_attr "type" "fdiv_media")])
13387 (define_insn "sqrtsf2_i"
13388 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13389 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
13390 (clobber (reg:SI FPSCR_STAT_REG))
13391 (use (reg:SI FPSCR_MODES_REG))]
13394 [(set_attr "type" "fdiv")
13395 (set_attr "fp_mode" "single")])
13397 (define_insn "rsqrtsf2"
13398 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13399 (div:SF (match_operand:SF 1 "immediate_operand" "i")
13400 (sqrt:SF (match_operand:SF 2 "fp_arith_reg_operand" "0"))))
13401 (clobber (reg:SI FPSCR_STAT_REG))
13402 (use (reg:SI FPSCR_MODES_REG))]
13403 "TARGET_FPU_ANY && TARGET_FSRRA
13404 && operands[1] == CONST1_RTX (SFmode)"
13406 [(set_attr "type" "fsrra")
13407 (set_attr "fp_mode" "single")])
13409 ;; When the sincos pattern is defined, the builtin functions sin and cos
13410 ;; will be expanded to the sincos pattern and one of the output values will
13412 (define_expand "sincossf3"
13413 [(set (match_operand:SF 0 "nonimmediate_operand")
13414 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
13415 (set (match_operand:SF 1 "nonimmediate_operand")
13416 (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
13417 "TARGET_FPU_ANY && TARGET_FSCA"
13419 rtx scaled = gen_reg_rtx (SFmode);
13420 rtx truncated = gen_reg_rtx (SImode);
13421 rtx fsca = gen_reg_rtx (V2SFmode);
13422 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
13424 emit_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
13425 emit_insn (gen_fix_truncsfsi2 (truncated, scaled));
13426 emit_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf ()));
13428 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
13429 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
13433 (define_insn_and_split "fsca"
13434 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
13436 (unspec:SF [(mult:SF
13437 (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
13438 (match_operand:SF 2 "fsca_scale_factor" "i"))
13440 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
13442 (clobber (reg:SI FPSCR_STAT_REG))
13443 (use (reg:SI FPSCR_MODES_REG))]
13444 "TARGET_FPU_ANY && TARGET_FSCA"
13446 "&& !fpul_operand (operands[1], SImode)"
13449 /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
13450 to a simple reg, otherwise reload will have trouble reloading the
13451 pseudo into fpul. */
13452 rtx x = XEXP (operands[1], 0);
13453 while (x != NULL_RTX && !fpul_operand (x, SImode))
13455 gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
13458 gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
13459 emit_insn (gen_fsca (operands[0], x, operands[2]));
13462 [(set_attr "type" "fsca")
13463 (set_attr "fp_mode" "single")])
13465 (define_expand "abssf2"
13466 [(set (match_operand:SF 0 "fp_arith_reg_operand")
13467 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand")))]
13468 "TARGET_SH2E || TARGET_SHMEDIA_FPU")
13470 (define_insn "*abssf2_media"
13471 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13472 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13473 "TARGET_SHMEDIA_FPU"
13475 [(set_attr "type" "fmove_media")])
13477 (define_insn "*abssf2_i"
13478 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13479 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))]
13482 [(set_attr "type" "fmove")])
13484 (define_expand "adddf3"
13485 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13486 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
13487 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
13488 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13490 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13492 emit_insn (gen_adddf3_i (operands[0], operands[1], operands[2]));
13497 (define_insn "*adddf3_media"
13498 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13499 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
13500 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13501 "TARGET_SHMEDIA_FPU"
13502 "fadd.d %1, %2, %0"
13503 [(set_attr "type" "dfparith_media")])
13505 (define_insn "adddf3_i"
13506 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13507 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
13508 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13509 (clobber (reg:SI FPSCR_STAT_REG))
13510 (use (reg:SI FPSCR_MODES_REG))]
13511 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13513 [(set_attr "type" "dfp_arith")
13514 (set_attr "fp_mode" "double")])
13516 (define_expand "subdf3"
13517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13518 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
13519 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
13520 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13522 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13524 emit_insn (gen_subdf3_i (operands[0], operands[1], operands[2]));
13529 (define_insn "*subdf3_media"
13530 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13531 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
13532 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13533 "TARGET_SHMEDIA_FPU"
13534 "fsub.d %1, %2, %0"
13535 [(set_attr "type" "dfparith_media")])
13537 (define_insn "subdf3_i"
13538 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13539 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
13540 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13541 (clobber (reg:SI FPSCR_STAT_REG))
13542 (use (reg:SI FPSCR_MODES_REG))]
13543 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13545 [(set_attr "type" "dfp_arith")
13546 (set_attr "fp_mode" "double")])
13548 (define_expand "muldf3"
13549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13550 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
13551 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
13552 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13554 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13556 emit_insn (gen_muldf3_i (operands[0], operands[1], operands[2]));
13561 (define_insn "*muldf3_media"
13562 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13563 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
13564 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13565 "TARGET_SHMEDIA_FPU"
13566 "fmul.d %1, %2, %0"
13567 [(set_attr "type" "dfmul_media")])
13569 (define_insn "muldf3_i"
13570 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13571 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
13572 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13573 (clobber (reg:SI FPSCR_STAT_REG))
13574 (use (reg:SI FPSCR_MODES_REG))]
13575 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13577 [(set_attr "type" "dfp_mul")
13578 (set_attr "fp_mode" "double")])
13580 (define_expand "divdf3"
13581 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13582 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
13583 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
13584 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13586 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13588 emit_insn (gen_divdf3_i (operands[0], operands[1], operands[2]));
13593 (define_insn "*divdf3_media"
13594 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13595 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
13596 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13597 "TARGET_SHMEDIA_FPU"
13598 "fdiv.d %1, %2, %0"
13599 [(set_attr "type" "dfdiv_media")])
13601 (define_insn "divdf3_i"
13602 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13603 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
13604 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
13605 (clobber (reg:SI FPSCR_STAT_REG))
13606 (use (reg:SI FPSCR_MODES_REG))]
13607 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13609 [(set_attr "type" "dfdiv")
13610 (set_attr "fp_mode" "double")])
13612 (define_insn "floatdidf2"
13613 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13614 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
13615 "TARGET_SHMEDIA_FPU"
13617 [(set_attr "type" "dfpconv_media")])
13619 (define_expand "floatsidf2"
13620 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13621 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
13622 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13624 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13626 emit_insn (gen_floatsidf2_i (operands[0], operands[1]));
13631 (define_insn "*floatsidf2_media"
13632 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13633 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
13634 "TARGET_SHMEDIA_FPU"
13636 [(set_attr "type" "dfpconv_media")])
13638 (define_insn "floatsidf2_i"
13639 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13640 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
13641 (clobber (reg:SI FPSCR_STAT_REG))
13642 (use (reg:SI FPSCR_MODES_REG))]
13643 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13645 [(set_attr "type" "dfp_conv")
13646 (set_attr "fp_mode" "double")])
13648 (define_insn "fix_truncdfdi2"
13649 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
13650 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13651 "TARGET_SHMEDIA_FPU"
13653 [(set_attr "type" "dfpconv_media")])
13655 (define_expand "fix_truncdfsi2"
13656 [(set (match_operand:SI 0 "fpul_operand" "")
13657 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13658 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13660 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13662 emit_insn (gen_fix_truncdfsi2_i (operands[0], operands[1]));
13667 (define_insn "*fix_truncdfsi2_media"
13668 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
13669 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13670 "TARGET_SHMEDIA_FPU"
13672 [(set_attr "type" "dfpconv_media")])
13674 (define_insn "fix_truncdfsi2_i"
13675 [(set (match_operand:SI 0 "fpul_operand" "=y")
13676 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13677 (clobber (reg:SI FPSCR_STAT_REG))
13678 (use (reg:SI FPSCR_MODES_REG))]
13679 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13681 [(set_attr "type" "dfp_conv")
13682 (set_attr "dfp_comp" "no")
13683 (set_attr "fp_mode" "double")])
13685 (define_insn "cmpgtdf_t"
13686 [(set (reg:SI T_REG)
13687 (gt:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13688 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13689 (clobber (reg:SI FPSCR_STAT_REG))
13690 (use (reg:SI FPSCR_MODES_REG))]
13691 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13693 [(set_attr "type" "dfp_cmp")
13694 (set_attr "fp_mode" "double")])
13696 (define_insn "cmpeqdf_t"
13697 [(set (reg:SI T_REG)
13698 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13699 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13700 (clobber (reg:SI FPSCR_STAT_REG))
13701 (use (reg:SI FPSCR_MODES_REG))]
13702 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13704 [(set_attr "type" "dfp_cmp")
13705 (set_attr "fp_mode" "double")])
13707 (define_insn "*ieee_ccmpeqdf_t"
13708 [(set (reg:SI T_REG)
13709 (ior:SI (reg:SI T_REG)
13710 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13711 (match_operand:DF 1 "fp_arith_reg_operand" "f"))))
13712 (clobber (reg:SI FPSCR_STAT_REG))
13713 (use (reg:SI FPSCR_MODES_REG))]
13714 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13716 return output_ieee_ccmpeq (insn, operands);
13718 [(set_attr "length" "4")
13719 (set_attr "fp_mode" "double")])
13721 (define_insn "cmpeqdf_media"
13722 [(set (match_operand:SI 0 "register_operand" "=r")
13723 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13724 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13725 "TARGET_SHMEDIA_FPU"
13726 "fcmpeq.d %1,%2,%0"
13727 [(set_attr "type" "fcmp_media")])
13729 (define_insn "cmpgtdf_media"
13730 [(set (match_operand:SI 0 "register_operand" "=r")
13731 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13732 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13733 "TARGET_SHMEDIA_FPU"
13734 "fcmpgt.d %1,%2,%0"
13735 [(set_attr "type" "fcmp_media")])
13737 (define_insn "cmpgedf_media"
13738 [(set (match_operand:SI 0 "register_operand" "=r")
13739 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13740 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13741 "TARGET_SHMEDIA_FPU"
13742 "fcmpge.d %1,%2,%0"
13743 [(set_attr "type" "fcmp_media")])
13745 (define_insn "cmpundf_media"
13746 [(set (match_operand:SI 0 "register_operand" "=r")
13747 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13748 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13749 "TARGET_SHMEDIA_FPU"
13750 "fcmpun.d %1,%2,%0"
13751 [(set_attr "type" "fcmp_media")])
13753 (define_expand "cbranchdf4"
13755 (if_then_else (match_operator 0 "sh_float_comparison_operator"
13756 [(match_operand:DF 1 "arith_operand" "")
13757 (match_operand:DF 2 "arith_operand" "")])
13758 (match_operand 3 "" "")
13760 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13762 if (TARGET_SHMEDIA)
13763 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
13766 sh_emit_compare_and_branch (operands, DFmode);
13770 (define_expand "negdf2"
13771 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13772 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13773 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU")
13775 (define_insn "*negdf2_media"
13776 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13777 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13778 "TARGET_SHMEDIA_FPU"
13780 [(set_attr "type" "fmove_media")])
13782 (define_insn "*negdf2_i"
13783 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13784 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))]
13785 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13787 [(set_attr "type" "fmove")])
13789 (define_expand "sqrtdf2"
13790 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13791 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13792 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13794 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13796 emit_insn (gen_sqrtdf2_i (operands[0], operands[1]));
13801 (define_insn "*sqrtdf2_media"
13802 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13803 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13804 "TARGET_SHMEDIA_FPU"
13806 [(set_attr "type" "dfdiv_media")])
13808 (define_insn "sqrtdf2_i"
13809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13810 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
13811 (clobber (reg:SI FPSCR_STAT_REG))
13812 (use (reg:SI FPSCR_MODES_REG))]
13813 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13815 [(set_attr "type" "dfdiv")
13816 (set_attr "fp_mode" "double")])
13818 (define_expand "absdf2"
13819 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13820 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13821 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU")
13823 (define_insn "*absdf2_media"
13824 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13825 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13826 "TARGET_SHMEDIA_FPU"
13828 [(set_attr "type" "fmove_media")])
13830 (define_insn "*absdf2_i"
13831 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13832 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))]
13833 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13835 [(set_attr "type" "fmove")])
13837 (define_expand "extendsfdf2"
13838 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13839 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
13840 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13842 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13844 emit_insn (gen_extendsfdf2_i4 (operands[0], operands[1]));
13849 (define_insn "*extendsfdf2_media"
13850 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13851 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13852 "TARGET_SHMEDIA_FPU"
13854 [(set_attr "type" "dfpconv_media")])
13856 (define_insn "extendsfdf2_i4"
13857 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13858 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
13859 (clobber (reg:SI FPSCR_STAT_REG))
13860 (use (reg:SI FPSCR_MODES_REG))]
13861 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13863 [(set_attr "type" "fp")
13864 (set_attr "fp_mode" "double")])
13866 (define_expand "truncdfsf2"
13867 [(set (match_operand:SF 0 "fpul_operand" "")
13868 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13869 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13871 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13873 emit_insn (gen_truncdfsf2_i4 (operands[0], operands[1]));
13878 (define_insn "*truncdfsf2_media"
13879 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13880 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13881 "TARGET_SHMEDIA_FPU"
13883 [(set_attr "type" "dfpconv_media")])
13885 (define_insn "truncdfsf2_i4"
13886 [(set (match_operand:SF 0 "fpul_operand" "=y")
13887 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13888 (clobber (reg:SI FPSCR_STAT_REG))
13889 (use (reg:SI FPSCR_MODES_REG))]
13890 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13892 [(set_attr "type" "fp")
13893 (set_attr "fp_mode" "double")])
13895 ;; -------------------------------------------------------------------------
13896 ;; Bit field extract patterns.
13897 ;; -------------------------------------------------------------------------
13899 ;; These give better code for packed bitfields, because they allow
13900 ;; auto-increment addresses to be generated.
13902 (define_expand "insv"
13903 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
13904 (match_operand:SI 1 "immediate_operand" "")
13905 (match_operand:SI 2 "immediate_operand" ""))
13906 (match_operand:SI 3 "general_operand" ""))]
13907 "TARGET_SH1 && TARGET_BIG_ENDIAN"
13909 rtx addr_target, orig_address, shift_reg, qi_val;
13910 HOST_WIDE_INT bitsize, size, v = 0;
13911 rtx x = operands[3];
13913 if (TARGET_SH2A && TARGET_BITOPS
13914 && (satisfies_constraint_Sbw (operands[0])
13915 || satisfies_constraint_Sbv (operands[0]))
13916 && satisfies_constraint_M (operands[1])
13917 && satisfies_constraint_K03 (operands[2]))
13919 if (satisfies_constraint_N (operands[3]))
13921 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
13924 else if (satisfies_constraint_M (operands[3]))
13926 emit_insn (gen_bset_m2a (operands[0], operands[2]));
13929 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
13930 && satisfies_constraint_M (operands[1]))
13932 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13935 else if (REG_P (operands[3])
13936 && satisfies_constraint_M (operands[1]))
13938 emit_insn (gen_bldsi_reg (operands[3], const0_rtx));
13939 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13943 /* ??? expmed doesn't care for non-register predicates. */
13944 if (! memory_operand (operands[0], VOIDmode)
13945 || ! immediate_operand (operands[1], VOIDmode)
13946 || ! immediate_operand (operands[2], VOIDmode)
13947 || ! general_operand (x, VOIDmode))
13949 /* If this isn't a 16 / 24 / 32 bit field, or if
13950 it doesn't start on a byte boundary, then fail. */
13951 bitsize = INTVAL (operands[1]);
13952 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13953 || (INTVAL (operands[2]) % 8) != 0)
13956 size = bitsize / 8;
13957 orig_address = XEXP (operands[0], 0);
13958 shift_reg = gen_reg_rtx (SImode);
13959 if (CONST_INT_P (x))
13962 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13966 emit_insn (gen_movsi (shift_reg, operands[3]));
13967 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13969 addr_target = copy_addr_to_reg (plus_constant (Pmode,
13970 orig_address, size - 1));
13972 operands[0] = replace_equiv_address (operands[0], addr_target);
13973 emit_insn (gen_movqi (operands[0], qi_val));
13977 if (CONST_INT_P (x))
13979 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13982 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13983 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13985 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13986 emit_insn (gen_movqi (operands[0], qi_val));
13992 (define_insn "movua"
13993 [(set (match_operand:SI 0 "register_operand" "=z")
13994 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13998 [(set_attr "type" "movua")])
14000 ;; We shouldn't need this, but cse replaces increments with references
14001 ;; to other regs before flow has a chance to create post_inc
14002 ;; addressing modes, and only postreload's cse_move2add brings the
14003 ;; increments back to a usable form.
14005 [(set (match_operand:SI 0 "register_operand" "")
14006 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
14007 (const_int 32) (const_int 0)))
14008 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
14009 "TARGET_SH4A && REGNO (operands[0]) != REGNO (operands[1])"
14010 [(set (match_operand:SI 0 "register_operand" "")
14011 (sign_extract:SI (mem:SI (post_inc:SI
14012 (match_operand:SI 1 "register_operand" "")))
14013 (const_int 32) (const_int 0)))]
14016 (define_expand "extv"
14017 [(set (match_operand:SI 0 "register_operand" "")
14018 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
14019 (match_operand 2 "const_int_operand" "")
14020 (match_operand 3 "const_int_operand" "")))]
14021 "TARGET_SH4A || TARGET_SH2A"
14023 if (TARGET_SH2A && TARGET_BITOPS
14024 && (satisfies_constraint_Sbw (operands[1])
14025 || satisfies_constraint_Sbv (operands[1]))
14026 && satisfies_constraint_M (operands[2])
14027 && satisfies_constraint_K03 (operands[3]))
14029 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
14030 if (REGNO (operands[0]) != T_REG)
14031 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
14035 && INTVAL (operands[2]) == 32
14036 && INTVAL (operands[3]) == 0
14037 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
14039 rtx src = adjust_address (operands[1], BLKmode, 0);
14040 set_mem_size (src, 4);
14041 emit_insn (gen_movua (operands[0], src));
14048 (define_expand "extzv"
14049 [(set (match_operand:SI 0 "register_operand" "")
14050 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
14051 (match_operand 2 "const_int_operand" "")
14052 (match_operand 3 "const_int_operand" "")))]
14053 "TARGET_SH4A || TARGET_SH2A"
14055 if (TARGET_SH2A && TARGET_BITOPS
14056 && (satisfies_constraint_Sbw (operands[1])
14057 || satisfies_constraint_Sbv (operands[1]))
14058 && satisfies_constraint_M (operands[2])
14059 && satisfies_constraint_K03 (operands[3]))
14061 emit_insn (gen_bld_m2a (operands[1], operands[3]));
14062 if (REGNO (operands[0]) != T_REG)
14063 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
14067 && INTVAL (operands[2]) == 32
14068 && INTVAL (operands[3]) == 0
14069 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
14071 rtx src = adjust_address (operands[1], BLKmode, 0);
14072 set_mem_size (src, 4);
14073 emit_insn (gen_movua (operands[0], src));
14080 ;; -------------------------------------------------------------------------
14081 ;; Extract negated single bit and zero extend it.
14082 ;; Generally we don't care about the exact xor const_int value, as long
14083 ;; as it contains the extracted bit. For simplicity, the pattern variations
14084 ;; that convert everything into the primary '*neg_zero_extract_0' pattern use
14085 ;; a xor const_int -1 value.
14087 (define_insn_and_split "*neg_zero_extract_0"
14088 [(set (reg:SI T_REG)
14089 (zero_extract:SI (xor:QIHISI (match_operand:QIHISI 0 "arith_reg_operand")
14090 (match_operand 1 "const_int_operand"))
14092 (match_operand 2 "const_int_operand")))]
14093 "TARGET_SH1 && can_create_pseudo_p ()
14094 && INTVAL (operands[1]) & (1LL << INTVAL (operands[2]))"
14097 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 2))
14100 if (INTVAL (operands[2]) == 31 && <MODE>mode == SImode)
14102 /* Use cmp/pz to extract bit 31 into the T bit. */
14103 emit_insn (gen_cmpgesi_t (operands[0], const0_rtx));
14107 operands[2] = GEN_INT ((1 << INTVAL (operands[2])));
14108 if (GET_MODE (operands[0]) != SImode)
14109 operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
14112 (define_insn_and_split "*neg_zero_extract_1"
14113 [(set (reg:SI T_REG)
14114 (and:SI (not:SI (match_operand:SI 0 "arith_reg_operand"))
14119 [(set (reg:SI T_REG) (zero_extract:SI (xor:SI (match_dup 0) (const_int -1))
14120 (const_int 1) (const_int 0)))])
14122 ;; x & (1 << n) == 0: 0x00000000 + 1 = 1
14123 ;; x & (1 << n) != 0: 0xFFFFFFFF + 1 = 0
14124 (define_insn_and_split "*neg_zero_extract_2"
14125 [(set (reg:SI T_REG)
14126 (plus:SI (sign_extract:SI (match_operand:QIHISI 0 "arith_reg_operand")
14128 (match_operand 1 "const_int_operand"))
14130 "TARGET_SH1 && can_create_pseudo_p ()"
14133 [(set (reg:SI T_REG) (zero_extract:SI (xor:SI (match_dup 0) (const_int -1))
14134 (const_int 1) (match_dup 1)))])
14136 ;; (signed)x >> 31 + 1 = (x >= 0) ^ 1
14137 (define_insn_and_split "*neg_zero_extract_3"
14138 [(set (reg:SI T_REG)
14139 (plus:SI (ashiftrt:SI (match_operand:SI 0 "arith_reg_operand")
14142 "TARGET_SH1 && can_create_pseudo_p ()"
14145 [(set (reg:SI T_REG) (zero_extract:SI (xor:SI (match_dup 0) (const_int -1))
14146 (const_int 1) (const_int 31)))])
14148 ;; This is required for some bit patterns of DImode subregs.
14149 ;; It looks like combine gets confused by the DImode right shift and fails
14150 ;; to simplify things.
14151 (define_insn_and_split "*neg_zero_extract_4"
14152 [(set (reg:SI T_REG)
14154 (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand")
14155 (match_operand 1 "const_int_operand"))
14156 (match_operand 2 "const_int_operand"))
14157 (not:SI (ashift:SI (match_operand:SI 3 "arith_reg_operand")
14158 (match_operand 4 "const_int_operand"))))
14160 "TARGET_SH1 && can_create_pseudo_p ()
14161 && INTVAL (operands[4]) > 0
14162 && INTVAL (operands[1]) & (1LL << INTVAL (operands[2]))"
14165 [(set (reg:SI T_REG) (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
14166 (const_int 1) (match_dup 2)))])
14168 (define_insn_and_split "*neg_zero_extract_5"
14169 [(set (reg:SI T_REG)
14170 (and:SI (not:SI (subreg:SI
14171 (lshiftrt:DI (match_operand:DI 0 "arith_reg_operand")
14172 (match_operand 1 "const_int_operand"))
14175 "TARGET_SH1 && TARGET_LITTLE_ENDIAN && can_create_pseudo_p ()
14176 && INTVAL (operands[1]) < 32"
14179 [(set (reg:SI T_REG) (zero_extract:SI (xor:SI (match_dup 0) (const_int -1))
14180 (const_int 1) (match_dup 1)))]
14182 operands[0] = gen_lowpart (SImode, operands[0]);
14185 (define_insn_and_split "*neg_zero_extract_6"
14186 [(set (reg:SI T_REG)
14187 (and:SI (not:SI (subreg:SI
14188 (lshiftrt:DI (match_operand:DI 0 "arith_reg_operand")
14189 (match_operand 1 "const_int_operand"))
14192 "TARGET_SH1 && TARGET_BIG_ENDIAN && can_create_pseudo_p ()
14193 && INTVAL (operands[1]) < 32"
14196 [(set (reg:SI T_REG) (zero_extract:SI (xor:SI (match_dup 0) (const_int -1))
14197 (const_int 1) (match_dup 1)))]
14199 operands[0] = gen_lowpart (SImode, operands[0]);
14202 ;; -------------------------------------------------------------------------
14203 ;; Extract single bit and zero extend it.
14204 ;; All patterns store the result bit in the T bit, although that is not
14205 ;; always possible to do with a single insn and a nott must be appended.
14206 ;; The trailing nott will be optimized away in most cases. E.g. if the
14207 ;; extracted bit is fed into a branch condition, the condition can be
14208 ;; inverted and the nott will be eliminated.
14209 ;; FIXME: In cases where the trailing nott can't be eliminated, try to
14210 ;; convert it into a (not, tst) sequence, which could be better on non-SH2A.
14212 ;; On SH2A the 'bld<mode>_reg' insn will be used if the bit position fits.
14213 (define_insn_and_split "*zero_extract_0"
14214 [(set (reg:SI T_REG)
14215 (zero_extract:SI (match_operand:QIHISI 0 "arith_reg_operand")
14217 (match_operand 1 "const_int_operand")))]
14218 "TARGET_SH1 && can_create_pseudo_p ()
14219 && !(TARGET_SH2A && satisfies_constraint_K03 (operands[1]))"
14222 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 1))
14224 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))]
14226 if (INTVAL (operands[1]) == 31 && <MODE>mode == SImode)
14228 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[0]));
14232 operands[1] = GEN_INT (1 << INTVAL (operands[1]));
14233 if (GET_MODE (operands[0]) != SImode)
14234 operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
14237 ;; This is required for some bit patterns of DImode subregs.
14238 ;; It looks like combine gets confused by the DImode right shift and fails
14239 ;; to simplify things.
14240 (define_insn_and_split "*zero_extract_1"
14241 [(set (reg:SI T_REG)
14242 (subreg:SI (zero_extract:DI (match_operand:SI 0 "arith_reg_operand")
14244 (match_operand 1 "const_int_operand"))
14246 "TARGET_SH1 && TARGET_LITTLE_ENDIAN && can_create_pseudo_p ()
14247 && INTVAL (operands[1]) < 32"
14250 [(set (reg:SI T_REG)
14251 (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))])
14253 (define_insn_and_split "*zero_extract_2"
14254 [(set (reg:SI T_REG)
14255 (subreg:SI (zero_extract:DI (match_operand:SI 0 "arith_reg_operand")
14257 (match_operand 1 "const_int_operand"))
14259 "TARGET_SH1 && TARGET_BIG_ENDIAN && can_create_pseudo_p ()
14260 && INTVAL (operands[1]) < 32"
14263 [(set (reg:SI T_REG)
14264 (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))])
14266 ;; -------------------------------------------------------------------------
14267 ;; SH2A instructions for bitwise operations.
14268 ;; FIXME: Convert multiple instruction insns to insn_and_split.
14269 ;; FIXME: Use iterators to fold at least and,xor,or insn variations.
14271 ;; Clear a bit in a memory location.
14272 (define_insn "bclr_m2a"
14273 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
14275 (not:QI (ashift:QI (const_int 1)
14276 (match_operand:QI 1 "const_int_operand" "K03,K03")))
14278 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14281 bclr.b %1,@(0,%t0)"
14282 [(set_attr "length" "4,4")])
14284 (define_insn "bclrmem_m2a"
14285 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
14286 (and:QI (match_dup 0)
14287 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
14288 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
14291 bclr.b %W1,@(0,%t0)"
14292 [(set_attr "length" "4,4")])
14294 ;; Set a bit in a memory location.
14295 (define_insn "bset_m2a"
14296 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
14298 (ashift:QI (const_int 1)
14299 (match_operand:QI 1 "const_int_operand" "K03,K03"))
14301 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14304 bset.b %1,@(0,%t0)"
14305 [(set_attr "length" "4,4")])
14307 (define_insn "bsetmem_m2a"
14308 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
14309 (ior:QI (match_dup 0)
14310 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
14311 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
14314 bset.b %V1,@(0,%t0)"
14315 [(set_attr "length" "4,4")])
14317 ;;; Transfer the contents of the T bit to a specified bit of memory.
14318 (define_insn "bst_m2a"
14319 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
14320 (if_then_else (eq (reg:SI T_REG) (const_int 0))
14322 (not:QI (ashift:QI (const_int 1)
14323 (match_operand:QI 1 "const_int_operand" "K03,K03")))
14326 (ashift:QI (const_int 1) (match_dup 1))
14328 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14332 [(set_attr "length" "4")])
14334 ;; Store a specified bit of memory in the T bit.
14335 (define_insn "bld_m2a"
14336 [(set (reg:SI T_REG)
14338 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
14340 (match_operand 1 "const_int_operand" "K03,K03")))]
14341 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14345 [(set_attr "length" "4,4")])
14347 ;; Store a specified bit of memory in the T bit.
14348 (define_insn "bldsign_m2a"
14349 [(set (reg:SI T_REG)
14351 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
14353 (match_operand 1 "const_int_operand" "K03,K03")))]
14354 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14358 [(set_attr "length" "4,4")])
14360 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
14361 (define_insn "bld<mode>_reg"
14362 [(set (reg:SI T_REG)
14363 (zero_extract:SI (match_operand:QIHISI 0 "arith_reg_operand" "r")
14365 (match_operand 1 "const_int_operand" "K03")))]
14366 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
14369 ;; Take logical and of a specified bit of memory with the T bit and
14370 ;; store its result in the T bit.
14371 (define_insn "band_m2a"
14372 [(set (reg:SI T_REG)
14373 (and:SI (reg:SI T_REG)
14375 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
14377 (match_operand 1 "const_int_operand" "K03,K03"))))]
14378 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14381 band.b %1,@(0,%t0)"
14382 [(set_attr "length" "4,4")])
14384 (define_insn "bandreg_m2a"
14385 [(set (match_operand:SI 0 "register_operand" "=r,r")
14386 (and:SI (zero_extract:SI
14387 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
14389 (match_operand 2 "const_int_operand" "K03,K03"))
14390 (match_operand:SI 3 "register_operand" "r,r")))]
14391 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
14393 static const char* alt[] =
14395 "band.b %2,%1" "\n"
14398 "band.b %2,@(0,%t1)" "\n"
14401 return alt[which_alternative];
14403 [(set_attr "length" "6,6")])
14405 ;; Take logical or of a specified bit of memory with the T bit and
14406 ;; store its result in the T bit.
14407 (define_insn "bor_m2a"
14408 [(set (reg:SI T_REG)
14409 (ior:SI (reg:SI T_REG)
14411 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
14413 (match_operand 1 "const_int_operand" "K03,K03"))))]
14414 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14418 [(set_attr "length" "4,4")])
14420 (define_insn "borreg_m2a"
14421 [(set (match_operand:SI 0 "register_operand" "=r,r")
14422 (ior:SI (zero_extract:SI
14423 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
14425 (match_operand 2 "const_int_operand" "K03,K03"))
14426 (match_operand:SI 3 "register_operand" "=r,r")))]
14427 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
14429 static const char* alt[] =
14434 "bor.b %2,@(0,%t1)" "\n"
14437 return alt[which_alternative];
14439 [(set_attr "length" "6,6")])
14441 ;; Take exclusive or of a specified bit of memory with the T bit and
14442 ;; store its result in the T bit.
14443 (define_insn "bxor_m2a"
14444 [(set (reg:SI T_REG)
14445 (xor:SI (reg:SI T_REG)
14447 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
14449 (match_operand 1 "const_int_operand" "K03,K03"))))]
14450 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
14453 bxor.b %1,@(0,%t0)"
14454 [(set_attr "length" "4,4")])
14456 (define_insn "bxorreg_m2a"
14457 [(set (match_operand:SI 0 "register_operand" "=r,r")
14458 (xor:SI (zero_extract:SI
14459 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
14461 (match_operand 2 "const_int_operand" "K03,K03"))
14462 (match_operand:SI 3 "register_operand" "=r,r")))]
14463 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
14465 static const char* alt[] =
14467 "bxor.b %2,%1" "\n"
14470 "bxor.b %2,@(0,%t1)" "\n"
14473 return alt[which_alternative];
14475 [(set_attr "length" "6,6")])
14477 ;; -------------------------------------------------------------------------
14479 ;; -------------------------------------------------------------------------
14480 ;; This matches cases where the bit in a memory location is set.
14482 [(set (match_operand:SI 0 "register_operand")
14483 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
14485 (ior:SI (match_dup 0)
14486 (match_operand:SI 2 "const_int_operand")))
14488 (match_operand 3 "arith_reg_operand"))]
14489 "TARGET_SH2A && TARGET_BITOPS
14490 && satisfies_constraint_Pso (operands[2])
14491 && REGNO (operands[0]) == REGNO (operands[3])"
14492 [(set (match_dup 1)
14493 (ior:QI (match_dup 1) (match_dup 2)))]
14496 ;; This matches cases where the bit in a memory location is cleared.
14498 [(set (match_operand:SI 0 "register_operand")
14499 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
14501 (and:SI (match_dup 0)
14502 (match_operand:SI 2 "const_int_operand")))
14504 (match_operand 3 "arith_reg_operand"))]
14505 "TARGET_SH2A && TARGET_BITOPS
14506 && satisfies_constraint_Psz (operands[2])
14507 && REGNO (operands[0]) == REGNO (operands[3])"
14508 [(set (match_dup 1)
14509 (and:QI (match_dup 1) (match_dup 2)))]
14512 ;; This matches cases where a stack pointer increment at the start of the
14513 ;; epilogue combines with a stack slot read loading the return value.
14515 [(set (match_operand:SI 0 "arith_reg_operand" "")
14516 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
14517 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
14518 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
14521 ;; See the comment on the dt combiner pattern above.
14523 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
14524 (plus:SI (match_dup 0)
14526 (set (reg:SI T_REG)
14527 (eq:SI (match_dup 0) (const_int 0)))]
14531 ;; The following peepholes fold load sequences for which reload was not
14532 ;; able to generate a displacement addressing move insn.
14533 ;; This can happen when reload has to transform a move insn
14534 ;; without displacement into one with displacement. Or when reload can't
14535 ;; fit a displacement into the insn's constraints. In the latter case, the
14536 ;; load destination reg remains at r0, which reload compensates by inserting
14537 ;; another mov insn.
14541 ;; mov.{b,w} @(r0,r15),r0
14544 ;; mov.{b,w} @(54,r15),r3
14547 [(set (match_operand:SI 0 "arith_reg_dest" "")
14548 (match_operand:SI 1 "const_int_operand" ""))
14549 (set (match_operand:SI 2 "arith_reg_dest" "")
14551 (mem:QI (plus:SI (match_dup 0)
14552 (match_operand:SI 3 "arith_reg_operand" "")))))
14553 (set (match_operand:QI 4 "arith_reg_dest" "")
14554 (match_operand:QI 5 "arith_reg_operand" ""))]
14556 && sh_legitimate_index_p (QImode, operands[1], true, true)
14557 && REGNO (operands[2]) == REGNO (operands[5])
14558 && peep2_reg_dead_p (3, operands[5])"
14559 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
14563 [(set (match_operand:SI 0 "arith_reg_dest" "")
14564 (match_operand:SI 1 "const_int_operand" ""))
14565 (set (match_operand:SI 2 "arith_reg_dest" "")
14567 (mem:HI (plus:SI (match_dup 0)
14568 (match_operand:SI 3 "arith_reg_operand" "")))))
14569 (set (match_operand:HI 4 "arith_reg_dest" "")
14570 (match_operand:HI 5 "arith_reg_operand" ""))]
14572 && sh_legitimate_index_p (HImode, operands[1], true, true)
14573 && REGNO (operands[2]) == REGNO (operands[5])
14574 && peep2_reg_dead_p (3, operands[5])"
14575 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
14580 ;; mov.{b,w} @(r0,r15),r1
14582 ;; mov.{b,w} @(54,r15),r1
14585 [(set (match_operand:SI 0 "arith_reg_dest" "")
14586 (match_operand:SI 1 "const_int_operand" ""))
14587 (set (match_operand:SI 2 "arith_reg_dest" "")
14589 (mem:QI (plus:SI (match_dup 0)
14590 (match_operand:SI 3 "arith_reg_operand" "")))))]
14592 && sh_legitimate_index_p (QImode, operands[1], true, true)
14593 && (peep2_reg_dead_p (2, operands[0])
14594 || REGNO (operands[0]) == REGNO (operands[2]))"
14595 [(set (match_dup 2)
14596 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
14600 [(set (match_operand:SI 0 "arith_reg_dest" "")
14601 (match_operand:SI 1 "const_int_operand" ""))
14602 (set (match_operand:SI 2 "arith_reg_dest" "")
14604 (mem:HI (plus:SI (match_dup 0)
14605 (match_operand:SI 3 "arith_reg_operand" "")))))]
14607 && sh_legitimate_index_p (HImode, operands[1], true, true)
14608 && (peep2_reg_dead_p (2, operands[0])
14609 || REGNO (operands[0]) == REGNO (operands[2]))"
14610 [(set (match_dup 2)
14611 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
14615 ;; mov.{b,w} @(r0,r15),r0
14618 ;; mov.{b,w} @(r0,r15),r3
14620 ;; This can happen when initially a displacement address is picked, where
14621 ;; the destination reg is fixed to r0, and then the address is transformed
14622 ;; into 'r0 + reg'.
14624 [(set (match_operand:SI 0 "arith_reg_dest" "")
14626 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
14627 (match_operand:SI 2 "arith_reg_operand" "")))))
14628 (set (match_operand:QI 3 "arith_reg_dest" "")
14629 (match_operand:QI 4 "arith_reg_operand" ""))]
14631 && REGNO (operands[0]) == REGNO (operands[4])
14632 && peep2_reg_dead_p (2, operands[0])"
14633 [(set (match_dup 3)
14634 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
14638 [(set (match_operand:SI 0 "arith_reg_dest" "")
14640 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
14641 (match_operand:SI 2 "arith_reg_operand" "")))))
14642 (set (match_operand:HI 3 "arith_reg_dest" "")
14643 (match_operand:HI 4 "arith_reg_operand" ""))]
14645 && REGNO (operands[0]) == REGNO (operands[4])
14646 && peep2_reg_dead_p (2, operands[0])"
14647 [(set (match_dup 3)
14648 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
14652 ;; mov b,c -> extu.bw a,c
14654 [(set (match_operand:SI 0 "arith_reg_dest")
14655 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand")))
14656 (set (match_operand:SI 2 "arith_reg_dest")
14658 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
14659 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))])
14662 ;; extu.bw r1,r1 -> extu.bw r0,r1
14664 [(set (match_operand 0 "arith_reg_dest")
14665 (match_operand 1 "arith_reg_operand"))
14666 (set (match_operand:SI 2 "arith_reg_dest")
14667 (zero_extend:SI (match_operand:QIHI 3 "arith_reg_operand")))]
14669 && REGNO (operands[0]) == REGNO (operands[3])
14670 && (REGNO (operands[0]) == REGNO (operands[2])
14671 || peep2_reg_dead_p (2, operands[0]))"
14672 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))]
14674 operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
14678 ;; mov b,a -> < nop >
14680 [(set (match_operand 0 "register_operand")
14681 (match_operand 1 "register_operand"))
14682 (set (match_operand 2 "register_operand")
14683 (match_operand 3 "register_operand"))]
14685 && REGNO (operands[0]) == REGNO (operands[3])
14686 && REGNO (operands[1]) == REGNO (operands[2])
14687 && peep2_reg_dead_p (2, operands[3])"
14691 ;; and r4,r1 -> mov r1,r0
14692 ;; mov r1,r0 and #3,r0
14693 (define_code_iterator ANDIORXOR [and ior xor])
14695 [(set (match_operand:SI 0 "register_operand")
14696 (match_operand:SI 1 "const_logical_operand"))
14697 (set (match_operand:SI 2) (ANDIORXOR:SI (match_dup 2) (match_dup 0)))
14698 (set (reg:SI R0_REG) (match_dup 2))]
14700 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])"
14701 [(set (reg:SI R0_REG) (match_dup 2))
14702 (set (reg:SI R0_REG) (ANDIORXOR:SI (reg:SI R0_REG) (match_dup 1)))])
14704 ;; ... r2,r0 ... r2,r0
14705 ;; or r1,r0 -> or r0,r1
14708 (define_code_iterator ANDIORXORPLUS [and ior xor plus])
14710 [(set (match_operand:SI 0 "arith_reg_dest")
14711 (ANDIORXORPLUS:SI (match_dup 0) (match_operand:SI 1 "arith_reg_dest")))
14712 (set (match_dup 1) (match_dup 0))]
14713 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
14714 [(set (match_dup 1) (ANDIORXORPLUS:SI (match_dup 1) (match_dup 0)))])
14717 ;; add #-48,r0 -> add #-48,r12
14718 ;; mov.l r0,@(4,r10) mov.l r12,@(4,r10)
14721 [(set (match_operand:SI 0 "arith_reg_dest")
14722 (match_operand:SI 1 "arith_reg_dest"))
14723 (set (match_dup 0) (plus:SI (match_dup 0)
14724 (match_operand:SI 2 "const_int_operand")))
14725 (set (match_operand:SI 3 "general_movdst_operand") (match_dup 0))]
14727 && peep2_reg_dead_p (2, operands[1]) && peep2_reg_dead_p (3, operands[0])"
14730 emit_insn (gen_addsi3 (operands[1], operands[1], operands[2]));
14731 sh_peephole_emit_move_insn (operands[3], operands[1]);
14734 ;; mov.l @(r0,r9),r1
14735 ;; mov r1,r0 -> mov @(r0,r9),r0
14737 [(set (match_operand:SI 0 "arith_reg_dest")
14738 (match_operand:SI 1 "general_movsrc_operand"))
14739 (set (match_operand:SI 2 "arith_reg_dest")
14741 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
14744 sh_peephole_emit_move_insn (operands[2], operands[1]);
14748 [(set (match_operand:QIHI 0 "register_operand")
14749 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand"))
14750 (set (match_operand:QIHI 2 "register_operand")
14752 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
14755 sh_peephole_emit_move_insn (operands[2], operands[1]);
14759 [(set (match_operand:SI 0 "arith_reg_dest")
14760 (sign_extend:SI (match_operand:QIHI 1 "movsrc_no_disp_mem_operand")))
14761 (set (match_operand:SI 2 "arith_reg_dest")
14763 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
14766 sh_check_add_incdec_notes (emit_insn (gen_extend<mode>si2 (operands[2],
14767 sh_remove_overlapping_post_inc (operands[2], operands[1]))));
14770 ;; mov.w @(18,r1),r0 (r0 = HImode)
14771 ;; mov r0,r1 (r0 = r1 = HImode) mov.w @(18,r1),r0
14772 ;; ... ..,r13 (r13 = SImode) -> ... ..,r13
14773 ;; tst r1,r13 tst r0,r13
14775 [(set (match_operand 0 "arith_reg_dest")
14776 (match_operand 1 "arith_reg_dest"))
14777 (set (match_operand:SI 2 "arith_reg_dest")
14778 (match_operand:SI 3))
14779 (set (reg:SI T_REG)
14780 (eq:SI (and:SI (match_operand:SI 4 "arith_reg_operand")
14781 (match_operand:SI 5 "arith_reg_operand"))
14784 && peep2_reg_dead_p (3, operands[0])
14785 && !reg_overlap_mentioned_p (operands[0], operands[3])
14786 && (REGNO (operands[0]) == REGNO (operands[4])
14787 || REGNO (operands[0]) == REGNO (operands[5]))
14788 && (REGNO (operands[2]) == REGNO (operands[4])
14789 || REGNO (operands[2]) == REGNO (operands[5]))"
14792 if (REGNO (operands[1]) == REGNO (operands[2]))
14793 operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
14795 // We don't know what the new set insn will be in detail. Just make sure
14796 // that it still can be recognized and the constraints are satisfied.
14797 rtx_insn* i = emit_insn (gen_rtx_SET (operands[2],
14798 sh_remove_overlapping_post_inc (operands[2], operands[3])));
14800 recog_data_d prev_recog_data = recog_data;
14801 bool i_invalid = insn_invalid_p (i, false);
14802 recog_data = prev_recog_data;
14807 sh_check_add_incdec_notes (i);
14809 emit_insn (gen_tstsi_t (operands[2],
14810 gen_rtx_REG (SImode, (REGNO (operands[1])))));
14813 ;; mov.w @(18,r1),r0 (r0 = HImode)
14814 ;; ... ..,r13 (r13 = SImode) mov.w @(18,r1),r0
14815 ;; mov r0,r1 (r0 = r1 = HImode) -> ... ..,r13
14816 ;; tst r1,r13 tst r0,r13
14818 [(set (match_operand:SI 2 "arith_reg_dest")
14819 (match_operand:SI 3))
14820 (set (match_operand 0 "arith_reg_dest")
14821 (match_operand 1 "arith_reg_operand"))
14822 (set (reg:SI T_REG)
14823 (eq:SI (and:SI (match_operand:SI 4 "arith_reg_operand")
14824 (match_operand:SI 5 "arith_reg_operand"))
14827 && peep2_reg_dead_p (3, operands[0])
14828 && !reg_overlap_mentioned_p (operands[0], operands[3])
14829 && (REGNO (operands[0]) == REGNO (operands[4])
14830 || REGNO (operands[0]) == REGNO (operands[5]))
14831 && (REGNO (operands[2]) == REGNO (operands[4])
14832 || REGNO (operands[2]) == REGNO (operands[5]))"
14835 // We don't know what the new set insn will be in detail. Just make sure
14836 // that it still can be recognized and the constraints are satisfied.
14837 rtx_insn* i = emit_insn (gen_rtx_SET (operands[2],
14838 sh_remove_overlapping_post_inc (operands[2], operands[3])));
14840 recog_data_d prev_recog_data = recog_data;
14841 bool i_invalid = insn_invalid_p (i, false);
14842 recog_data = prev_recog_data;
14847 sh_check_add_incdec_notes (i);
14849 emit_insn (gen_tstsi_t (operands[2],
14850 gen_rtx_REG (SImode, (REGNO (operands[1])))));
14853 ;; This is not a peephole, but it's here because it's actually supposed
14854 ;; to be one. It tries to convert a sequence such as
14855 ;; movt r2 -> movt r2
14856 ;; movt r13 mov r2,r13
14857 ;; This gives the schduler a bit more freedom to hoist a following
14858 ;; comparison insn. Moreover, it the reg-reg mov insn is MT group which has
14859 ;; better chances for parallel execution.
14860 ;; We can do this with a peephole2 pattern, but then the cprop_hardreg
14861 ;; pass will revert the change. See also PR 64331.
14862 ;; Thus do it manually in one of the split passes after register allocation.
14863 ;; Sometimes the cprop_hardreg pass might also eliminate the reg-reg copy.
14865 [(set (match_operand:SI 0 "arith_reg_dest")
14866 (match_operand:SI 1 "t_reg_operand"))]
14867 "TARGET_SH1 && reload_completed"
14868 [(set (match_dup 0) (match_dup 1))]
14870 rtx t_reg = get_t_reg_rtx ();
14872 for (rtx_insn* i = prev_nonnote_insn_bb (curr_insn); i != NULL;
14873 i = prev_nonnote_insn_bb (i))
14875 if (!INSN_P (i) || DEBUG_INSN_P (i))
14878 if (modified_in_p (t_reg, i) || BARRIER_P (i))
14881 if (sh_is_movt_insn (i))
14883 rtx r = sh_movt_set_dest (i);
14884 if (!modified_between_p (r, i, curr_insn))
14894 [(set (match_operand:SI 0 "register_operand" "=r")
14895 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
14896 (set (mem:SF (match_dup 0))
14897 (match_operand:SF 2 "general_movsrc_operand" ""))]
14898 "TARGET_SH1 && REGNO (operands[0]) == 0
14899 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
14900 || (GET_CODE (operands[2]) == SUBREG
14901 && REGNO (SUBREG_REG (operands[2])) < 16))
14902 && reg_unused_after (operands[0], insn)"
14903 "mov.l %2,@(%0,%1)")
14906 [(set (match_operand:SI 0 "register_operand" "=r")
14907 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
14908 (set (match_operand:SF 2 "general_movdst_operand" "")
14910 (mem:SF (match_dup 0)))]
14911 "TARGET_SH1 && REGNO (operands[0]) == 0
14912 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
14913 || (GET_CODE (operands[2]) == SUBREG
14914 && REGNO (SUBREG_REG (operands[2])) < 16))
14915 && reg_unused_after (operands[0], insn)"
14916 "mov.l @(%0,%1),%2")
14919 [(set (match_operand:SI 0 "register_operand" "=r")
14920 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
14921 (set (mem:SF (match_dup 0))
14922 (match_operand:SF 2 "general_movsrc_operand" ""))]
14923 "TARGET_SH2E && REGNO (operands[0]) == 0
14924 && ((REG_P (operands[2])
14925 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
14926 || (GET_CODE (operands[2]) == SUBREG
14927 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
14928 && reg_unused_after (operands[0], insn)"
14929 "fmov{.s|} %2,@(%0,%1)")
14932 [(set (match_operand:SI 0 "register_operand" "=r")
14933 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
14934 (set (match_operand:SF 2 "general_movdst_operand" "")
14936 (mem:SF (match_dup 0)))]
14937 "TARGET_SH2E && REGNO (operands[0]) == 0
14938 && ((REG_P (operands[2])
14939 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
14940 || (GET_CODE (operands[2]) == SUBREG
14941 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
14942 && reg_unused_after (operands[0], insn)"
14943 "fmov{.s|} @(%0,%1),%2")
14945 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
14946 (define_insn "sp_switch_1"
14947 [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
14948 UNSPECV_SP_SWITCH_B))]
14951 return "mov.l r0,@-r15" "\n"
14952 " mov.l %0,r0" "\n"
14953 " mov.l @r0,r0" "\n"
14954 " mov.l r15,@-r0" "\n"
14957 [(set_attr "length" "10")])
14959 ;; Switch back to the original stack for interrupt functions with the
14960 ;; sp_switch attribute.
14961 (define_insn "sp_switch_2"
14962 [(unspec_volatile [(const_int 0)]
14963 UNSPECV_SP_SWITCH_E)]
14966 return "mov.l @r15,r15" "\n"
14969 [(set_attr "length" "4")])
14971 ;; -------------------------------------------------------------------------
14972 ;; Integer vector moves
14973 ;; -------------------------------------------------------------------------
14975 (define_expand "movv8qi"
14976 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
14977 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
14980 prepare_move_operands (operands, V8QImode);
14983 (define_insn "movv8qi_i"
14984 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
14985 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14987 && (register_operand (operands[0], V8QImode)
14988 || sh_register_operand (operands[1], V8QImode))"
14995 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14996 (set_attr "length" "4,4,16,4,4")])
14999 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
15000 (subreg:V8QI (const_int 0) 0))]
15002 [(set (match_dup 0)
15003 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
15004 (const_int 0) (const_int 0) (const_int 0)
15005 (const_int 0) (const_int 0)]))])
15008 [(set (match_operand 0 "arith_reg_dest" "")
15009 (match_operand 1 "sh_rep_vec" ""))]
15010 "TARGET_SHMEDIA && reload_completed
15011 && GET_MODE (operands[0]) == GET_MODE (operands[1])
15012 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
15013 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
15014 && (XVECEXP (operands[1], 0, 0) != const0_rtx
15015 || XVECEXP (operands[1], 0, 1) != const0_rtx)
15016 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
15017 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
15018 [(set (match_dup 0) (match_dup 1))
15021 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
15022 rtx elt1 = XVECEXP (operands[1], 0, 1);
15025 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
15029 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
15030 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
15032 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
15033 operands[1] = XVECEXP (operands[1], 0, 0);
15036 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
15038 = GEN_INT (TARGET_LITTLE_ENDIAN
15039 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
15040 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
15043 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
15045 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
15051 [(set (match_operand 0 "arith_reg_dest" "")
15052 (match_operand 1 "sh_const_vec" ""))]
15053 "TARGET_SHMEDIA && reload_completed
15054 && GET_MODE (operands[0]) == GET_MODE (operands[1])
15055 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
15056 [(set (match_dup 0) (match_dup 1))]
15058 rtx v = operands[1];
15059 machine_mode new_mode
15060 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
15062 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
15064 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
15067 (define_expand "movv2hi"
15068 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
15069 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
15072 prepare_move_operands (operands, V2HImode);
15075 (define_insn "movv2hi_i"
15076 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
15077 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
15079 && (register_operand (operands[0], V2HImode)
15080 || sh_register_operand (operands[1], V2HImode))"
15087 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
15088 (set_attr "length" "4,4,16,4,4")
15089 (set (attr "highpart")
15090 (cond [(match_test "sh_contains_memref_p (insn)")
15091 (const_string "user")]
15092 (const_string "ignore")))])
15094 (define_expand "movv4hi"
15095 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
15096 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
15099 prepare_move_operands (operands, V4HImode);
15102 (define_insn "movv4hi_i"
15103 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
15104 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
15106 && (register_operand (operands[0], V4HImode)
15107 || sh_register_operand (operands[1], V4HImode))"
15114 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
15115 (set_attr "length" "4,4,16,4,4")
15116 (set_attr "highpart" "depend")])
15118 (define_expand "movv2si"
15119 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
15120 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
15123 prepare_move_operands (operands, V2SImode);
15126 (define_insn "movv2si_i"
15127 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
15128 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
15130 && (register_operand (operands[0], V2SImode)
15131 || sh_register_operand (operands[1], V2SImode))"
15138 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
15139 (set_attr "length" "4,4,16,4,4")
15140 (set_attr "highpart" "depend")])
15142 ;; -------------------------------------------------------------------------
15143 ;; Multimedia Intrinsics
15144 ;; -------------------------------------------------------------------------
15146 (define_insn "absv2si2"
15147 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15148 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
15151 [(set_attr "type" "mcmp_media")
15152 (set_attr "highpart" "depend")])
15154 (define_insn "absv4hi2"
15155 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15156 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
15159 [(set_attr "type" "mcmp_media")
15160 (set_attr "highpart" "depend")])
15162 (define_insn "addv2si3"
15163 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15164 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
15165 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15167 "madd.l %1, %2, %0"
15168 [(set_attr "type" "arith_media")
15169 (set_attr "highpart" "depend")])
15171 (define_insn "addv4hi3"
15172 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15173 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
15174 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15176 "madd.w %1, %2, %0"
15177 [(set_attr "type" "arith_media")
15178 (set_attr "highpart" "depend")])
15180 (define_insn_and_split "addv2hi3"
15181 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
15182 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
15183 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
15189 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
15190 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
15191 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
15192 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
15193 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
15195 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
15196 emit_insn (gen_truncdisi2 (si_dst, di_dst));
15199 [(set_attr "highpart" "must_split")])
15201 (define_insn "ssaddv2si3"
15202 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15203 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
15204 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15206 "madds.l %1, %2, %0"
15207 [(set_attr "type" "mcmp_media")
15208 (set_attr "highpart" "depend")])
15210 (define_insn "usaddv8qi3"
15211 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15212 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
15213 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
15215 "madds.ub %1, %2, %0"
15216 [(set_attr "type" "mcmp_media")
15217 (set_attr "highpart" "depend")])
15219 (define_insn "ssaddv4hi3"
15220 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15221 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
15222 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15224 "madds.w %1, %2, %0"
15225 [(set_attr "type" "mcmp_media")
15226 (set_attr "highpart" "depend")])
15228 (define_insn "negcmpeqv8qi"
15229 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15231 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
15232 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
15234 "mcmpeq.b %N1, %N2, %0"
15235 [(set_attr "type" "mcmp_media")
15236 (set_attr "highpart" "depend")])
15238 (define_insn "negcmpeqv2si"
15239 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15241 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
15242 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
15244 "mcmpeq.l %N1, %N2, %0"
15245 [(set_attr "type" "mcmp_media")
15246 (set_attr "highpart" "depend")])
15248 (define_insn "negcmpeqv4hi"
15249 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15251 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
15252 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
15254 "mcmpeq.w %N1, %N2, %0"
15255 [(set_attr "type" "mcmp_media")
15256 (set_attr "highpart" "depend")])
15258 (define_insn "negcmpgtuv8qi"
15259 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15260 (neg:V8QI (gtu:V8QI
15261 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
15262 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
15264 "mcmpgt.ub %N1, %N2, %0"
15265 [(set_attr "type" "mcmp_media")
15266 (set_attr "highpart" "depend")])
15268 (define_insn "negcmpgtv2si"
15269 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15271 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
15272 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
15274 "mcmpgt.l %N1, %N2, %0"
15275 [(set_attr "type" "mcmp_media")
15276 (set_attr "highpart" "depend")])
15278 (define_insn "negcmpgtv4hi"
15279 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15281 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
15282 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
15284 "mcmpgt.w %N1, %N2, %0"
15285 [(set_attr "type" "mcmp_media")
15286 (set_attr "highpart" "depend")])
15288 (define_insn "mcmv"
15289 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15290 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15291 (match_operand:DI 2 "arith_reg_operand" "r"))
15292 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
15293 (not:DI (match_dup 2)))))]
15296 [(set_attr "type" "arith_media")
15297 (set_attr "highpart" "depend")])
15299 (define_insn "mcnvs_lw"
15300 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15302 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
15304 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
15306 "mcnvs.lw %N1, %N2, %0"
15307 [(set_attr "type" "mcmp_media")])
15309 (define_insn "mcnvs_wb"
15310 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15312 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
15314 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
15316 "mcnvs.wb %N1, %N2, %0"
15317 [(set_attr "type" "mcmp_media")])
15319 (define_insn "mcnvs_wub"
15320 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15322 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
15324 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
15326 "mcnvs.wub %N1, %N2, %0"
15327 [(set_attr "type" "mcmp_media")])
15329 (define_insn "mextr_rl"
15330 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15331 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15332 (match_operand:HI 3 "mextr_bit_offset" "i"))
15333 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15334 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
15335 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
15337 static char templ[21];
15338 sprintf (templ, "mextr%d %%N1, %%N2, %%0",
15339 (int) INTVAL (operands[3]) >> 3);
15342 [(set_attr "type" "arith_media")])
15344 (define_insn "*mextr_lr"
15345 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15346 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15347 (match_operand:HI 3 "mextr_bit_offset" "i"))
15348 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15349 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
15350 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
15352 static char templ[21];
15353 sprintf (templ, "mextr%d %%N2, %%N1, %%0",
15354 (int) INTVAL (operands[4]) >> 3);
15357 [(set_attr "type" "arith_media")])
15359 ; mextrN can be modelled with vec_select / vec_concat, but the selection
15360 ; vector then varies depending on endianness.
15361 (define_expand "mextr1"
15362 [(match_operand:DI 0 "arith_reg_dest" "")
15363 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15364 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15367 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15368 GEN_INT (1 * 8), GEN_INT (7 * 8)));
15372 (define_expand "mextr2"
15373 [(match_operand:DI 0 "arith_reg_dest" "")
15374 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15375 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15378 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15379 GEN_INT (2 * 8), GEN_INT (6 * 8)));
15383 (define_expand "mextr3"
15384 [(match_operand:DI 0 "arith_reg_dest" "")
15385 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15386 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15389 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15390 GEN_INT (3 * 8), GEN_INT (5 * 8)));
15394 (define_expand "mextr4"
15395 [(match_operand:DI 0 "arith_reg_dest" "")
15396 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15397 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15400 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15401 GEN_INT (4 * 8), GEN_INT (4 * 8)));
15405 (define_expand "mextr5"
15406 [(match_operand:DI 0 "arith_reg_dest" "")
15407 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15408 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15411 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15412 GEN_INT (5 * 8), GEN_INT (3 * 8)));
15416 (define_expand "mextr6"
15417 [(match_operand:DI 0 "arith_reg_dest" "")
15418 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15419 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15422 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15423 GEN_INT (6 * 8), GEN_INT (2 * 8)));
15427 (define_expand "mextr7"
15428 [(match_operand:DI 0 "arith_reg_dest" "")
15429 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15430 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
15433 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
15434 GEN_INT (7 * 8), GEN_INT (1 * 8)));
15438 (define_expand "mmacfx_wl"
15439 [(match_operand:V2SI 0 "arith_reg_dest" "")
15440 (match_operand:V2HI 1 "extend_reg_operand" "")
15441 (match_operand:V2HI 2 "extend_reg_operand" "")
15442 (match_operand:V2SI 3 "arith_reg_operand" "")]
15445 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
15446 operands[1], operands[2]));
15450 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
15452 (define_insn "mmacfx_wl_i"
15453 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15455 (match_operand:V2SI 1 "arith_reg_operand" "0")
15460 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
15461 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
15464 "mmacfx.wl %2, %3, %0"
15465 [(set_attr "type" "mac_media")
15466 (set_attr "highpart" "depend")])
15468 (define_expand "mmacnfx_wl"
15469 [(match_operand:V2SI 0 "arith_reg_dest" "")
15470 (match_operand:V2HI 1 "extend_reg_operand" "")
15471 (match_operand:V2HI 2 "extend_reg_operand" "")
15472 (match_operand:V2SI 3 "arith_reg_operand" "")]
15475 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
15476 operands[1], operands[2]));
15480 (define_insn "mmacnfx_wl_i"
15481 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15483 (match_operand:V2SI 1 "arith_reg_operand" "0")
15488 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
15489 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
15492 "mmacnfx.wl %2, %3, %0"
15493 [(set_attr "type" "mac_media")
15494 (set_attr "highpart" "depend")])
15496 (define_insn "mulv2si3"
15497 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15498 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15499 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15501 "mmul.l %1, %2, %0"
15502 [(set_attr "type" "d2mpy_media")
15503 (set_attr "highpart" "depend")])
15505 (define_insn "mulv4hi3"
15506 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15507 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15508 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15510 "mmul.w %1, %2, %0"
15511 [(set_attr "type" "dmpy_media")
15512 (set_attr "highpart" "depend")])
15514 (define_insn "mmulfx_l"
15515 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15519 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
15520 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
15523 "mmulfx.l %1, %2, %0"
15524 [(set_attr "type" "d2mpy_media")
15525 (set_attr "highpart" "depend")])
15527 (define_insn "mmulfx_w"
15528 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15532 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
15533 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
15536 "mmulfx.w %1, %2, %0"
15537 [(set_attr "type" "dmpy_media")
15538 (set_attr "highpart" "depend")])
15540 (define_insn "mmulfxrp_w"
15541 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15546 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
15547 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
15551 "mmulfxrp.w %1, %2, %0"
15552 [(set_attr "type" "dmpy_media")
15553 (set_attr "highpart" "depend")])
15556 (define_expand "mmulhi_wl"
15557 [(match_operand:V2SI 0 "arith_reg_dest" "")
15558 (match_operand:V4HI 1 "arith_reg_operand" "")
15559 (match_operand:V4HI 2 "arith_reg_operand" "")]
15562 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
15563 (operands[0], operands[1], operands[2]));
15567 (define_expand "mmullo_wl"
15568 [(match_operand:V2SI 0 "arith_reg_dest" "")
15569 (match_operand:V4HI 1 "arith_reg_operand" "")
15570 (match_operand:V4HI 2 "arith_reg_operand" "")]
15573 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
15574 (operands[0], operands[1], operands[2]));
15578 (define_insn "mmul23_wl"
15579 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15582 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
15583 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
15584 (parallel [(const_int 2) (const_int 3)])))]
15587 return (TARGET_LITTLE_ENDIAN
15588 ? "mmulhi.wl %1, %2, %0"
15589 : "mmullo.wl %1, %2, %0");
15591 [(set_attr "type" "dmpy_media")
15592 (set (attr "highpart")
15593 (cond [(eq_attr "endian" "big") (const_string "ignore")]
15594 (const_string "user")))])
15596 (define_insn "mmul01_wl"
15597 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15600 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
15601 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
15602 (parallel [(const_int 0) (const_int 1)])))]
15605 return (TARGET_LITTLE_ENDIAN
15606 ? "mmullo.wl %1, %2, %0"
15607 : "mmulhi.wl %1, %2, %0");
15609 [(set_attr "type" "dmpy_media")
15610 (set (attr "highpart")
15611 (cond [(eq_attr "endian" "little") (const_string "ignore")]
15612 (const_string "user")))])
15615 (define_expand "mmulsum_wq"
15616 [(match_operand:DI 0 "arith_reg_dest" "")
15617 (match_operand:V4HI 1 "arith_reg_operand" "")
15618 (match_operand:V4HI 2 "arith_reg_operand" "")
15619 (match_operand:DI 3 "arith_reg_operand" "")]
15622 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
15623 operands[1], operands[2]));
15627 (define_insn "mmulsum_wq_i"
15628 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15629 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
15634 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
15635 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
15636 (parallel [(const_int 0)]))
15637 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
15638 (sign_extend:V4DI (match_dup 3)))
15639 (parallel [(const_int 1)])))
15641 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
15642 (sign_extend:V4DI (match_dup 3)))
15643 (parallel [(const_int 2)]))
15644 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
15645 (sign_extend:V4DI (match_dup 3)))
15646 (parallel [(const_int 3)]))))))]
15648 "mmulsum.wq %2, %3, %0"
15649 [(set_attr "type" "mac_media")])
15651 (define_expand "mperm_w"
15652 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
15653 (match_operand:V4HI 1 "arith_reg_operand" "r")
15654 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
15657 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
15658 (operands[0], operands[1], operands[2]));
15662 ; This use of vec_select isn't exactly correct according to rtl.texi
15663 ; (because not constant), but it seems a straightforward extension.
15664 (define_insn "mperm_w_little"
15665 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15667 (match_operand:V4HI 1 "arith_reg_operand" "r")
15669 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
15670 (const_int 2) (const_int 0))
15671 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
15672 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
15673 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
15674 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
15675 "mperm.w %1, %N2, %0"
15676 [(set_attr "type" "arith_media")])
15678 (define_insn "mperm_w_big"
15679 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15681 (match_operand:V4HI 1 "arith_reg_operand" "r")
15683 [(zero_extract:QI (not:QI (match_operand:QI 2
15684 "extend_reg_or_0_operand" "rZ"))
15685 (const_int 2) (const_int 0))
15686 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
15687 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
15688 (zero_extract:QI (not:QI (match_dup 2))
15689 (const_int 2) (const_int 6))])))]
15690 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
15691 "mperm.w %1, %N2, %0"
15692 [(set_attr "type" "arith_media")])
15694 (define_insn "mperm_w0"
15695 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15696 (vec_duplicate:V4HI (truncate:HI (match_operand 1
15697 "trunc_hi_operand" "r"))))]
15699 "mperm.w %1, r63, %0"
15700 [(set_attr "type" "arith_media")
15701 (set_attr "highpart" "ignore")])
15703 (define_expand "msad_ubq"
15704 [(match_operand:DI 0 "arith_reg_dest" "")
15705 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
15706 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
15707 (match_operand:DI 3 "arith_reg_operand" "")]
15710 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
15711 operands[1], operands[2]));
15715 (define_insn "msad_ubq_i"
15716 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15721 (match_operand:DI 1 "arith_reg_operand" "0")
15722 (abs:DI (vec_select:DI
15725 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
15727 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
15728 (parallel [(const_int 0)]))))
15729 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15730 (zero_extend:V8DI (match_dup 3)))
15731 (parallel [(const_int 1)]))))
15733 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15734 (zero_extend:V8DI (match_dup 3)))
15735 (parallel [(const_int 2)])))
15736 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15737 (zero_extend:V8DI (match_dup 3)))
15738 (parallel [(const_int 3)])))))
15741 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15742 (zero_extend:V8DI (match_dup 3)))
15743 (parallel [(const_int 4)])))
15744 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15745 (zero_extend:V8DI (match_dup 3)))
15746 (parallel [(const_int 5)]))))
15748 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15749 (zero_extend:V8DI (match_dup 3)))
15750 (parallel [(const_int 6)])))
15751 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
15752 (zero_extend:V8DI (match_dup 3)))
15753 (parallel [(const_int 7)])))))))]
15755 "msad.ubq %N2, %N3, %0"
15756 [(set_attr "type" "mac_media")])
15758 (define_insn "mshalds_l"
15759 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15762 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
15763 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
15764 (const_int 31)))))]
15766 "mshalds.l %1, %2, %0"
15767 [(set_attr "type" "mcmp_media")
15768 (set_attr "highpart" "depend")])
15770 (define_insn "mshalds_w"
15771 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15774 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
15775 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
15776 (const_int 15)))))]
15778 "mshalds.w %1, %2, %0"
15779 [(set_attr "type" "mcmp_media")
15780 (set_attr "highpart" "depend")])
15782 (define_insn "ashrv2si3"
15783 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15784 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15785 (match_operand:DI 2 "arith_reg_operand" "r")))]
15787 "mshard.l %1, %2, %0"
15788 [(set_attr "type" "arith_media")
15789 (set_attr "highpart" "depend")])
15791 (define_insn "ashrv4hi3"
15792 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15793 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15794 (match_operand:DI 2 "arith_reg_operand" "r")))]
15796 "mshard.w %1, %2, %0"
15797 [(set_attr "type" "arith_media")
15798 (set_attr "highpart" "depend")])
15800 (define_insn "mshards_q"
15801 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
15803 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
15804 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
15806 "mshards.q %1, %N2, %0"
15807 [(set_attr "type" "mcmp_media")])
15809 (define_expand "mshfhi_b"
15810 [(match_operand:V8QI 0 "arith_reg_dest" "")
15811 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15812 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
15815 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
15816 (operands[0], operands[1], operands[2]));
15820 (define_expand "mshflo_b"
15821 [(match_operand:V8QI 0 "arith_reg_dest" "")
15822 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15823 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
15826 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
15827 (operands[0], operands[1], operands[2]));
15831 (define_insn "mshf4_b"
15833 (match_operand:V8QI 0 "arith_reg_dest" "=r")
15835 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15836 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
15837 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
15838 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
15841 return (TARGET_LITTLE_ENDIAN
15842 ? "mshfhi.b %N1, %N2, %0"
15843 : "mshflo.b %N1, %N2, %0");
15845 [(set_attr "type" "arith_media")
15846 (set (attr "highpart")
15847 (cond [(eq_attr "endian" "big") (const_string "ignore")]
15848 (const_string "user")))])
15850 (define_insn "mshf0_b"
15852 (match_operand:V8QI 0 "arith_reg_dest" "=r")
15854 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15855 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
15856 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
15857 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
15860 return (TARGET_LITTLE_ENDIAN
15861 ? "mshflo.b %N1, %N2, %0"
15862 : "mshfhi.b %N1, %N2, %0");
15864 [(set_attr "type" "arith_media")
15865 (set (attr "highpart")
15866 (cond [(eq_attr "endian" "little") (const_string "ignore")]
15867 (const_string "user")))])
15869 (define_expand "mshfhi_l"
15870 [(match_operand:V2SI 0 "arith_reg_dest" "")
15871 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15872 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
15875 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
15876 (operands[0], operands[1], operands[2]));
15880 (define_expand "mshflo_l"
15881 [(match_operand:V2SI 0 "arith_reg_dest" "")
15882 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15883 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
15886 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
15887 (operands[0], operands[1], operands[2]));
15891 (define_insn "mshf4_l"
15892 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15894 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15895 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
15896 (parallel [(const_int 1) (const_int 3)])))]
15899 return (TARGET_LITTLE_ENDIAN
15900 ? "mshfhi.l %N1, %N2, %0"
15901 : "mshflo.l %N1, %N2, %0");
15903 [(set_attr "type" "arith_media")
15904 (set (attr "highpart")
15905 (cond [(eq_attr "endian" "big") (const_string "ignore")]
15906 (const_string "user")))])
15908 (define_insn "mshf0_l"
15909 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15911 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15912 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
15913 (parallel [(const_int 0) (const_int 2)])))]
15916 return (TARGET_LITTLE_ENDIAN
15917 ? "mshflo.l %N1, %N2, %0"
15918 : "mshfhi.l %N1, %N2, %0");
15920 [(set_attr "type" "arith_media")
15921 (set (attr "highpart")
15922 (cond [(eq_attr "endian" "little") (const_string "ignore")]
15923 (const_string "user")))])
15925 (define_expand "mshfhi_w"
15926 [(match_operand:V4HI 0 "arith_reg_dest" "")
15927 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15928 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
15931 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
15932 (operands[0], operands[1], operands[2]));
15936 (define_expand "mshflo_w"
15937 [(match_operand:V4HI 0 "arith_reg_dest" "")
15938 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15939 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
15942 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
15943 (operands[0], operands[1], operands[2]));
15947 (define_insn "mshf4_w"
15948 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15950 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15951 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
15952 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
15955 return (TARGET_LITTLE_ENDIAN
15956 ? "mshfhi.w %N1, %N2, %0"
15957 : "mshflo.w %N1, %N2, %0");
15959 [(set_attr "type" "arith_media")
15960 (set (attr "highpart")
15961 (cond [(eq_attr "endian" "big") (const_string "ignore")]
15962 (const_string "user")))])
15964 (define_insn "mshf0_w"
15965 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15967 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15968 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
15969 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
15972 return (TARGET_LITTLE_ENDIAN
15973 ? "mshflo.w %N1, %N2, %0"
15974 : "mshfhi.w %N1, %N2, %0");
15976 [(set_attr "type" "arith_media")
15977 (set (attr "highpart")
15978 (cond [(eq_attr "endian" "little") (const_string "ignore")]
15979 (const_string "user")))])
15981 (define_insn "mshflo_w_x"
15982 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15984 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
15985 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
15986 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
15988 "mshflo.w %N1, %N2, %0"
15989 [(set_attr "type" "arith_media")
15990 (set_attr "highpart" "ignore")])
15992 ;; These are useful to expand ANDs and as combiner patterns.
15993 (define_insn_and_split "mshfhi_l_di"
15994 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
15995 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
15997 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
15998 (const_int -4294967296))))]
16001 mshfhi.l %N1, %N2, %0
16003 "TARGET_SHMEDIA && reload_completed
16004 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
16005 [(set (match_dup 3) (match_dup 4))
16006 (set (match_dup 5) (match_dup 6))]
16008 operands[3] = gen_lowpart (SImode, operands[0]);
16009 operands[4] = gen_highpart (SImode, operands[1]);
16010 operands[5] = gen_highpart (SImode, operands[0]);
16011 operands[6] = gen_highpart (SImode, operands[2]);
16013 [(set_attr "type" "arith_media")])
16015 (define_insn "*mshfhi_l_di_rev"
16016 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16017 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
16018 (const_int -4294967296))
16019 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
16022 "mshfhi.l %N2, %N1, %0"
16023 [(set_attr "type" "arith_media")])
16026 [(set (match_operand:DI 0 "arith_reg_dest" "")
16027 (ior:DI (zero_extend:DI (match_operand:SI 1
16028 "extend_reg_or_0_operand" ""))
16029 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
16030 (const_int -4294967296))))
16031 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
16035 emit_insn (gen_ashldi3_media (operands[3],
16036 simplify_gen_subreg (DImode, operands[1],
16039 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
16043 (define_insn "mshflo_l_di"
16044 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16045 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
16046 (const_int 4294967295))
16047 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
16051 "mshflo.l %N1, %N2, %0"
16052 [(set_attr "type" "arith_media")
16053 (set_attr "highpart" "ignore")])
16055 (define_insn "*mshflo_l_di_rev"
16056 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16057 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
16059 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
16060 (const_int 4294967295))))]
16063 "mshflo.l %N2, %N1, %0"
16064 [(set_attr "type" "arith_media")
16065 (set_attr "highpart" "ignore")])
16067 ;; Combiner pattern for trampoline initialization.
16068 (define_insn_and_split "*double_shori"
16069 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16070 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
16072 (match_operand:DI 2 "const_int_operand" "n")))]
16074 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
16076 "rtx_equal_p (operands[0], operands[1])"
16079 HOST_WIDE_INT v = INTVAL (operands[2]);
16081 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
16082 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
16085 [(set_attr "highpart" "ignore")])
16087 (define_insn "*mshflo_l_di_x"
16088 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16089 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
16091 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
16094 "mshflo.l %N1, %N2, %0"
16095 [(set_attr "type" "arith_media")
16096 (set_attr "highpart" "ignore")])
16098 (define_insn_and_split "concat_v2sf"
16099 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
16100 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
16101 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
16102 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
16105 mshflo.l %N1, %N2, %0
16108 "TARGET_SHMEDIA && reload_completed
16109 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
16110 [(set (match_dup 3) (match_dup 1))
16111 (set (match_dup 4) (match_dup 2))]
16113 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
16114 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
16116 [(set_attr "type" "arith_media")
16117 (set_attr "highpart" "ignore")])
16119 (define_insn "*mshflo_l_di_x_rev"
16120 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16121 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
16124 (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
16126 "mshflo.l %N2, %N1, %0"
16127 [(set_attr "type" "arith_media")
16128 (set_attr "highpart" "ignore")])
16130 (define_insn "ashlv2si3"
16131 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
16132 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
16133 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
16135 "mshlld.l %1, %2, %0"
16136 [(set_attr "type" "arith_media")
16137 (set_attr "highpart" "depend")])
16140 [(set (match_operand 0 "any_register_operand" "")
16141 (match_operator 3 "shift_operator"
16142 [(match_operand 1 "any_register_operand" "")
16143 (match_operand 2 "shift_count_reg_operand" "")]))]
16144 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
16145 [(set (match_dup 0) (match_dup 3))]
16147 rtx count = operands[2];
16148 machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
16150 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
16151 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
16152 || GET_CODE (count) == TRUNCATE)
16153 count = XEXP (count, 0);
16154 inner_mode = GET_MODE (count);
16155 count = simplify_gen_subreg (outer_mode, count, inner_mode,
16156 subreg_lowpart_offset (outer_mode, inner_mode));
16157 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
16158 operands[1], count);
16161 (define_insn "ashlv4hi3"
16162 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
16163 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
16164 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
16166 "mshlld.w %1, %2, %0"
16167 [(set_attr "type" "arith_media")
16168 (set_attr "highpart" "depend")])
16170 (define_insn "lshrv2si3"
16171 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
16172 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
16173 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
16175 "mshlrd.l %1, %2, %0"
16176 [(set_attr "type" "arith_media")
16177 (set_attr "highpart" "depend")])
16179 (define_insn "lshrv4hi3"
16180 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
16181 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
16182 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
16184 "mshlrd.w %1, %2, %0"
16185 [(set_attr "type" "arith_media")
16186 (set_attr "highpart" "depend")])
16188 (define_insn "subv2si3"
16189 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
16190 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
16191 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
16193 "msub.l %N1, %2, %0"
16194 [(set_attr "type" "arith_media")
16195 (set_attr "highpart" "depend")])
16197 (define_insn "subv4hi3"
16198 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
16199 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
16200 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
16202 "msub.w %N1, %2, %0"
16203 [(set_attr "type" "arith_media")
16204 (set_attr "highpart" "depend")])
16206 (define_insn_and_split "subv2hi3"
16207 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
16208 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
16209 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
16215 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
16216 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
16217 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
16218 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
16219 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
16221 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
16222 emit_insn (gen_truncdisi2 (si_dst, di_dst));
16225 [(set_attr "highpart" "must_split")])
16227 (define_insn "sssubv2si3"
16228 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
16229 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
16230 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
16232 "msubs.l %N1, %2, %0"
16233 [(set_attr "type" "mcmp_media")
16234 (set_attr "highpart" "depend")])
16236 (define_insn "ussubv8qi3"
16237 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
16238 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
16239 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
16241 "msubs.ub %N1, %2, %0"
16242 [(set_attr "type" "mcmp_media")
16243 (set_attr "highpart" "depend")])
16245 (define_insn "sssubv4hi3"
16246 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
16247 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
16248 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
16250 "msubs.w %N1, %2, %0"
16251 [(set_attr "type" "mcmp_media")
16252 (set_attr "highpart" "depend")])
16254 ;; -------------------------------------------------------------------------
16255 ;; Floating Point Intrinsics
16256 ;; -------------------------------------------------------------------------
16258 (define_insn "fcosa_s"
16259 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
16260 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
16264 [(set_attr "type" "atrans_media")])
16266 (define_insn "fsina_s"
16267 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
16268 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
16272 [(set_attr "type" "atrans_media")])
16274 (define_insn "fipr"
16275 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
16276 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
16277 "fp_arith_reg_operand" "f")
16278 (match_operand:V4SF 2
16279 "fp_arith_reg_operand" "f"))
16280 (parallel [(const_int 0)]))
16281 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
16282 (parallel [(const_int 1)])))
16283 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
16284 (parallel [(const_int 2)]))
16285 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
16286 (parallel [(const_int 3)])))))]
16288 "fipr.s %1, %2, %0"
16289 [(set_attr "type" "fparith_media")])
16291 (define_insn "fsrra_s"
16292 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
16293 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
16297 [(set_attr "type" "atrans_media")])
16299 (define_insn "ftrv"
16300 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
16304 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
16305 (parallel [(const_int 0) (const_int 5)
16306 (const_int 10) (const_int 15)]))
16307 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
16309 (vec_select:V4SF (match_dup 1)
16310 (parallel [(const_int 4) (const_int 9)
16311 (const_int 14) (const_int 3)]))
16312 (vec_select:V4SF (match_dup 2)
16313 (parallel [(const_int 1) (const_int 2)
16314 (const_int 3) (const_int 0)]))))
16317 (vec_select:V4SF (match_dup 1)
16318 (parallel [(const_int 8) (const_int 13)
16319 (const_int 2) (const_int 7)]))
16320 (vec_select:V4SF (match_dup 2)
16321 (parallel [(const_int 2) (const_int 3)
16322 (const_int 0) (const_int 1)])))
16324 (vec_select:V4SF (match_dup 1)
16325 (parallel [(const_int 12) (const_int 1)
16326 (const_int 6) (const_int 11)]))
16327 (vec_select:V4SF (match_dup 2)
16328 (parallel [(const_int 3) (const_int 0)
16329 (const_int 1) (const_int 2)]))))))]
16331 "ftrv.s %1, %2, %0"
16332 [(set_attr "type" "fparith_media")])
16334 (define_insn "ldhi_l"
16335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
16337 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
16340 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
16344 [(set_attr "type" "load_media")])
16346 (define_insn "ldhi_q"
16347 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16349 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
16352 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
16356 [(set_attr "type" "load_media")])
16358 (define_insn_and_split "*ldhi_q_comb0"
16359 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16361 (mem:DI (plus:SI (ior:SI (plus:SI
16362 (match_operand:SI 1 "register_operand" "r")
16363 (match_operand:SI 2 "ua_offset" "I06"))
16366 (plus:SI (and:SI (match_dup 1) (const_int 7))
16369 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
16374 emit_insn (gen_ldhi_q (operands[0],
16375 gen_rtx_PLUS (SImode, operands[1], operands[2])));
16379 (define_insn_and_split "*ldhi_q_comb1"
16380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16382 (mem:DI (plus:SI (ior:SI (plus:SI
16383 (match_operand:SI 1 "register_operand" "r")
16384 (match_operand:SI 2 "ua_offset" "I06"))
16387 (plus:SI (and:SI (plus:SI (match_dup 1)
16388 (match_operand:SI 3 "ua_offset" "I06"))
16392 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
16393 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
16398 emit_insn (gen_ldhi_q (operands[0],
16399 gen_rtx_PLUS (SImode, operands[1], operands[2])));
16403 (define_insn "ldlo_l"
16404 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
16406 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
16408 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
16409 (and:SI (match_dup 1) (const_int 3))))]
16412 [(set_attr "type" "load_media")])
16414 (define_insn "ldlo_q"
16415 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16417 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
16419 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
16420 (and:SI (match_dup 1) (const_int 7))))]
16423 [(set_attr "type" "load_media")])
16425 (define_insn_and_split "*ldlo_q_comb0"
16426 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16428 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
16429 (match_operand:SI 2 "ua_offset" "I06"))
16431 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
16432 (and:SI (match_dup 1) (const_int 7))))]
16433 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
16438 emit_insn (gen_ldlo_q (operands[0],
16439 gen_rtx_PLUS (SImode, operands[1], operands[2])));
16443 (define_insn_and_split "*ldlo_q_comb1"
16444 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16446 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
16447 (match_operand:SI 2 "ua_offset" "I06"))
16449 (minus:SI (const_int 8)
16450 (and:SI (plus:SI (match_dup 1)
16451 (match_operand:SI 3 "ua_offset" "I06"))
16453 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
16454 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
16455 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
16460 emit_insn (gen_ldlo_q (operands[0],
16461 gen_rtx_PLUS (SImode, operands[1], operands[2])));
16465 (define_insn "sthi_l"
16466 [(set (zero_extract:SI
16467 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
16470 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
16472 (match_operand:SI 1 "arith_reg_operand" "r"))]
16475 [(set_attr "type" "ustore_media")])
16477 ;; All unaligned stores are considered to be 'narrow' because they typically
16478 ;; operate on less that a quadword, and when they operate on a full quadword,
16479 ;; the vanilla store high / store low sequence will cause a stall if not
16480 ;; scheduled apart.
16481 (define_insn "sthi_q"
16482 [(set (zero_extract:DI
16483 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
16486 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
16488 (match_operand:DI 1 "arith_reg_operand" "r"))]
16491 [(set_attr "type" "ustore_media")])
16493 (define_insn_and_split "*sthi_q_comb0"
16494 [(set (zero_extract:DI
16495 (mem:DI (plus:SI (ior:SI (plus:SI
16496 (match_operand:SI 0 "register_operand" "r")
16497 (match_operand:SI 1 "ua_offset" "I06"))
16500 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
16502 (match_operand:DI 2 "arith_reg_operand" "r"))]
16503 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
16508 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
16513 (define_insn_and_split "*sthi_q_comb1"
16514 [(set (zero_extract:DI
16515 (mem:DI (plus:SI (ior:SI (plus:SI
16516 (match_operand:SI 0 "register_operand" "r")
16517 (match_operand:SI 1 "ua_offset" "I06"))
16520 (plus:SI (and:SI (plus:SI (match_dup 0)
16521 (match_operand:SI 2 "ua_offset" "I06"))
16525 (match_operand:DI 3 "arith_reg_operand" "r"))]
16526 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
16527 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
16532 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
16537 ;; This is highpart user because the address is used as full 64 bit.
16538 (define_insn "stlo_l"
16539 [(set (zero_extract:SI
16540 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
16542 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
16543 (and:SI (match_dup 0) (const_int 3)))
16544 (match_operand:SI 1 "arith_reg_operand" "r"))]
16547 [(set_attr "type" "ustore_media")])
16549 (define_insn "stlo_q"
16550 [(set (zero_extract:DI
16551 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
16553 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
16554 (and:SI (match_dup 0) (const_int 7)))
16555 (match_operand:DI 1 "arith_reg_operand" "r"))]
16558 [(set_attr "type" "ustore_media")])
16560 (define_insn_and_split "*stlo_q_comb0"
16561 [(set (zero_extract:DI
16562 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
16563 (match_operand:SI 1 "ua_offset" "I06"))
16565 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
16566 (and:SI (match_dup 0) (const_int 7)))
16567 (match_operand:DI 2 "arith_reg_operand" "r"))]
16568 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
16573 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
16578 (define_insn_and_split "*stlo_q_comb1"
16579 [(set (zero_extract:DI
16580 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
16581 (match_operand:SI 1 "ua_offset" "I06"))
16583 (minus:SI (const_int 8)
16584 (and:SI (plus:SI (match_dup 0)
16585 (match_operand:SI 2 "ua_offset" "I06"))
16587 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
16588 (match_operand:DI 3 "arith_reg_operand" "r"))]
16589 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
16594 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
16599 (define_insn "ldhi_l64"
16600 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
16602 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
16605 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
16609 [(set_attr "type" "load_media")])
16611 (define_insn "ldhi_q64"
16612 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16614 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
16617 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
16621 [(set_attr "type" "load_media")])
16623 (define_insn "ldlo_l64"
16624 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
16626 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
16628 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
16629 (and:DI (match_dup 1) (const_int 3))))]
16632 [(set_attr "type" "load_media")])
16634 (define_insn "ldlo_q64"
16635 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16637 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
16639 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
16640 (and:DI (match_dup 1) (const_int 7))))]
16643 [(set_attr "type" "load_media")])
16645 (define_insn "sthi_l64"
16646 [(set (zero_extract:SI
16647 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
16650 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
16652 (match_operand:SI 1 "arith_reg_operand" "r"))]
16655 [(set_attr "type" "ustore_media")])
16657 (define_insn "sthi_q64"
16658 [(set (zero_extract:DI
16659 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
16662 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
16664 (match_operand:DI 1 "arith_reg_operand" "r"))]
16667 [(set_attr "type" "ustore_media")])
16669 (define_insn "stlo_l64"
16670 [(set (zero_extract:SI
16671 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
16673 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
16674 (and:DI (match_dup 0) (const_int 3)))
16675 (match_operand:SI 1 "arith_reg_operand" "r"))]
16678 [(set_attr "type" "ustore_media")])
16680 (define_insn "stlo_q64"
16681 [(set (zero_extract:DI
16682 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
16684 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
16685 (and:DI (match_dup 0) (const_int 7)))
16686 (match_operand:DI 1 "arith_reg_operand" "r"))]
16689 [(set_attr "type" "ustore_media")])
16692 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
16693 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
16697 [(set_attr "type" "arith_media")])
16699 (define_insn "nsbsi"
16700 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
16702 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
16706 [(set_attr "type" "arith_media")])
16708 (define_insn "nsbdi"
16709 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
16711 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
16715 [(set_attr "type" "arith_media")])
16717 (define_expand "ffsdi2"
16718 [(set (match_operand:DI 0 "arith_reg_dest" "")
16719 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
16722 rtx scratch = gen_reg_rtx (DImode);
16725 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
16726 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
16727 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
16728 emit_insn (gen_nsbdi (scratch, scratch));
16729 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
16730 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
16731 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
16732 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
16737 (define_expand "ffssi2"
16738 [(set (match_operand:SI 0 "arith_reg_dest" "")
16739 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
16742 rtx scratch = gen_reg_rtx (SImode);
16743 rtx discratch = gen_reg_rtx (DImode);
16746 emit_insn (gen_adddi3 (discratch,
16747 simplify_gen_subreg (DImode, operands[1], SImode, 0),
16749 emit_insn (gen_andcdi3 (discratch,
16750 simplify_gen_subreg (DImode, operands[1], SImode, 0),
16752 emit_insn (gen_nsbsi (scratch, discratch));
16753 last = emit_insn (gen_subsi3 (operands[0],
16754 force_reg (SImode, GEN_INT (63)), scratch));
16755 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
16760 (define_insn "byterev"
16761 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
16762 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
16763 (parallel [(const_int 7) (const_int 6) (const_int 5)
16764 (const_int 4) (const_int 3) (const_int 2)
16765 (const_int 1) (const_int 0)])))]
16768 [(set_attr "type" "arith_media")])
16770 ;; In user mode, the "pref" instruction will raise a RADDERR exception
16771 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
16772 ;; implementation of __builtin_prefetch for VxWorks RTPs.
16773 (define_expand "prefetch"
16774 [(prefetch (match_operand 0 "address_operand" "")
16775 (match_operand:SI 1 "const_int_operand" "")
16776 (match_operand:SI 2 "const_int_operand" ""))]
16777 "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
16778 && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
16780 (define_insn "*prefetch"
16781 [(prefetch (match_operand:SI 0 "register_operand" "r")
16782 (match_operand:SI 1 "const_int_operand" "n")
16783 (match_operand:SI 2 "const_int_operand" "n"))]
16784 "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
16786 [(set_attr "type" "other")])
16788 (define_insn "*prefetch_media"
16789 [(prefetch (match_operand:QI 0 "address_operand" "p")
16790 (match_operand:SI 1 "const_int_operand" "n")
16791 (match_operand:SI 2 "const_int_operand" "n"))]
16794 operands[0] = gen_rtx_MEM (QImode, operands[0]);
16795 output_asm_insn ("ld%M0.b %m0,r63", operands);
16798 [(set_attr "type" "other")])
16800 (define_insn "alloco_i"
16801 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
16802 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
16807 if (GET_CODE (operands[0]) == PLUS)
16809 xops[0] = XEXP (operands[0], 0);
16810 xops[1] = XEXP (operands[0], 1);
16814 xops[0] = operands[0];
16815 xops[1] = const0_rtx;
16817 output_asm_insn ("alloco %0, %1", xops);
16820 [(set_attr "type" "other")])
16823 [(set (match_operand 0 "any_register_operand" "")
16824 (match_operand 1 "" ""))]
16825 "TARGET_SHMEDIA && reload_completed"
16826 [(set (match_dup 0) (match_dup 1))]
16828 if (!shmedia_cleanup_truncate (operands[1]))
16832 ;; -------------------------------------------------------------------------
16833 ;; Stack Protector Patterns
16834 ;; -------------------------------------------------------------------------
16836 (define_expand "stack_protect_set"
16837 [(set (match_operand 0 "memory_operand" "")
16838 (match_operand 1 "memory_operand" ""))]
16841 if (TARGET_SHMEDIA)
16843 if (TARGET_SHMEDIA64)
16844 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
16846 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
16849 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
16854 (define_insn "stack_protect_set_si"
16855 [(set (match_operand:SI 0 "memory_operand" "=m")
16856 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
16857 (set (match_scratch:SI 2 "=&r") (const_int 0))]
16860 return "mov.l %1,%2" "\n"
16861 " mov.l %2,%0" "\n"
16864 [(set_attr "type" "other")
16865 (set_attr "length" "6")])
16867 (define_insn "stack_protect_set_si_media"
16868 [(set (match_operand:SI 0 "memory_operand" "=m")
16869 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
16870 (set (match_scratch:SI 2 "=&r") (const_int 0))]
16873 return "ld%M1.l %m1,%2" "\n"
16874 " st%M0.l %m0,%2" "\n"
16877 [(set_attr "type" "other")
16878 (set_attr "length" "12")])
16880 (define_insn "stack_protect_set_di_media"
16881 [(set (match_operand:DI 0 "memory_operand" "=m")
16882 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
16883 (set (match_scratch:DI 2 "=&r") (const_int 0))]
16886 return "ld%M1.q %m1,%2" "\n"
16887 " st%M0.q %m0,%2" "\n"
16890 [(set_attr "type" "other")
16891 (set_attr "length" "12")])
16893 (define_expand "stack_protect_test"
16894 [(match_operand 0 "memory_operand" "")
16895 (match_operand 1 "memory_operand" "")
16896 (match_operand 2 "" "")]
16899 if (TARGET_SHMEDIA)
16901 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
16904 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
16905 if (TARGET_SHMEDIA64)
16907 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
16909 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
16913 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
16915 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
16920 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
16921 emit_jump_insn (gen_branch_true (operands[2]));
16927 (define_insn "stack_protect_test_si"
16928 [(set (reg:SI T_REG)
16929 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
16930 (match_operand:SI 1 "memory_operand" "m")]
16932 (set (match_scratch:SI 2 "=&r") (const_int 0))
16933 (set (match_scratch:SI 3 "=&r") (const_int 0))]
16936 return "mov.l %0,%2" "\n"
16937 " mov.l %1,%3" "\n"
16938 " cmp/eq %2,%3" "\n"
16942 [(set_attr "type" "other")
16943 (set_attr "length" "10")])
16945 (define_insn "stack_protect_test_si_media"
16946 [(set (match_operand:SI 0 "register_operand" "=&r")
16947 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
16948 (match_operand:SI 2 "memory_operand" "m")]
16950 (set (match_scratch:SI 3 "=&r") (const_int 0))]
16953 return "ld%M1.l %m1,%0" "\n"
16954 " ld%M2.l %m2,%3" "\n"
16955 " cmpeq %0,%3,%0" "\n"
16958 [(set_attr "type" "other")
16959 (set_attr "length" "16")])
16961 (define_insn "stack_protect_test_di_media"
16962 [(set (match_operand:DI 0 "register_operand" "=&r")
16963 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
16964 (match_operand:DI 2 "memory_operand" "m")]
16966 (set (match_scratch:DI 3 "=&r") (const_int 0))]
16969 return "ld%M1.q %m1,%0" "\n"
16970 " ld%M2.q %m2,%3" "\n"
16971 " cmpeq %0,%3,%0" "\n"
16974 [(set_attr "type" "other")
16975 (set_attr "length" "16")])
16977 ;; -------------------------------------------------------------------------
16978 ;; Atomic operations
16979 ;; -------------------------------------------------------------------------
16981 (include "sync.md")