1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993-2014 Free Software Foundation, Inc.
3 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
4 ;; Improved by Jim Wilson (wilson@cygnus.com).
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
23 ;; ??? Should prepend a * to all pattern names which are not used.
24 ;; This will make the compiler smaller, and rebuilds after changes faster.
26 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
27 ;; sequences. Especially the sequences for arithmetic right shifts.
29 ;; ??? Should check all DImode patterns for consistency and usefulness.
31 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
32 ;; way to generate them.
34 ;; BSR is not generated by the compiler proper, but when relaxing, it
35 ;; generates .uses pseudo-ops that allow linker relaxation to create
36 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
38 ;; Special constraints for SH machine description:
45 ;; Special formats used for outputting SH instructions:
47 ;; %. -- print a .s if insn needs delay slot
48 ;; %@ -- print rte/rts if is/isn't an interrupt function
49 ;; %# -- output a nop if there is nothing to put in the delay slot
50 ;; %O -- print a constant without the #
51 ;; %R -- print the lsw reg of a double
52 ;; %S -- print the msw reg of a double
53 ;; %T -- print next word of a double REG or MEM
55 ;; Special predicates:
57 ;; arith_operand -- operand is valid source for arithmetic op
58 ;; arith_reg_operand -- operand is valid register for arithmetic op
59 ;; general_movdst_operand -- operand is valid move destination
60 ;; general_movsrc_operand -- operand is valid move source
61 ;; logical_operand -- operand is valid source for logical op
63 ;; -------------------------------------------------------------------------
65 ;; -------------------------------------------------------------------------
113 ;; These are used with unspec.
114 (UNSPEC_COMPACT_ARGS 0)
127 (UNSPEC_INIT_TRAMP 13)
140 (UNSPEC_DIV_INV_M0 30)
141 (UNSPEC_DIV_INV_M1 31)
142 (UNSPEC_DIV_INV_M2 32)
143 (UNSPEC_DIV_INV_M3 33)
144 (UNSPEC_DIV_INV20 34)
145 (UNSPEC_DIV_INV_TABLE 37)
153 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
154 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
155 (UNSPEC_EXTRACT_S16 43)
156 (UNSPEC_EXTRACT_U16 44)
158 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
161 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
162 (UNSPEC_PCREL_SYMOFF 46)
165 (UNSPEC_BUILTIN_STRLEN 47)
167 ;; These are used with unspec_volatile.
173 (UNSPECV_WINDOW_END 10)
174 (UNSPECV_CONST_END 11)
175 (UNSPECV_EH_RETURN 12)
177 (UNSPECV_SP_SWITCH_B 14)
178 (UNSPECV_SP_SWITCH_E 15)
181 ;; -------------------------------------------------------------------------
183 ;; -------------------------------------------------------------------------
188 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
189 (const (symbol_ref "sh_cpu_attr")))
191 (define_attr "endian" "big,little"
192 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
193 (const_string "little") (const_string "big"))))
195 ;; Indicate if the default fpu mode is single precision.
196 (define_attr "fpu_single" "yes,no"
197 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
198 (const_string "yes") (const_string "no"))))
200 (define_attr "fmovd" "yes,no"
201 (const (if_then_else (symbol_ref "TARGET_FMOVD")
202 (const_string "yes") (const_string "no"))))
204 (define_attr "pipe_model" "sh1,sh4,sh5media"
206 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
207 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
208 (const_string "sh1"))))
210 ;; cbranch conditional branch instructions
211 ;; jump unconditional jumps
212 ;; arith ordinary arithmetic
213 ;; arith3 a compound insn that behaves similarly to a sequence of
214 ;; three insns of type arith
215 ;; arith3b like above, but might end with a redirected branch
217 ;; load_si Likewise, SImode variant for general register.
218 ;; fload Likewise, but load to fp register.
220 ;; fstore floating point register to memory
221 ;; move general purpose register to register
222 ;; movi8 8-bit immediate to general purpose register
223 ;; mt_group other sh4 mt instructions
224 ;; fmove register to register, floating point
225 ;; smpy word precision integer multiply
226 ;; dmpy longword or doublelongword precision integer multiply
228 ;; pload load of pr reg, which can't be put into delay slot of rts
229 ;; prset copy register to pr reg, ditto
230 ;; pstore store of pr reg, which can't be put into delay slot of jsr
231 ;; prget copy pr to register, ditto
232 ;; pcload pc relative load of constant value
233 ;; pcfload Likewise, but load to fp register.
234 ;; pcload_si Likewise, SImode variant for general register.
235 ;; rte return from exception
236 ;; sfunc special function call with known used registers
237 ;; call function call
239 ;; fpscr_toggle toggle a bit in the fpscr
240 ;; fdiv floating point divide (or square root)
241 ;; gp_fpul move from general purpose register to fpul
242 ;; fpul_gp move from fpul to general purpose register
243 ;; mac_gp move from mac[lh] to general purpose register
244 ;; gp_mac move from general purpose register to mac[lh]
245 ;; mac_mem move from mac[lh] to memory
246 ;; mem_mac move from memory to mac[lh]
247 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
248 ;; ftrc_s fix_truncsfsi2_i4
249 ;; dfdiv double precision floating point divide (or square root)
250 ;; cwb ic_invalidate_line_i
251 ;; movua SH4a unaligned load
252 ;; fsrra square root reciprocal approximate
253 ;; fsca sine and cosine approximate
254 ;; tls_load load TLS related address
255 ;; arith_media SHmedia arithmetic, logical, and shift instructions
256 ;; cbranch_media SHmedia conditional branch instructions
257 ;; cmp_media SHmedia compare instructions
258 ;; dfdiv_media SHmedia double precision divide and square root
259 ;; dfmul_media SHmedia double precision multiply instruction
260 ;; dfparith_media SHmedia double precision floating point arithmetic
261 ;; dfpconv_media SHmedia double precision floating point conversions
262 ;; dmpy_media SHmedia longword multiply
263 ;; fcmp_media SHmedia floating point compare instructions
264 ;; fdiv_media SHmedia single precision divide and square root
265 ;; fload_media SHmedia floating point register load instructions
266 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
267 ;; fparith_media SHmedia single precision floating point arithmetic
268 ;; fpconv_media SHmedia single precision floating point conversions
269 ;; fstore_media SHmedia floating point register store instructions
270 ;; gettr_media SHmedia gettr instruction
271 ;; invalidate_line_media SHmedia invalidate_line sequence
272 ;; jump_media SHmedia unconditional branch instructions
273 ;; load_media SHmedia general register load instructions
274 ;; pt_media SHmedia pt instruction (expanded by assembler)
275 ;; ptabs_media SHmedia ptabs instruction
276 ;; store_media SHmedia general register store instructions
277 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
278 ;; mac_media SHmedia mac-style fixed point operations
279 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
280 ;; atrans_media SHmedia approximate transcendental functions
281 ;; ustore_media SHmedia unaligned stores
282 ;; nil no-op move, will be deleted.
285 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,
286 fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,
287 prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,
288 dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,
289 gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,
290 arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,
291 dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,
292 fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,
293 jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,
294 d2mpy_media,atrans_media,ustore_media,nil,other"
295 (const_string "other"))
297 ;; We define a new attribute namely "insn_class".We use
298 ;; this for the DFA based pipeline description.
300 ;; mt_group SH4 "mt" group instructions.
302 ;; ex_group SH4 "ex" group instructions.
304 ;; ls_group SH4 "ls" group instructions.
306 (define_attr "insn_class"
307 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
308 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
309 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
310 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,
311 store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
312 (eq_attr "type" "cbranch,jump") (const_string "br_group")
313 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
314 (const_string "fe_group")
315 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,
316 prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,
317 gp_mac,mac_mem,mem_mac") (const_string "co_group")]
318 (const_string "none")))
320 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
321 ;; so these do not belong in an insn group, although they are modeled
322 ;; with their own define_insn_reservations.
324 ;; Indicate what precision must be selected in fpscr for this insn, if any.
325 (define_attr "fp_mode" "single,double,none" (const_string "none"))
327 ;; Indicate if the fpu mode is set by this instruction
328 ;; "unknown" must have the value as "none" in fp_mode, and means
329 ;; that the instruction/abi has left the processor in an unknown
331 ;; "none" means that nothing has changed and no mode is set.
332 ;; This attribute is only used for the Renesas ABI.
333 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
335 ; If a conditional branch destination is within -252..258 bytes away
336 ; from the instruction it can be 2 bytes long. Something in the
337 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
338 ; branches are initially assumed to be 16 bytes long.
339 ; In machine_dependent_reorg, we split all branches that are longer than
342 ;; The maximum range used for SImode constant pool entries is 1018. A final
343 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
344 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
345 ;; instruction around the pool table, 2 bytes of alignment before the table,
346 ;; and 30 bytes of alignment after the table. That gives a maximum total
347 ;; pool size of 1058 bytes.
348 ;; Worst case code/pool content size ratio is 1:2 (using asms).
349 ;; Thus, in the worst case, there is one instruction in front of a maximum
350 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
351 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
352 ;; If we have a forward branch, the initial table will be put after the
353 ;; unconditional branch.
355 ;; ??? We could do much better by keeping track of the actual pcloads within
356 ;; the branch range and in the pcload range in front of the branch range.
358 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
360 (define_attr "short_cbranch_p" "no,yes"
361 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
363 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
365 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
367 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
369 ] (const_string "no")))
371 (define_attr "med_branch_p" "no,yes"
372 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
375 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
380 ] (const_string "no")))
382 (define_attr "med_cbranch_p" "no,yes"
383 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
386 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
388 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
391 ] (const_string "no")))
393 (define_attr "braf_branch_p" "no,yes"
394 (cond [(match_test "! TARGET_SH2")
396 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
399 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
404 ] (const_string "no")))
406 (define_attr "braf_cbranch_p" "no,yes"
407 (cond [(match_test "! TARGET_SH2")
409 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
412 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
414 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
417 ] (const_string "no")))
419 ;; An unconditional jump in the range -4092..4098 can be 2 bytes long.
420 ;; For wider ranges, we need a combination of a code and a data part.
421 ;; If we can get a scratch register for a long range jump, the code
422 ;; part can be 4 bytes long; otherwise, it must be 8 bytes long.
423 ;; If the jump is in the range -32764..32770, the data part can be 2 bytes
424 ;; long; otherwise, it must be 6 bytes long.
426 ;; All other instructions are two bytes long by default.
428 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
429 ;; but getattrtab doesn't understand this.
430 (define_attr "length" ""
431 (cond [(eq_attr "type" "cbranch")
432 (cond [(eq_attr "short_cbranch_p" "yes")
434 (eq_attr "med_cbranch_p" "yes")
436 (eq_attr "braf_cbranch_p" "yes")
438 ;; ??? using pc is not computed transitively.
439 (ne (match_dup 0) (match_dup 0))
441 (match_test "flag_pic")
444 (eq_attr "type" "jump")
445 (cond [(eq_attr "med_branch_p" "yes")
447 (and (match_test "prev_nonnote_insn (insn)")
448 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
450 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
451 (symbol_ref "code_for_indirect_jump_scratch"))))
452 (cond [(eq_attr "braf_branch_p" "yes")
454 (not (match_test "flag_pic"))
456 (match_test "TARGET_SH2")
457 (const_int 10)] (const_int 18))
458 (eq_attr "braf_branch_p" "yes")
460 ;; ??? using pc is not computed transitively.
461 (ne (match_dup 0) (match_dup 0))
463 (match_test "flag_pic")
466 (eq_attr "type" "pt_media")
467 (if_then_else (match_test "TARGET_SHMEDIA64")
468 (const_int 20) (const_int 12))
469 (and (eq_attr "type" "jump_media")
470 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
472 ] (if_then_else (match_test "TARGET_SHMEDIA")
476 ;; DFA descriptions for the pipelines
479 (include "shmedia.md")
482 (include "iterators.md")
483 (include "predicates.md")
484 (include "constraints.md")
486 ;; Definitions for filling delay slots
488 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
490 (define_attr "banked" "yes,no"
491 (cond [(match_test "sh_loads_bankedreg_p (insn)")
492 (const_string "yes")]
493 (const_string "no")))
495 ;; ??? This should be (nil) instead of (const_int 0)
496 (define_attr "hit_stack" "yes,no"
497 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
499 (const_string "yes")))
501 (define_attr "interrupt_function" "no,yes"
502 (const (symbol_ref "current_function_interrupt")))
504 (define_attr "in_delay_slot" "yes,no"
505 (cond [(eq_attr "type" "cbranch") (const_string "no")
506 (eq_attr "type" "pcload,pcload_si") (const_string "no")
507 (eq_attr "needs_delay_slot" "yes") (const_string "no")
508 (eq_attr "length" "2") (const_string "yes")
509 ] (const_string "no")))
511 (define_attr "cond_delay_slot" "yes,no"
512 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
513 ] (const_string "no")))
515 (define_attr "is_sfunc" ""
516 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
518 (define_attr "is_mac_media" ""
519 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
521 (define_attr "branch_zero" "yes,no"
522 (cond [(eq_attr "type" "!cbranch") (const_string "no")
523 (ne (symbol_ref "(next_active_insn (insn)\
524 == (prev_active_insn\
525 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
526 && get_attr_length (next_active_insn (insn)) == 2")
528 (const_string "yes")]
529 (const_string "no")))
531 ;; SH4 Double-precision computation with double-precision result -
532 ;; the two halves are ready at different times.
533 (define_attr "dfp_comp" "yes,no"
534 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
535 (const_string "no")))
537 ;; Insns for which the latency of a preceding fp insn is decreased by one.
538 (define_attr "late_fp_use" "yes,no" (const_string "no"))
539 ;; And feeding insns for which this relevant.
540 (define_attr "any_fp_comp" "yes,no"
541 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
542 (const_string "yes")]
543 (const_string "no")))
545 (define_attr "any_int_load" "yes,no"
546 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
547 (const_string "yes")]
548 (const_string "no")))
550 (define_attr "highpart" "user, ignore, extend, depend, must_split"
551 (const_string "user"))
554 (eq_attr "needs_delay_slot" "yes")
555 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
557 ;; Since a normal return (rts) implicitly uses the PR register,
558 ;; we can't allow PR register loads in an rts delay slot.
559 ;; On the SH1* and SH2*, the rte instruction reads the return pc from the
560 ;; stack, and thus we can't put a pop instruction in its delay slot.
561 ;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
562 ;; pop instruction can go in the delay slot, unless it references a banked
563 ;; register (the register bank is switched by rte).
565 (eq_attr "type" "return")
566 [(and (eq_attr "in_delay_slot" "yes")
567 (ior (and (eq_attr "interrupt_function" "no")
568 (eq_attr "type" "!pload,prset"))
569 (and (eq_attr "interrupt_function" "yes")
570 (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
571 (eq_attr "banked" "no"))))
574 ;; Since a call implicitly uses the PR register, we can't allow
575 ;; a PR register store in a jsr delay slot.
578 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
579 [(and (eq_attr "in_delay_slot" "yes")
580 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
582 ;; Say that we have annulled true branches, since this gives smaller and
583 ;; faster code when branches are predicted as not taken.
585 ;; ??? The non-annulled condition should really be "in_delay_slot",
586 ;; but insns that can be filled in non-annulled get priority over insns
587 ;; that can only be filled in anulled.
590 (and (eq_attr "type" "cbranch")
591 (match_test "TARGET_SH2"))
592 ;; SH2e has a hardware bug that pretty much prohibits the use of
593 ;; annulled delay slots.
594 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
595 (not (eq_attr "cpu" "sh2e"))) (nil)])
597 ;; -------------------------------------------------------------------------
598 ;; SImode signed integer comparisons
599 ;; -------------------------------------------------------------------------
601 ;; Various patterns to generate the TST #imm, R0 instruction.
602 ;; Although this adds some pressure on the R0 register, it can potentially
603 ;; result in faster code, even if the operand has to be moved to R0 first.
604 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group
605 ;; instructions and thus will be executed in parallel. On SH4A TST #imm, R0
606 ;; is an EX group instruction but still can be executed in parallel with the
607 ;; MT group MOV Rm, Rn instruction.
609 ;; Usual TST #imm, R0 patterns for SI, HI and QI
610 ;; This is usually used for bit patterns other than contiguous bits
612 (define_insn "tstsi_t"
614 (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
615 (match_operand:SI 1 "logical_operand" "K08,r"))
619 [(set_attr "type" "mt_group")])
621 (define_insn "tsthi_t"
623 (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
624 (match_operand 1 "const_int_operand")) 0)
627 && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
629 [(set_attr "type" "mt_group")])
631 (define_insn "tstqi_t"
633 (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
634 (match_operand 1 "const_int_operand")) 0)
637 && (CONST_OK_FOR_K08 (INTVAL (operands[1]))
638 || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
640 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
643 [(set_attr "type" "mt_group")])
645 ;; Test low QI subreg against zero.
646 ;; This avoids unnecessary zero extension before the test.
647 (define_insn "*tstqi_t_zero"
649 (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
652 [(set_attr "type" "mt_group")])
654 ;; This pattern might be risky because it also tests the upper bits and not
655 ;; only the subreg. However, it seems that combine will get to this only
656 ;; when testing sign/zero extended values. In this case the extended upper
657 ;; bits do not matter.
658 (define_insn "*tst<mode>_t_zero"
662 (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
663 (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_le>)
665 "TARGET_SH1 && TARGET_LITTLE_ENDIAN"
667 [(set_attr "type" "mt_group")])
669 (define_insn "*tst<mode>_t_zero"
673 (and:SI (match_operand:SI 0 "arith_reg_operand" "%r")
674 (match_operand:SI 1 "arith_reg_operand" "r")) <lowpart_be>)
676 "TARGET_SH1 && TARGET_BIG_ENDIAN"
678 [(set_attr "type" "mt_group")])
680 ;; Extract LSB, negate and store in T bit.
681 (define_insn "tstsi_t_and_not"
683 (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
687 [(set_attr "type" "mt_group")])
689 ;; Extract contiguous bits and compare them against zero.
690 (define_insn "tst<mode>_t_zero_extract_eq"
692 (eq:SI (zero_extract:SI (match_operand:QIHISIDI 0 "logical_operand" "z")
693 (match_operand:SI 1 "const_int_operand")
694 (match_operand:SI 2 "const_int_operand"))
697 && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
699 operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
702 [(set_attr "type" "mt_group")])
704 ;; This split is required when testing bits in a QI subreg.
709 (zero_extract:SI (match_operand 0 "logical_operand")
710 (match_operand 1 "const_int_operand")
711 (match_operand 2 "const_int_operand"))
712 (match_operand 3 "const_int_operand")
716 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
717 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
718 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
721 if (GET_MODE (operands[0]) == QImode)
722 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
725 ;; Extract single bit, negate and store it in the T bit.
726 ;; Not used for SH4A.
727 (define_insn "tstsi_t_zero_extract_xor"
729 (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
730 (match_operand:SI 3 "const_int_operand"))
731 (match_operand:SI 1 "const_int_operand")
732 (match_operand:SI 2 "const_int_operand")))]
734 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
735 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
737 [(set_attr "type" "mt_group")])
739 ;; Extract single bit, negate and store it in the T bit.
740 ;; Used for SH4A little endian.
741 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
744 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
745 (match_operand:SI 3 "const_int_operand")) 0)
746 (match_operand:SI 1 "const_int_operand")
747 (match_operand:SI 2 "const_int_operand")))]
748 "TARGET_SH1 && TARGET_LITTLE_ENDIAN
749 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
750 == (INTVAL (operands[3]) & 255)
751 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
753 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
756 [(set_attr "type" "mt_group")])
758 ;; Extract single bit, negate and store it in the T bit.
759 ;; Used for SH4A big endian.
760 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
763 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
764 (match_operand:SI 3 "const_int_operand")) 3)
765 (match_operand:SI 1 "const_int_operand")
766 (match_operand:SI 2 "const_int_operand")))]
767 "TARGET_SH1 && TARGET_BIG_ENDIAN
768 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
769 == (INTVAL (operands[3]) & 255)
770 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
772 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
775 [(set_attr "type" "mt_group")])
777 (define_insn "cmpeqsi_t"
779 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
780 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
786 [(set_attr "type" "mt_group")])
788 ;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
789 ;; pattern by itself. What this actually does is:
790 ;; x == 0: (1 >> 0-0) & 1 = 1
791 ;; x != 0: (1 >> 0-x) & 1 = 0
792 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
793 (define_insn_and_split "*cmpeqsi_t"
797 (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
802 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
804 (define_insn "cmpgtsi_t"
806 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
807 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
812 [(set_attr "type" "mt_group")])
814 (define_insn "cmpgesi_t"
816 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
817 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
822 [(set_attr "type" "mt_group")])
824 ;; FIXME: This is actually wrong. There is no way to literally move a
825 ;; general reg to t reg. Luckily, it seems that this pattern will be only
826 ;; used when the general reg is known be either '0' or '1' during combine.
827 ;; What we actually need is reg != 0 -> T, but we have only reg == 0 -> T.
828 ;; Due to interactions with other patterns, combine fails to pick the latter
829 ;; and invert the dependent logic.
830 (define_insn "*negtstsi"
831 [(set (reg:SI T_REG) (match_operand:SI 0 "arith_reg_operand" "r"))]
834 [(set_attr "type" "mt_group")])
836 ;; Some integer sign comparison patterns can be realized with the div0s insn.
837 ;; div0s Rm,Rn T = (Rm >> 31) ^ (Rn >> 31)
838 (define_insn "cmp_div0s_0"
840 (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
841 (match_operand:SI 1 "arith_reg_operand" "r"))
845 [(set_attr "type" "arith")])
847 (define_insn "cmp_div0s_1"
849 (lt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
850 (match_operand:SI 1 "arith_reg_operand" "r"))
854 [(set_attr "type" "arith")])
856 (define_insn_and_split "*cmp_div0s_0"
857 [(set (match_operand:SI 0 "arith_reg_dest" "")
858 (lshiftrt:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
859 (match_operand:SI 2 "arith_reg_operand" ""))
861 (clobber (reg:SI T_REG))]
866 (lshiftrt:SI (xor:SI (match_dup 1) (match_dup 2)) (const_int 31)))
867 (set (match_dup 0) (reg:SI T_REG))])
869 (define_insn "*cmp_div0s_0"
871 (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
873 (ge:SI (match_operand:SI 1 "arith_reg_operand")
877 [(set_attr "type" "arith")])
879 (define_insn_and_split "*cmp_div0s_1"
880 [(set (match_operand:SI 0 "arith_reg_dest" "")
881 (ge:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
882 (match_operand:SI 2 "arith_reg_operand" ""))
884 (clobber (reg:SI T_REG))]
887 "&& can_create_pseudo_p ()"
889 ;; We have to go through the movnegt expander here which will handle the
890 ;; SH2A vs non-SH2A cases.
892 emit_insn (gen_cmp_div0s_1 (operands[1], operands[2]));
893 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
897 (define_insn_and_split "*cmp_div0s_1"
899 (ge:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
900 (match_operand:SI 1 "arith_reg_operand" ""))
904 "&& can_create_pseudo_p ()"
905 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
907 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
909 (define_insn_and_split "*cmp_div0s_1"
911 (eq:SI (lshiftrt:SI (match_operand:SI 0 "arith_reg_operand")
913 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
917 "&& can_create_pseudo_p ()"
918 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
920 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
922 ;; -------------------------------------------------------------------------
923 ;; SImode compare and branch
924 ;; -------------------------------------------------------------------------
926 (define_expand "cbranchsi4"
928 (if_then_else (match_operator 0 "comparison_operator"
929 [(match_operand:SI 1 "arith_operand" "")
930 (match_operand:SI 2 "arith_operand" "")])
931 (label_ref (match_operand 3 "" ""))
933 (clobber (reg:SI T_REG))]
937 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
938 operands[2], operands[3]));
940 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
945 ;; Combine patterns to invert compare and branch operations for which we
946 ;; don't have actual comparison insns. These patterns are used in cases
947 ;; which appear after the initial cbranchsi expansion, which also does
948 ;; some condition inversion.
951 (if_then_else (ne (match_operand:SI 0 "arith_reg_operand" "")
952 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
953 (label_ref (match_operand 2))
955 (clobber (reg:SI T_REG))]
957 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (match_dup 1)))
958 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
959 (label_ref (match_dup 2))
962 ;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
963 ;; and SH2A combine fails to simplify this pattern by itself.
964 ;; What this actually does is:
965 ;; x == 0: (1 >> 0-0) & 1 = 1
966 ;; x != 0: (1 >> 0-x) & 1 = 0
967 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
971 (eq (and:SI (lshiftrt:SI
973 (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
976 (label_ref (match_operand 2))
978 (clobber (reg:SI T_REG))]
980 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
981 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
982 (label_ref (match_dup 2))
985 ;; FIXME: These could probably use code iterators for the compare op.
988 (if_then_else (le (match_operand:SI 0 "arith_reg_operand" "")
989 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
990 (label_ref (match_operand 2))
992 (clobber (reg:SI T_REG))]
994 [(set (reg:SI T_REG) (gt:SI (match_dup 0) (match_dup 1)))
995 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
996 (label_ref (match_dup 2))
1001 (if_then_else (lt (match_operand:SI 0 "arith_reg_operand" "")
1002 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1003 (label_ref (match_operand 2))
1005 (clobber (reg:SI T_REG))]
1007 [(set (reg:SI T_REG) (ge:SI (match_dup 0) (match_dup 1)))
1008 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1009 (label_ref (match_dup 2))
1014 (if_then_else (leu (match_operand:SI 0 "arith_reg_operand" "")
1015 (match_operand:SI 1 "arith_reg_operand" ""))
1016 (label_ref (match_operand 2))
1018 (clobber (reg:SI T_REG))]
1020 [(set (reg:SI T_REG) (gtu:SI (match_dup 0) (match_dup 1)))
1021 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1022 (label_ref (match_dup 2))
1027 (if_then_else (ltu (match_operand:SI 0 "arith_reg_operand" "")
1028 (match_operand:SI 1 "arith_reg_operand" ""))
1029 (label_ref (match_operand 2))
1031 (clobber (reg:SI T_REG))]
1033 [(set (reg:SI T_REG) (geu:SI (match_dup 0) (match_dup 1)))
1034 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1035 (label_ref (match_dup 2))
1038 ;; Compare and branch combine patterns for div0s comparisons.
1039 (define_insn_and_split "*cbranch_div0s"
1041 (if_then_else (lt (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1042 (match_operand:SI 1 "arith_reg_operand" ""))
1044 (label_ref (match_operand 2))
1046 (clobber (reg:SI T_REG))]
1050 [(set (reg:SI T_REG)
1051 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1053 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1054 (label_ref (match_dup 2))
1057 (define_insn_and_split "*cbranch_div0s"
1059 (if_then_else (ge (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1060 (match_operand:SI 1 "arith_reg_operand" ""))
1062 (label_ref (match_operand 2))
1064 (clobber (reg:SI T_REG))]
1068 [(set (reg:SI T_REG)
1069 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1071 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1072 (label_ref (match_dup 2))
1075 ;; Conditional move combine pattern for div0s comparisons.
1076 ;; This is used when TARGET_PRETEND_CMOVE is in effect.
1077 (define_insn_and_split "*movsicc_div0s"
1078 [(set (match_operand:SI 0 "arith_reg_dest" "")
1079 (if_then_else:SI (ge (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
1080 (match_operand:SI 2 "arith_reg_operand" ""))
1082 (match_operand:SI 3 "arith_reg_operand" "")
1083 (match_operand:SI 4 "general_movsrc_operand" "")))
1084 (clobber (reg:SI T_REG))]
1085 "TARGET_PRETEND_CMOVE"
1088 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1091 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1095 (define_insn_and_split "*movsicc_div0s"
1096 [(set (match_operand:SI 0 "arith_reg_dest")
1097 (if_then_else:SI (eq (lshiftrt:SI
1098 (match_operand:SI 1 "arith_reg_operand")
1101 (match_operand:SI 2 "arith_reg_operand")
1103 (match_operand:SI 3 "arith_reg_operand")
1104 (match_operand:SI 4 "general_movsrc_operand")))
1105 (clobber (reg:SI T_REG))]
1106 "TARGET_PRETEND_CMOVE"
1109 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1112 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1116 ;; -------------------------------------------------------------------------
1117 ;; SImode unsigned integer comparisons
1118 ;; -------------------------------------------------------------------------
1120 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1121 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1122 ;; might remain and we have to handle them. If the '>= 0' case wasn't
1123 ;; handled here, something else would just load a '0' into the second operand
1124 ;; and do the comparison. We can do slightly better by just setting the
1126 (define_insn_and_split "cmpgeusi_t"
1127 [(set (reg:SI T_REG)
1128 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1129 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1132 "&& satisfies_constraint_Z (operands[1])"
1133 [(set (reg:SI T_REG) (const_int 1))]
1135 [(set_attr "type" "mt_group")])
1137 (define_insn "cmpgtusi_t"
1138 [(set (reg:SI T_REG)
1139 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1140 (match_operand:SI 1 "arith_reg_operand" "r")))]
1143 [(set_attr "type" "mt_group")])
1145 ;; -------------------------------------------------------------------------
1146 ;; DImode compare and branch
1147 ;; -------------------------------------------------------------------------
1149 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1150 ;; Therefore, we aim to have a set of three branches that go straight to the
1151 ;; destination, i.e. only one of them is taken at any one time.
1152 ;; This mechanism should also be slightly better for the sh4-200.
1154 (define_expand "cbranchdi4"
1156 (if_then_else (match_operator 0 "comparison_operator"
1157 [(match_operand:DI 1 "arith_operand" "")
1158 (match_operand:DI 2 "arith_operand" "")])
1159 (label_ref (match_operand 3 "" ""))
1161 (clobber (match_dup 4))
1162 (clobber (reg:SI T_REG))]
1163 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1165 enum rtx_code comparison;
1169 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1170 operands[2], operands[3]));
1173 else if (!TARGET_CBRANCHDI4)
1175 sh_emit_compare_and_branch (operands, DImode);
1180 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1183 comparison = prepare_cbranch_operands (operands, DImode,
1184 LAST_AND_UNUSED_RTX_CODE);
1185 if (comparison != GET_CODE (operands[0]))
1187 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1188 operands[4] = gen_rtx_SCRATCH (SImode);
1192 (define_insn_and_split "cbranchdi4_i"
1194 (if_then_else (match_operator 0 "comparison_operator"
1195 [(match_operand:DI 1 "arith_operand" "r,r")
1196 (match_operand:DI 2 "arith_operand" "rN,I08")])
1197 (label_ref (match_operand 3 "" ""))
1199 (clobber (match_scratch:SI 4 "=X,&r"))
1200 (clobber (reg:SI T_REG))]
1203 "&& reload_completed"
1206 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1211 ;; -------------------------------------------------------------------------
1212 ;; DImode signed integer comparisons
1213 ;; -------------------------------------------------------------------------
1216 [(set (reg:SI T_REG)
1217 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1218 (match_operand:DI 1 "arith_operand" "r"))
1222 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1225 [(set_attr "length" "6")
1226 (set_attr "type" "arith3b")])
1228 (define_insn "cmpeqdi_t"
1229 [(set (reg:SI T_REG)
1230 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1231 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1234 static const char* alt[] =
1241 "cmp/eq %S1,%S0" "\n"
1243 " cmp/eq %R1,%R0" "\n"
1246 return alt[which_alternative];
1248 [(set_attr "length" "6")
1249 (set_attr "type" "arith3b")])
1252 [(set (reg:SI T_REG)
1253 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1254 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1255 ;; If we applied this split when not optimizing, it would only be
1256 ;; applied during the machine-dependent reorg, when no new basic blocks
1258 "TARGET_SH1 && reload_completed && optimize"
1259 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1260 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1261 (label_ref (match_dup 6))
1263 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1266 operands[2] = gen_highpart (SImode, operands[0]);
1267 operands[3] = operands[1] == const0_rtx
1269 : gen_highpart (SImode, operands[1]);
1270 operands[4] = gen_lowpart (SImode, operands[0]);
1271 operands[5] = gen_lowpart (SImode, operands[1]);
1272 operands[6] = gen_label_rtx ();
1275 (define_insn "cmpgtdi_t"
1276 [(set (reg:SI T_REG)
1277 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1278 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1281 static const char* alt[] =
1283 "cmp/eq %S1,%S0" "\n"
1285 " cmp/gt %S1,%S0" "\n"
1286 " cmp/hi %R1,%R0" "\n"
1292 " cmp/hi %S0,%R0" "\n"
1295 return alt[which_alternative];
1297 [(set_attr "length" "8")
1298 (set_attr "type" "arith3")])
1300 (define_insn "cmpgedi_t"
1301 [(set (reg:SI T_REG)
1302 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1303 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1306 static const char* alt[] =
1308 "cmp/eq %S1,%S0" "\n"
1310 " cmp/ge %S1,%S0" "\n"
1311 " cmp/hs %R1,%R0" "\n"
1316 return alt[which_alternative];
1318 [(set_attr "length" "8,2")
1319 (set_attr "type" "arith3,mt_group")])
1321 ;; -------------------------------------------------------------------------
1322 ;; DImode unsigned integer comparisons
1323 ;; -------------------------------------------------------------------------
1325 (define_insn "cmpgeudi_t"
1326 [(set (reg:SI T_REG)
1327 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1328 (match_operand:DI 1 "arith_reg_operand" "r")))]
1331 return "cmp/eq %S1,%S0" "\n"
1333 " cmp/hs %S1,%S0" "\n"
1334 " cmp/hs %R1,%R0" "\n"
1337 [(set_attr "length" "8")
1338 (set_attr "type" "arith3")])
1340 (define_insn "cmpgtudi_t"
1341 [(set (reg:SI T_REG)
1342 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1343 (match_operand:DI 1 "arith_reg_operand" "r")))]
1346 return "cmp/eq %S1,%S0" "\n"
1348 " cmp/hi %S1,%S0" "\n"
1349 " cmp/hi %R1,%R0" "\n"
1352 [(set_attr "length" "8")
1353 (set_attr "type" "arith3")])
1355 (define_insn "cmpeqsi_media"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1358 (match_operand:SI 2 "cmp_operand" "Nr")))]
1361 [(set_attr "type" "cmp_media")])
1363 (define_insn "cmpeqdi_media"
1364 [(set (match_operand:SI 0 "register_operand" "=r")
1365 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1366 (match_operand:DI 2 "cmp_operand" "Nr")))]
1369 [(set_attr "type" "cmp_media")])
1371 (define_insn "cmpgtsi_media"
1372 [(set (match_operand:SI 0 "register_operand" "=r")
1373 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1374 (match_operand:SI 2 "cmp_operand" "rN")))]
1376 "cmpgt %N1, %N2, %0"
1377 [(set_attr "type" "cmp_media")])
1379 (define_insn "cmpgtdi_media"
1380 [(set (match_operand:SI 0 "register_operand" "=r")
1381 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1382 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1384 "cmpgt %N1, %N2, %0"
1385 [(set_attr "type" "cmp_media")])
1387 (define_insn "cmpgtusi_media"
1388 [(set (match_operand:SI 0 "register_operand" "=r")
1389 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1390 (match_operand:SI 2 "cmp_operand" "rN")))]
1392 "cmpgtu %N1, %N2, %0"
1393 [(set_attr "type" "cmp_media")])
1395 (define_insn "cmpgtudi_media"
1396 [(set (match_operand:SI 0 "register_operand" "=r")
1397 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1398 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1400 "cmpgtu %N1, %N2, %0"
1401 [(set_attr "type" "cmp_media")])
1403 ; This pattern is for combine.
1404 (define_insn "*cmpne0sisi_media"
1405 [(set (match_operand:SI 0 "register_operand" "=r")
1406 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1409 [(set_attr "type" "cmp_media")])
1411 ;; -------------------------------------------------------------------------
1412 ;; Conditional move instructions
1413 ;; -------------------------------------------------------------------------
1415 ;; The insn names may seem reversed, but note that cmveq performs the move
1416 ;; if op1 == 0, and cmvne does it if op1 != 0.
1418 (define_insn "movdicc_false"
1419 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1420 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1422 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1423 (match_operand:DI 3 "arith_reg_operand" "0")))]
1426 [(set_attr "type" "arith_media")])
1428 (define_insn "movdicc_true"
1429 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1430 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1432 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1433 (match_operand:DI 3 "arith_reg_operand" "0")))]
1436 [(set_attr "type" "arith_media")])
1439 [(set (match_operand:DI 0 "arith_reg_dest" "")
1440 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1441 [(match_operand:DI 1 "arith_reg_operand" "")
1443 (match_operand:DI 2 "arith_reg_dest" "")
1445 (set (match_dup 2) (match_dup 0))]
1446 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1448 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1450 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1451 VOIDmode, operands[1], CONST0_RTX (DImode));
1455 [(set (match_operand:DI 0 "general_movdst_operand" "")
1456 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1457 (set (match_operand:DI 2 "arith_reg_dest" "")
1458 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1459 [(match_operand:DI 3 "arith_reg_operand" "")
1463 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1465 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1468 (define_expand "movdicc"
1469 [(set (match_operand:DI 0 "register_operand" "")
1470 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1471 (match_operand:DI 2 "register_operand" "")
1472 (match_operand:DI 3 "register_operand" "")))]
1475 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1476 && GET_MODE (XEXP (operands[1], 0)) == DImode
1477 && XEXP (operands[1], 1) == const0_rtx)
1481 if (!can_create_pseudo_p ())
1484 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1485 GET_CODE (operands[1]),
1486 XEXP (operands[1], 0),
1487 XEXP (operands[1], 1));
1493 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1494 ;; SImode to DImode.
1495 (define_insn "movsicc_false"
1496 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1497 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1499 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1500 (match_operand:SI 3 "arith_reg_operand" "0")))]
1503 [(set_attr "type" "arith_media")])
1505 (define_insn "movsicc_true"
1506 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1507 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1509 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1510 (match_operand:SI 3 "arith_reg_operand" "0")))]
1513 [(set_attr "type" "arith_media")])
1516 [(set (match_operand:SI 0 "arith_reg_dest" "")
1517 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1518 [(match_operand:SI 1 "arith_reg_operand" "")
1520 (match_operand:SI 2 "arith_reg_dest" "")
1522 (set (match_dup 2) (match_dup 0))]
1523 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1525 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1527 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1528 VOIDmode, operands[1], CONST0_RTX (SImode));
1532 [(set (match_operand:SI 0 "general_movdst_operand" "")
1533 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1534 (set (match_operand:SI 2 "arith_reg_dest" "")
1535 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1536 [(match_operand:SI 3 "arith_reg_operand" "")
1540 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1541 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1543 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1545 replace_rtx (operands[4], operands[0], operands[1]);
1549 [(set (match_operand 0 "any_register_operand" "")
1550 (match_operand 1 "any_register_operand" ""))
1551 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1552 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1553 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1554 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1555 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1556 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1557 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1558 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1559 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1560 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1561 && (REGNO_REG_CLASS (REGNO (operands[0]))
1562 == REGNO_REG_CLASS (REGNO (operands[2])))
1563 && (REGNO_REG_CLASS (REGNO (operands[1]))
1564 == REGNO_REG_CLASS (REGNO (operands[0])))"
1565 [(set (match_dup 0) (match_dup 3))
1566 (set (match_dup 4) (match_dup 5))]
1568 rtx set1, set2, insn2;
1569 rtx replacements[4];
1571 /* We want to replace occurrences of operands[0] with operands[1] and
1572 operands[2] with operands[0] in operands[4]/operands[5].
1573 Doing just two replace_rtx calls naively would result in the second
1574 replacement undoing all that the first did if operands[1] and operands[2]
1575 are identical, so we must do this simultaneously. */
1576 replacements[0] = operands[0];
1577 replacements[1] = operands[1];
1578 replacements[2] = operands[2];
1579 replacements[3] = operands[0];
1580 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1581 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1582 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1585 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1586 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1587 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1588 /* The operands array is aliased to recog_data.operand, which gets
1589 clobbered by extract_insn, so finish with it now. */
1590 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1591 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1592 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1593 always uses emit_insn. */
1594 /* Check that we don't violate matching constraints or earlyclobbers. */
1595 extract_insn (emit_insn (set1));
1596 if (! constrain_operands (1))
1598 insn2 = emit (set2);
1599 if (GET_CODE (insn2) == BARRIER)
1601 extract_insn (insn2);
1602 if (! constrain_operands (1))
1606 tmp = replacements[0];
1607 replacements[0] = replacements[1];
1608 replacements[1] = tmp;
1609 tmp = replacements[2];
1610 replacements[2] = replacements[3];
1611 replacements[3] = tmp;
1612 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1613 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1614 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1620 ;; The register allocator is rather clumsy in handling multi-way conditional
1621 ;; moves, so allow the combiner to make them, and we split them up after
1623 (define_insn_and_split "*movsicc_umin"
1624 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1625 (umin:SI (if_then_else:SI
1626 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1628 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1629 (match_operand:SI 3 "register_operand" "0"))
1630 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1631 (clobber (match_scratch:SI 5 "=&r"))]
1632 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1634 "TARGET_SHMEDIA && reload_completed"
1637 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1639 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1640 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1645 (define_insn "*movsicc_t_false"
1646 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1647 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1648 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1649 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1650 "TARGET_PRETEND_CMOVE
1651 && (arith_reg_operand (operands[1], SImode)
1652 || (immediate_operand (operands[1], SImode)
1653 && satisfies_constraint_I08 (operands[1])))"
1659 [(set_attr "type" "mt_group,arith") ;; poor approximation
1660 (set_attr "length" "4")])
1662 (define_insn "*movsicc_t_true"
1663 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1664 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1665 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1666 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1667 "TARGET_PRETEND_CMOVE
1668 && (arith_reg_operand (operands[1], SImode)
1669 || (immediate_operand (operands[1], SImode)
1670 && satisfies_constraint_I08 (operands[1])))"
1676 [(set_attr "type" "mt_group,arith") ;; poor approximation
1677 (set_attr "length" "4")])
1679 (define_expand "movsicc"
1680 [(set (match_operand:SI 0 "arith_reg_dest" "")
1681 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1682 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1683 (match_operand:SI 3 "arith_reg_operand" "")))]
1684 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1686 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1687 && GET_MODE (XEXP (operands[1], 0)) == SImode
1689 || (REG_P (XEXP (operands[1], 0))
1690 && REGNO (XEXP (operands[1], 0)) == T_REG))
1691 && XEXP (operands[1], 1) == const0_rtx)
1694 else if (TARGET_PRETEND_CMOVE)
1696 enum rtx_code code = GET_CODE (operands[1]);
1697 enum rtx_code new_code = code;
1698 rtx op0 = XEXP (operands[1], 0);
1699 rtx op1 = XEXP (operands[1], 1);
1701 if (! currently_expanding_to_rtl)
1705 case LT: case LE: case LEU: case LTU:
1706 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1709 new_code = reverse_condition (code);
1711 case EQ: case GT: case GE: case GEU: case GTU:
1716 sh_emit_scc_to_t (new_code, op0, op1);
1717 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1718 gen_rtx_REG (SImode, T_REG), const0_rtx);
1722 if (!can_create_pseudo_p ())
1725 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1726 GET_CODE (operands[1]),
1727 XEXP (operands[1], 0),
1728 XEXP (operands[1], 1));
1734 (define_expand "movqicc"
1735 [(set (match_operand:QI 0 "register_operand" "")
1736 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1737 (match_operand:QI 2 "register_operand" "")
1738 (match_operand:QI 3 "register_operand" "")))]
1741 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1742 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1743 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1744 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1748 ;; -------------------------------------------------------------------------
1749 ;; Addition instructions
1750 ;; -------------------------------------------------------------------------
1752 (define_expand "adddi3"
1753 [(set (match_operand:DI 0 "arith_reg_operand")
1754 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1755 (match_operand:DI 2 "arith_operand")))]
1760 operands[2] = force_reg (DImode, operands[2]);
1761 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1766 (define_insn "*adddi3_media"
1767 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1768 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1769 (match_operand:DI 2 "arith_operand" "r,I10")))]
1774 [(set_attr "type" "arith_media")])
1776 (define_insn "*adddisi3_media"
1777 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1778 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1779 (match_operand:DI 2 "arith_operand" "r,I10")))]
1784 [(set_attr "type" "arith_media")
1785 (set_attr "highpart" "ignore")])
1787 (define_insn "adddi3z_media"
1788 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1790 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1791 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1793 "addz.l %1, %N2, %0"
1794 [(set_attr "type" "arith_media")
1795 (set_attr "highpart" "ignore")])
1797 (define_insn_and_split "adddi3_compact"
1798 [(set (match_operand:DI 0 "arith_reg_dest")
1799 (plus:DI (match_operand:DI 1 "arith_reg_operand")
1800 (match_operand:DI 2 "arith_reg_operand")))
1801 (clobber (reg:SI T_REG))]
1804 "&& can_create_pseudo_p ()"
1807 emit_insn (gen_clrt ());
1808 emit_insn (gen_addc (gen_lowpart (SImode, operands[0]),
1809 gen_lowpart (SImode, operands[1]),
1810 gen_lowpart (SImode, operands[2])));
1811 emit_insn (gen_addc (gen_highpart (SImode, operands[0]),
1812 gen_highpart (SImode, operands[1]),
1813 gen_highpart (SImode, operands[2])));
1818 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1819 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1820 (match_operand:SI 2 "arith_reg_operand" "r"))
1823 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1826 [(set_attr "type" "arith")])
1828 ;; A simplified version of the addc insn, where the exact value of the
1829 ;; T bit doesn't matter. This is easier for combine to pick up.
1830 ;; We allow a reg or 0 for one of the operands in order to be able to
1831 ;; do 'reg + T' sequences. Reload will load the constant 0 into the reg
1833 (define_insn "*addc"
1834 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1835 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1836 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1837 (match_operand:SI 3 "t_reg_operand" "")))
1838 (clobber (reg:SI T_REG))]
1841 [(set_attr "type" "arith")])
1843 ;; Split 'reg + reg + 1' into a sett addc sequence, as it can be scheduled
1844 ;; better, if the sett insn can be done early.
1845 (define_insn_and_split "*addc_r_r_1"
1846 [(set (match_operand:SI 0 "arith_reg_dest" "")
1847 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
1848 (match_operand:SI 2 "arith_reg_operand" ""))
1850 (clobber (reg:SI T_REG))]
1854 [(set (reg:SI T_REG) (const_int 1))
1855 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
1857 (clobber (reg:SI T_REG))])])
1859 ;; Left shifts by one are usually done with an add insn to avoid T_REG
1860 ;; clobbers. Thus addc can also be used to do something like '(x << 1) + 1'.
1861 (define_insn_and_split "*addc_2r_1"
1862 [(set (match_operand:SI 0 "arith_reg_dest")
1863 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
1866 (clobber (reg:SI T_REG))]
1870 [(set (reg:SI T_REG) (const_int 1))
1871 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
1873 (clobber (reg:SI T_REG))])])
1875 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1876 ;; matched. Split this up into a simple sub add sequence, as this will save
1877 ;; us one sett insn.
1878 (define_insn_and_split "*minus_plus_one"
1879 [(set (match_operand:SI 0 "arith_reg_dest" "")
1880 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1881 (match_operand:SI 2 "arith_reg_operand" ""))
1886 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1887 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
1889 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
1890 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1891 ;; operation, as opposed to sequences such as
1895 ;; Even if the constant is not CSE-ed, a sequence such as
1898 ;; can be scheduled much better since the load of the constant can be
1899 ;; done earlier, before any comparison insns that store the result in
1901 (define_insn_and_split "*addc_r_1"
1902 [(set (match_operand:SI 0 "arith_reg_dest" "")
1903 (plus:SI (match_operand:SI 1 "t_reg_operand" "")
1904 (match_operand:SI 2 "arith_reg_operand" "")))
1905 (clobber (reg:SI T_REG))]
1909 [(parallel [(set (match_dup 0)
1910 (plus:SI (plus:SI (match_dup 2) (const_int 0))
1912 (clobber (reg:SI T_REG))])])
1914 ;; Use shlr-addc to do 'reg + (reg & 1)'.
1915 (define_insn_and_split "*addc_r_lsb"
1916 [(set (match_operand:SI 0 "arith_reg_dest")
1917 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1919 (match_operand:SI 2 "arith_reg_operand")))
1920 (clobber (reg:SI T_REG))]
1923 "&& can_create_pseudo_p ()"
1924 [(parallel [(set (match_dup 0) (plus:SI (reg:SI T_REG) (match_dup 2)))
1925 (clobber (reg:SI T_REG))])]
1927 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[1]));
1930 ;; Use shlr-addc to do 'reg + reg + (reg & 1)'.
1931 (define_insn_and_split "*addc_r_r_lsb"
1932 [(set (match_operand:SI 0 "arith_reg_dest")
1933 (plus:SI (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1935 (match_operand:SI 2 "arith_reg_operand"))
1936 (match_operand:SI 3 "arith_reg_operand")))
1937 (clobber (reg:SI T_REG))]
1940 "&& can_create_pseudo_p ()"
1941 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
1943 (clobber (reg:SI T_REG))])]
1945 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[1]));
1948 ;; Canonicalize 'reg + (reg & 1) + reg' into 'reg + reg + (reg & 1)'.
1949 (define_insn_and_split "*addc_r_lsb_r"
1950 [(set (match_operand:SI 0 "arith_reg_dest")
1951 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1953 (plus:SI (match_operand:SI 2 "arith_reg_operand")
1954 (match_operand:SI 3 "arith_reg_operand"))))
1955 (clobber (reg:SI T_REG))]
1958 "&& can_create_pseudo_p ()"
1959 [(parallel [(set (match_dup 0)
1960 (plus:SI (plus:SI (and:SI (match_dup 1) (const_int 1))
1963 (clobber (reg:SI T_REG))])])
1965 ;; Canonicalize '2 * reg + (reg & 1)' into 'reg + reg + (reg & 1)'.
1966 (define_insn_and_split "*addc_2r_lsb"
1967 [(set (match_operand:SI 0 "arith_reg_dest")
1968 (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
1970 (mult:SI (match_operand:SI 2 "arith_reg_operand")
1972 (clobber (reg:SI T_REG))]
1975 "&& can_create_pseudo_p ()"
1976 [(parallel [(set (match_dup 0)
1977 (plus:SI (plus:SI (and:SI (match_dup 1) (const_int 1))
1980 (clobber (reg:SI T_REG))])])
1982 ;; Use shll-addc to do 'reg + ((unsigned int)reg >> 31)'.
1983 (define_insn_and_split "*addc_r_msb"
1984 [(set (match_operand:SI 0 "arith_reg_dest")
1985 (plus:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
1987 (match_operand:SI 2 "arith_reg_operand")))
1988 (clobber (reg:SI T_REG))]
1991 "&& can_create_pseudo_p ()"
1992 [(parallel [(set (match_dup 0) (plus:SI (reg:SI T_REG) (match_dup 2)))
1993 (clobber (reg:SI T_REG))])]
1995 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[1]));
1998 ;; Use shll-addc to do 'reg + reg + ((unsigned int)reg >> 31)'.
1999 (define_insn_and_split "*addc_r_r_msb"
2000 [(set (match_operand:SI 0 "arith_reg_dest")
2001 (plus:SI (plus:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
2003 (match_operand:SI 2 "arith_reg_operand"))
2004 (match_operand:SI 3 "arith_reg_operand")))
2005 (clobber (reg:SI T_REG))]
2008 "&& can_create_pseudo_p ()"
2009 [(parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 2) (match_dup 3))
2011 (clobber (reg:SI T_REG))])]
2013 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[1]));
2016 ;; Canonicalize '2 * reg + ((unsigned int)reg >> 31)'
2017 ;; into 'reg + reg + (reg & 1)'.
2018 (define_insn_and_split "*addc_2r_msb"
2019 [(set (match_operand:SI 0 "arith_reg_dest")
2020 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
2022 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
2024 (clobber (reg:SI T_REG))]
2027 "&& can_create_pseudo_p ()"
2028 [(parallel [(set (match_dup 0)
2029 (plus:SI (plus:SI (lshiftrt:SI (match_dup 2) (const_int 31))
2032 (clobber (reg:SI T_REG))])])
2034 (define_expand "addsi3"
2035 [(set (match_operand:SI 0 "arith_reg_operand" "")
2036 (plus:SI (match_operand:SI 1 "arith_operand" "")
2037 (match_operand:SI 2 "arith_operand" "")))]
2041 operands[1] = force_reg (SImode, operands[1]);
2044 (define_insn "addsi3_media"
2045 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2046 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
2047 (match_operand:SI 2 "arith_operand" "r,I10")))]
2052 [(set_attr "type" "arith_media")
2053 (set_attr "highpart" "ignore")])
2055 (define_insn "addsidi3_media"
2056 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
2057 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
2059 (match_operand:SI 2 "arith_operand"
2065 [(set_attr "type" "arith_media")
2066 (set_attr "highpart" "ignore")])
2068 (define_insn "*addsi3_compact"
2069 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2070 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
2071 (match_operand:SI 2 "arith_operand" "rI08")))]
2074 [(set_attr "type" "arith")])
2076 ;; -------------------------------------------------------------------------
2077 ;; Subtraction instructions
2078 ;; -------------------------------------------------------------------------
2080 (define_expand "subdi3"
2081 [(set (match_operand:DI 0 "arith_reg_operand" "")
2082 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
2083 (match_operand:DI 2 "arith_reg_operand" "")))]
2088 operands[1] = force_reg (DImode, operands[1]);
2089 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
2094 (define_insn "*subdi3_media"
2095 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2096 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2097 (match_operand:DI 2 "arith_reg_operand" "r")))]
2100 [(set_attr "type" "arith_media")])
2102 (define_insn "subdisi3_media"
2103 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
2104 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
2105 (match_operand:DI 2 "arith_reg_operand" "r")))]
2108 [(set_attr "type" "arith_media")
2109 (set_attr "highpart" "ignore")])
2111 (define_insn_and_split "subdi3_compact"
2112 [(set (match_operand:DI 0 "arith_reg_dest")
2113 (minus:DI (match_operand:DI 1 "arith_reg_operand")
2114 (match_operand:DI 2 "arith_reg_operand")))
2115 (clobber (reg:SI T_REG))]
2118 "&& can_create_pseudo_p ()"
2121 emit_insn (gen_clrt ());
2122 emit_insn (gen_subc (gen_lowpart (SImode, operands[0]),
2123 gen_lowpart (SImode, operands[1]),
2124 gen_lowpart (SImode, operands[2])));
2125 emit_insn (gen_subc (gen_highpart (SImode, operands[0]),
2126 gen_highpart (SImode, operands[1]),
2127 gen_highpart (SImode, operands[2])));
2132 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2133 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2134 (match_operand:SI 2 "arith_reg_operand" "r"))
2137 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
2142 [(set_attr "type" "arith")])
2144 ;; A simplified version of the subc insn, where the exact value of the
2145 ;; T bit doesn't matter. This is easier for combine to pick up.
2146 ;; We allow a reg or 0 for one of the operands in order to be able to
2147 ;; do 'reg - T' sequences. Reload will load the constant 0 into the reg
2149 (define_insn "*subc"
2150 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2151 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2152 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
2153 (match_operand:SI 3 "t_reg_operand" "")))
2154 (clobber (reg:SI T_REG))]
2157 [(set_attr "type" "arith")])
2159 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
2160 ;; better, if the sett insn can be done early.
2161 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
2162 (define_insn_and_split "*subc"
2163 [(set (match_operand:SI 0 "arith_reg_dest" "")
2164 (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
2165 (match_operand:SI 2 "arith_reg_operand" "")))
2166 (clobber (reg:SI T_REG))]
2170 [(set (reg:SI T_REG) (const_int 1))
2171 (parallel [(set (match_dup 0)
2172 (minus:SI (minus:SI (match_dup 2) (match_dup 1))
2174 (clobber (reg:SI T_REG))])])
2176 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
2177 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
2178 ;; operation, as opposed to sequences such as
2182 ;; Even if the constant is not CSE-ed, a sequence such as
2185 ;; can be scheduled much better since the load of the constant can be
2186 ;; done earlier, before any comparison insns that store the result in
2188 (define_insn_and_split "*subc"
2189 [(set (match_operand:SI 0 "arith_reg_dest" "")
2190 (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2191 (match_operand:SI 2 "t_reg_operand" "")))
2192 (clobber (reg:SI T_REG))]
2196 [(parallel [(set (match_dup 0)
2197 (minus:SI (minus:SI (match_dup 1) (const_int 0))
2199 (clobber (reg:SI T_REG))])])
2201 (define_insn "*subsi3_internal"
2202 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2203 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2204 (match_operand:SI 2 "arith_reg_operand" "r")))]
2207 [(set_attr "type" "arith")])
2209 (define_insn_and_split "*subsi3_media"
2210 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2211 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2212 (match_operand:SI 2 "extend_reg_operand" "r")))]
2214 && (operands[1] != constm1_rtx
2215 || (GET_CODE (operands[2]) != TRUNCATE
2216 && GET_CODE (operands[2]) != SUBREG))"
2218 "operands[1] == constm1_rtx"
2219 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2221 [(set_attr "type" "arith_media")
2222 (set_attr "highpart" "ignore")])
2225 [(set (match_operand:SI 0 "arith_reg_dest" "")
2226 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2227 "general_extend_operand"
2229 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2230 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2231 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2235 [(set (match_operand:SI 0 "arith_reg_dest" "")
2236 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2237 "general_extend_operand"
2239 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
2240 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2241 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2249 ;; since this will sometimes save one instruction.
2250 ;; Otherwise we might get a sequence like
2254 ;; if the source and dest regs are the same.
2255 (define_expand "subsi3"
2256 [(set (match_operand:SI 0 "arith_reg_operand" "")
2257 (minus:SI (match_operand:SI 1 "arith_operand" "")
2258 (match_operand:SI 2 "arith_reg_operand" "")))]
2261 if (TARGET_SH1 && CONST_INT_P (operands[1]))
2263 emit_insn (gen_negsi2 (operands[0], operands[2]));
2264 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2269 if (!can_create_pseudo_p ()
2270 && ! arith_reg_or_0_operand (operands[1], SImode))
2272 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2273 operands[1] = force_reg (SImode, operands[1]);
2277 ;; -------------------------------------------------------------------------
2278 ;; Division instructions
2279 ;; -------------------------------------------------------------------------
2281 ;; We take advantage of the library routines which don't clobber as many
2282 ;; registers as a normal function call would.
2284 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2285 ;; also has an effect on the register that holds the address of the sfunc.
2286 ;; To make this work, we have an extra dummy insn that shows the use
2287 ;; of this register for reorg.
2289 (define_insn "use_sfunc_addr"
2290 [(set (reg:SI PR_REG)
2291 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2292 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2294 [(set_attr "length" "0")])
2296 (define_insn "udivsi3_sh2a"
2297 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2298 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2299 (match_operand:SI 2 "arith_reg_operand" "z")))]
2302 [(set_attr "type" "arith")
2303 (set_attr "in_delay_slot" "no")])
2305 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2306 ;; hard register 0. If we used hard register 0, then the next instruction
2307 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
2308 ;; gets allocated to a stack slot that needs its address reloaded, then
2309 ;; there is nothing to prevent reload from using r0 to reload the address.
2310 ;; This reload would clobber the value in r0 we are trying to store.
2311 ;; If we let reload allocate r0, then this problem can never happen.
2312 (define_insn "udivsi3_i1"
2313 [(set (match_operand:SI 0 "register_operand" "=z")
2314 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2315 (clobber (reg:SI T_REG))
2316 (clobber (reg:SI PR_REG))
2317 (clobber (reg:SI R1_REG))
2318 (clobber (reg:SI R4_REG))
2319 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2320 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2322 [(set_attr "type" "sfunc")
2323 (set_attr "needs_delay_slot" "yes")])
2325 ; Since shmedia-nofpu code could be linked against shcompact code, and
2326 ; the udivsi3 libcall has the same name, we must consider all registers
2327 ; clobbered that are in the union of the registers clobbered by the
2328 ; shmedia and the shcompact implementation. Note, if the shcompact
2329 ; implementation actually used shcompact code, we'd need to clobber
2330 ; also r23 and fr23.
2331 (define_insn "udivsi3_i1_media"
2332 [(set (match_operand:SI 0 "register_operand" "=z")
2333 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2334 (clobber (reg:SI T_MEDIA_REG))
2335 (clobber (reg:SI PR_MEDIA_REG))
2336 (clobber (reg:SI R20_REG))
2337 (clobber (reg:SI R21_REG))
2338 (clobber (reg:SI R22_REG))
2339 (clobber (reg:DI TR0_REG))
2340 (clobber (reg:DI TR1_REG))
2341 (clobber (reg:DI TR2_REG))
2342 (use (match_operand 1 "target_reg_operand" "b"))]
2343 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2345 [(set_attr "type" "sfunc")
2346 (set_attr "needs_delay_slot" "yes")])
2348 (define_expand "udivsi3_i4_media"
2350 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2352 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2353 (set (match_dup 5) (float:DF (match_dup 3)))
2354 (set (match_dup 6) (float:DF (match_dup 4)))
2355 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2356 (set (match_dup 8) (fix:DI (match_dup 7)))
2357 (set (match_operand:SI 0 "register_operand" "")
2358 (truncate:SI (match_dup 8)))]
2359 "TARGET_SHMEDIA_FPU"
2361 operands[3] = gen_reg_rtx (DImode);
2362 operands[4] = gen_reg_rtx (DImode);
2363 operands[5] = gen_reg_rtx (DFmode);
2364 operands[6] = gen_reg_rtx (DFmode);
2365 operands[7] = gen_reg_rtx (DFmode);
2366 operands[8] = gen_reg_rtx (DImode);
2369 (define_insn "udivsi3_i4"
2370 [(set (match_operand:SI 0 "register_operand" "=y")
2371 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2372 (clobber (reg:SI T_REG))
2373 (clobber (reg:SI PR_REG))
2374 (clobber (reg:DF DR0_REG))
2375 (clobber (reg:DF DR2_REG))
2376 (clobber (reg:DF DR4_REG))
2377 (clobber (reg:SI R0_REG))
2378 (clobber (reg:SI R1_REG))
2379 (clobber (reg:SI R4_REG))
2380 (clobber (reg:SI R5_REG))
2381 (use (reg:PSI FPSCR_REG))
2382 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2383 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2385 [(set_attr "type" "sfunc")
2386 (set_attr "fp_mode" "double")
2387 (set_attr "needs_delay_slot" "yes")])
2389 (define_insn "udivsi3_i4_single"
2390 [(set (match_operand:SI 0 "register_operand" "=y")
2391 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2392 (clobber (reg:SI T_REG))
2393 (clobber (reg:SI PR_REG))
2394 (clobber (reg:DF DR0_REG))
2395 (clobber (reg:DF DR2_REG))
2396 (clobber (reg:DF DR4_REG))
2397 (clobber (reg:SI R0_REG))
2398 (clobber (reg:SI R1_REG))
2399 (clobber (reg:SI R4_REG))
2400 (clobber (reg:SI R5_REG))
2401 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2402 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2403 && TARGET_FPU_SINGLE"
2405 [(set_attr "type" "sfunc")
2406 (set_attr "needs_delay_slot" "yes")])
2408 (define_insn "udivsi3_i4_int"
2409 [(set (match_operand:SI 0 "register_operand" "=z")
2410 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2411 (clobber (reg:SI T_REG))
2412 (clobber (reg:SI R1_REG))
2413 (clobber (reg:SI PR_REG))
2414 (clobber (reg:SI MACH_REG))
2415 (clobber (reg:SI MACL_REG))
2416 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2419 [(set_attr "type" "sfunc")
2420 (set_attr "needs_delay_slot" "yes")])
2423 (define_expand "udivsi3"
2424 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2425 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2426 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2427 (parallel [(set (match_operand:SI 0 "register_operand" "")
2428 (udiv:SI (reg:SI R4_REG)
2430 (clobber (reg:SI T_REG))
2431 (clobber (reg:SI PR_REG))
2432 (clobber (reg:SI R4_REG))
2433 (use (match_dup 3))])]
2438 operands[3] = gen_reg_rtx (Pmode);
2439 /* Emit the move of the address to a pseudo outside of the libcall. */
2440 if (TARGET_DIVIDE_CALL_TABLE)
2442 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2443 that causes problems when the divide code is supposed to come from a
2444 separate library. Division by zero is undefined, so dividing 1 can be
2445 implemented by comparing with the divisor. */
2446 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2448 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2449 emit_insn (gen_cstoresi4 (operands[0], test,
2450 operands[1], operands[2]));
2453 else if (operands[2] == const0_rtx)
2455 emit_move_insn (operands[0], operands[2]);
2458 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2459 last = gen_udivsi3_i4_int (operands[0], operands[3]);
2461 else if (TARGET_DIVIDE_CALL_FP)
2463 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2464 if (TARGET_FPU_SINGLE)
2465 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2467 last = gen_udivsi3_i4 (operands[0], operands[3]);
2469 else if (TARGET_SHMEDIA_FPU)
2471 operands[1] = force_reg (SImode, operands[1]);
2472 operands[2] = force_reg (SImode, operands[2]);
2473 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2476 else if (TARGET_SH2A)
2478 operands[1] = force_reg (SImode, operands[1]);
2479 operands[2] = force_reg (SImode, operands[2]);
2480 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2483 else if (TARGET_SH5)
2485 function_symbol (operands[3],
2486 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2490 last = gen_udivsi3_i1_media (operands[0], operands[3]);
2491 else if (TARGET_FPU_ANY)
2492 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2494 last = gen_udivsi3_i1 (operands[0], operands[3]);
2498 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2499 last = gen_udivsi3_i1 (operands[0], operands[3]);
2501 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2502 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2507 (define_insn "divsi3_sh2a"
2508 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2509 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2510 (match_operand:SI 2 "arith_reg_operand" "z")))]
2513 [(set_attr "type" "arith")
2514 (set_attr "in_delay_slot" "no")])
2516 (define_insn "divsi3_i1"
2517 [(set (match_operand:SI 0 "register_operand" "=z")
2518 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2519 (clobber (reg:SI T_REG))
2520 (clobber (reg:SI PR_REG))
2521 (clobber (reg:SI R1_REG))
2522 (clobber (reg:SI R2_REG))
2523 (clobber (reg:SI R3_REG))
2524 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2525 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
2527 [(set_attr "type" "sfunc")
2528 (set_attr "needs_delay_slot" "yes")])
2530 (define_insn "divsi3_i1_media"
2531 [(set (match_operand:SI 0 "register_operand" "=z")
2532 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2533 (clobber (reg:SI T_MEDIA_REG))
2534 (clobber (reg:SI PR_MEDIA_REG))
2535 (clobber (reg:SI R1_REG))
2536 (clobber (reg:SI R20_REG))
2537 (clobber (reg:SI R21_REG))
2538 (clobber (reg:SI TR0_REG))
2539 (use (match_operand 1 "target_reg_operand" "b"))]
2540 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2542 [(set_attr "type" "sfunc")])
2544 (define_insn "divsi3_media_2"
2545 [(set (match_operand:SI 0 "register_operand" "=z")
2546 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2547 (clobber (reg:SI T_MEDIA_REG))
2548 (clobber (reg:SI PR_MEDIA_REG))
2549 (clobber (reg:SI R1_REG))
2550 (clobber (reg:SI R21_REG))
2551 (clobber (reg:SI TR0_REG))
2552 (use (reg:SI R20_REG))
2553 (use (match_operand 1 "target_reg_operand" "b"))]
2554 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2556 [(set_attr "type" "sfunc")])
2558 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2559 ;; hard reg clobbers and data dependencies that we need when we want
2560 ;; to rematerialize the division into a call.
2561 (define_insn_and_split "divsi_inv_call"
2562 [(set (match_operand:SI 0 "register_operand" "=r")
2563 (div:SI (match_operand:SI 1 "register_operand" "r")
2564 (match_operand:SI 2 "register_operand" "r")))
2565 (clobber (reg:SI R4_REG))
2566 (clobber (reg:SI R5_REG))
2567 (clobber (reg:SI T_MEDIA_REG))
2568 (clobber (reg:SI PR_MEDIA_REG))
2569 (clobber (reg:SI R1_REG))
2570 (clobber (reg:SI R21_REG))
2571 (clobber (reg:SI TR0_REG))
2572 (clobber (reg:SI R20_REG))
2573 (use (match_operand:SI 3 "register_operand" "r"))]
2576 "&& (reload_in_progress || reload_completed)"
2577 [(set (match_dup 0) (match_dup 3))]
2579 [(set_attr "highpart" "must_split")])
2581 ;; This is the combiner pattern for -mdiv=inv:call .
2582 (define_insn_and_split "*divsi_inv_call_combine"
2583 [(set (match_operand:SI 0 "register_operand" "=z")
2584 (div:SI (match_operand:SI 1 "register_operand" "r")
2585 (match_operand:SI 2 "register_operand" "r")))
2586 (clobber (reg:SI R4_REG))
2587 (clobber (reg:SI R5_REG))
2588 (clobber (reg:SI T_MEDIA_REG))
2589 (clobber (reg:SI PR_MEDIA_REG))
2590 (clobber (reg:SI R1_REG))
2591 (clobber (reg:SI R21_REG))
2592 (clobber (reg:SI TR0_REG))
2593 (clobber (reg:SI R20_REG))
2594 (use (unspec:SI [(match_dup 1)
2595 (match_operand:SI 3 "" "")
2596 (unspec:SI [(match_operand:SI 4 "" "")
2598 (match_operand:DI 5 "" "")]
2600 (match_operand:DI 6 "" "")
2603 UNSPEC_DIV_INV_M3))]
2606 "&& (reload_in_progress || reload_completed)"
2609 const char *name = sh_divsi3_libfunc;
2610 enum sh_function_kind kind = SFUNC_GOT;
2613 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2614 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2615 while (TARGET_DIVIDE_INV_CALL2)
2617 rtx x = operands[3];
2619 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2621 x = XVECEXP (x, 0, 0);
2622 name = "__sdivsi3_2";
2623 kind = SFUNC_STATIC;
2624 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2627 sym = function_symbol (NULL, name, kind);
2628 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2631 [(set_attr "highpart" "must_split")])
2633 (define_expand "divsi3_i4_media"
2634 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2635 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2636 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2637 (set (match_operand:SI 0 "register_operand" "=r")
2638 (fix:SI (match_dup 5)))]
2639 "TARGET_SHMEDIA_FPU"
2641 operands[3] = gen_reg_rtx (DFmode);
2642 operands[4] = gen_reg_rtx (DFmode);
2643 operands[5] = gen_reg_rtx (DFmode);
2646 (define_insn "divsi3_i4"
2647 [(set (match_operand:SI 0 "register_operand" "=y")
2648 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2649 (clobber (reg:SI PR_REG))
2650 (clobber (reg:DF DR0_REG))
2651 (clobber (reg:DF DR2_REG))
2652 (use (reg:PSI FPSCR_REG))
2653 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2654 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2656 [(set_attr "type" "sfunc")
2657 (set_attr "fp_mode" "double")
2658 (set_attr "needs_delay_slot" "yes")])
2660 (define_insn "divsi3_i4_single"
2661 [(set (match_operand:SI 0 "register_operand" "=y")
2662 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2663 (clobber (reg:SI PR_REG))
2664 (clobber (reg:DF DR0_REG))
2665 (clobber (reg:DF DR2_REG))
2666 (clobber (reg:SI R2_REG))
2667 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2668 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2669 && TARGET_FPU_SINGLE"
2671 [(set_attr "type" "sfunc")
2672 (set_attr "needs_delay_slot" "yes")])
2674 (define_insn "divsi3_i4_int"
2675 [(set (match_operand:SI 0 "register_operand" "=z")
2676 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2677 (clobber (reg:SI T_REG))
2678 (clobber (reg:SI PR_REG))
2679 (clobber (reg:SI R1_REG))
2680 (clobber (reg:SI MACH_REG))
2681 (clobber (reg:SI MACL_REG))
2682 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2685 [(set_attr "type" "sfunc")
2686 (set_attr "needs_delay_slot" "yes")])
2688 (define_expand "divsi3"
2689 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2690 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2691 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2692 (parallel [(set (match_operand:SI 0 "register_operand" "")
2693 (div:SI (reg:SI R4_REG)
2695 (clobber (reg:SI T_REG))
2696 (clobber (reg:SI PR_REG))
2697 (clobber (reg:SI R1_REG))
2698 (clobber (reg:SI R2_REG))
2699 (clobber (reg:SI R3_REG))
2700 (use (match_dup 3))])]
2705 operands[3] = gen_reg_rtx (Pmode);
2706 /* Emit the move of the address to a pseudo outside of the libcall. */
2707 if (TARGET_DIVIDE_CALL_TABLE)
2709 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2710 last = gen_divsi3_i4_int (operands[0], operands[3]);
2712 else if (TARGET_DIVIDE_CALL_FP)
2714 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2715 if (TARGET_FPU_SINGLE)
2716 last = gen_divsi3_i4_single (operands[0], operands[3]);
2718 last = gen_divsi3_i4 (operands[0], operands[3]);
2720 else if (TARGET_SH2A)
2722 operands[1] = force_reg (SImode, operands[1]);
2723 operands[2] = force_reg (SImode, operands[2]);
2724 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2727 else if (TARGET_DIVIDE_INV)
2729 rtx dividend = operands[1];
2730 rtx divisor = operands[2];
2732 rtx nsb_res = gen_reg_rtx (DImode);
2733 rtx norm64 = gen_reg_rtx (DImode);
2734 rtx tab_ix = gen_reg_rtx (DImode);
2735 rtx norm32 = gen_reg_rtx (SImode);
2736 rtx i92 = force_reg (DImode, GEN_INT (92));
2737 rtx scratch0a = gen_reg_rtx (DImode);
2738 rtx scratch0b = gen_reg_rtx (DImode);
2739 rtx inv0 = gen_reg_rtx (SImode);
2740 rtx scratch1a = gen_reg_rtx (DImode);
2741 rtx scratch1b = gen_reg_rtx (DImode);
2742 rtx shift = gen_reg_rtx (DImode);
2744 rtx inv1 = gen_reg_rtx (SImode);
2745 rtx scratch2a = gen_reg_rtx (DImode);
2746 rtx scratch2b = gen_reg_rtx (SImode);
2747 rtx inv2 = gen_reg_rtx (SImode);
2748 rtx scratch3a = gen_reg_rtx (DImode);
2749 rtx scratch3b = gen_reg_rtx (DImode);
2750 rtx scratch3c = gen_reg_rtx (DImode);
2751 rtx scratch3d = gen_reg_rtx (SImode);
2752 rtx scratch3e = gen_reg_rtx (DImode);
2753 rtx result = gen_reg_rtx (SImode);
2755 if (! arith_reg_or_0_operand (dividend, SImode))
2756 dividend = force_reg (SImode, dividend);
2757 if (! arith_reg_operand (divisor, SImode))
2758 divisor = force_reg (SImode, divisor);
2759 if (flag_pic && Pmode != DImode)
2761 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2762 tab_base = gen_datalabel_ref (tab_base);
2763 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2767 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2768 tab_base = gen_datalabel_ref (tab_base);
2769 tab_base = force_reg (DImode, tab_base);
2771 if (TARGET_DIVIDE_INV20U)
2772 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2774 i2p27 = GEN_INT (0);
2775 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2776 i43 = force_reg (DImode, GEN_INT (43));
2779 emit_insn (gen_nsbdi (nsb_res,
2780 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2781 emit_insn (gen_ashldi3_media (norm64,
2782 gen_rtx_SUBREG (DImode, divisor, 0),
2784 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2785 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2786 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2787 inv0, scratch0a, scratch0b,
2788 scratch1a, scratch1b));
2789 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2790 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2792 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2794 scratch3a, scratch3b, scratch3c,
2795 scratch2a, scratch2b, scratch3d, scratch3e));
2796 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2797 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2798 else if (TARGET_DIVIDE_INV_FP)
2799 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2800 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2801 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2802 gen_reg_rtx (DFmode)));
2804 emit_move_insn (operands[0], result);
2807 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2809 operands[1] = force_reg (SImode, operands[1]);
2810 operands[2] = force_reg (SImode, operands[2]);
2811 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2814 else if (TARGET_SH5)
2816 if (TARGET_DIVIDE_CALL2)
2818 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2819 tab_base = gen_datalabel_ref (tab_base);
2820 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2822 if (TARGET_FPU_ANY && TARGET_SH1)
2823 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2824 else if (TARGET_DIVIDE_CALL2)
2825 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2827 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2830 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2831 (operands[0], operands[3]));
2832 else if (TARGET_FPU_ANY)
2833 last = gen_divsi3_i4_single (operands[0], operands[3]);
2835 last = gen_divsi3_i1 (operands[0], operands[3]);
2839 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2840 last = gen_divsi3_i1 (operands[0], operands[3]);
2842 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2843 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2848 ;; operands: scratch, tab_base, tab_ix
2849 ;; These are unspecs because we could generate an indexed addressing mode
2850 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2851 ;; confuse reload. See PR27117.
2852 (define_insn "divsi_inv_qitable"
2853 [(set (match_operand:DI 0 "register_operand" "=r")
2854 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2855 (match_operand:DI 2 "register_operand" "r")]
2856 UNSPEC_DIV_INV_TABLE)))]
2859 [(set_attr "type" "load_media")
2860 (set_attr "highpart" "user")])
2862 ;; operands: scratch, tab_base, tab_ix
2863 (define_insn "divsi_inv_hitable"
2864 [(set (match_operand:DI 0 "register_operand" "=r")
2865 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2866 (match_operand:DI 2 "register_operand" "r")]
2867 UNSPEC_DIV_INV_TABLE)))]
2870 [(set_attr "type" "load_media")
2871 (set_attr "highpart" "user")])
2873 ;; operands: inv0, tab_base, tab_ix, norm32
2874 ;; scratch equiv in sdivsi3_2: r19, r21
2875 (define_expand "divsi_inv_m0"
2876 [(set (match_operand:SI 0 "register_operand" "=r")
2877 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2878 (match_operand:DI 2 "register_operand" "r")
2879 (match_operand:SI 3 "register_operand" "r")]
2881 (clobber (match_operand:DI 4 "register_operand" "=r"))
2882 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2889 ldx.ub r20, r21, r19 // u0.8
2891 muls.l r25, r19, r19 // s2.38
2892 ldx.w r20, r21, r21 // s2.14
2893 shari r19, 24, r19 // truncate to s2.14
2894 sub r21, r19, r19 // some 11 bit inverse in s1.14
2897 rtx inv0 = operands[0];
2898 rtx tab_base = operands[1];
2899 rtx tab_ix = operands[2];
2900 rtx norm32 = operands[3];
2901 rtx scratch0 = operands[4];
2902 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2903 rtx scratch1 = operands[5];
2905 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2906 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2907 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2908 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2909 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2910 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2914 ;; operands: inv1, tab_base, tab_ix, norm32
2915 (define_insn_and_split "divsi_inv_m1"
2916 [(set (match_operand:SI 0 "register_operand" "=r")
2917 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2918 (match_operand:DI 2 "register_operand" "r")
2919 (match_operand:SI 3 "register_operand" "r")]
2921 (clobber (match_operand:SI 4 "register_operand" "=r"))
2922 (clobber (match_operand:DI 5 "register_operand" "=r"))
2923 (clobber (match_operand:DI 6 "register_operand" "=r"))
2924 (clobber (match_operand:DI 7 "register_operand" "=r"))
2925 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2928 "&& !can_create_pseudo_p ()"
2932 muls.l r19, r19, r18 // u0.28
2933 muls.l r25, r18, r18 // s2.58
2934 shlli r19, 45, r0 // multiply by two and convert to s2.58
2936 shari r18, 28, r18 // some 18 bit inverse in s1.30
2939 rtx inv1 = operands[0];
2940 rtx tab_base = operands[1];
2941 rtx tab_ix = operands[2];
2942 rtx norm32 = operands[3];
2943 rtx inv0 = operands[4];
2944 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2945 rtx scratch0a = operands[5];
2946 rtx scratch0b = operands[6];
2947 rtx scratch0 = operands[7];
2948 rtx scratch1 = operands[8];
2949 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2951 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2952 scratch0a, scratch0b));
2953 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2954 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2955 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2956 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2957 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2961 ;; operands: inv2, norm32, inv1, i92
2962 (define_insn_and_split "divsi_inv_m2"
2963 [(set (match_operand:SI 0 "register_operand" "=r")
2964 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2965 (match_operand:SI 2 "register_operand" "r")
2966 (match_operand:DI 3 "register_operand" "r")]
2968 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2971 "&& !can_create_pseudo_p ()"
2975 muls.l r18, r25, r0 // s2.60
2976 shari r0, 16, r0 // s-16.44
2978 muls.l r0, r18, r19 // s-16.74
2979 shari r19, 30, r19 // s-16.44
2981 rtx inv2 = operands[0];
2982 rtx norm32 = operands[1];
2983 rtx inv1 = operands[2];
2984 rtx i92 = operands[3];
2985 rtx scratch0 = operands[4];
2986 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2988 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2989 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2990 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2991 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2992 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2996 (define_insn_and_split "divsi_inv_m3"
2997 [(set (match_operand:SI 0 "register_operand" "=r")
2998 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2999 (match_operand:SI 2 "register_operand" "r")
3000 (match_operand:SI 3 "register_operand" "r")
3001 (match_operand:DI 4 "register_operand" "r")
3002 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
3003 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
3005 (clobber (match_operand:DI 7 "register_operand" "=r"))
3006 (clobber (match_operand:DI 8 "register_operand" "=r"))
3007 (clobber (match_operand:DI 9 "register_operand" "=r"))
3008 (clobber (match_operand:DI 10 "register_operand" "=r"))
3009 (clobber (match_operand:SI 11 "register_operand" "=r"))
3010 (clobber (match_operand:SI 12 "register_operand" "=r"))
3011 (clobber (match_operand:DI 13 "register_operand" "=r"))]
3014 "&& !can_create_pseudo_p ()"
3018 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
3019 r0: scratch0 r19: scratch1 r21: scratch2
3021 muls.l r18, r4, r25 // s32.30
3022 muls.l r19, r4, r19 // s15.30
3024 shari r19, 14, r19 // s18.-14
3030 rtx result = operands[0];
3031 rtx dividend = operands[1];
3032 rtx inv1 = operands[2];
3033 rtx inv2 = operands[3];
3034 rtx shift = operands[4];
3035 rtx scratch0 = operands[7];
3036 rtx scratch1 = operands[8];
3037 rtx scratch2 = operands[9];
3039 if (satisfies_constraint_N (dividend))
3041 emit_move_insn (result, dividend);
3045 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
3046 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
3047 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
3048 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
3049 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
3050 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
3051 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
3055 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
3056 ;; inv1: tab_base, tab_ix, norm32
3057 ;; inv2: norm32, inv1, i92
3058 (define_insn_and_split "divsi_inv_m1_3"
3059 [(set (match_operand:SI 0 "register_operand" "=r")
3060 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
3061 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
3062 (match_operand:DI 3 "register_operand" "r")
3063 (match_operand:SI 4 "register_operand" "r")]
3065 (unspec:SI [(match_dup 4)
3066 (unspec:SI [(match_dup 2)
3068 (match_dup 4)] UNSPEC_DIV_INV_M1)
3069 (match_operand:SI 5 "" "")]
3071 (match_operand:DI 6 "register_operand" "r")
3072 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
3073 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
3075 (clobber (match_operand:DI 9 "register_operand" "=r"))
3076 (clobber (match_operand:DI 10 "register_operand" "=r"))
3077 (clobber (match_operand:DI 11 "register_operand" "=r"))
3078 (clobber (match_operand:DI 12 "register_operand" "=r"))
3079 (clobber (match_operand:SI 13 "register_operand" "=r"))
3080 (clobber (match_operand:SI 14 "register_operand" "=r"))
3081 (clobber (match_operand:DI 15 "register_operand" "=r"))]
3083 && (TARGET_DIVIDE_INV_MINLAT
3084 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3086 "&& !can_create_pseudo_p ()"
3089 rtx result = operands[0];
3090 rtx dividend = operands[1];
3091 rtx tab_base = operands[2];
3092 rtx tab_ix = operands[3];
3093 rtx norm32 = operands[4];
3094 /* rtx i92 = operands[5]; */
3095 rtx shift = operands[6];
3096 rtx i2p27 = operands[7];
3097 rtx i43 = operands[8];
3098 rtx scratch0 = operands[9];
3099 rtx scratch0_si = gen_lowpart (SImode, scratch0);
3100 rtx scratch1 = operands[10];
3101 rtx scratch1_si = gen_lowpart (SImode, scratch1);
3102 rtx scratch2 = operands[11];
3103 rtx scratch3 = operands[12];
3104 rtx scratch4 = operands[13];
3105 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
3106 rtx scratch5 = operands[14];
3107 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
3108 rtx scratch6 = operands[15];
3110 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
3111 scratch0, scratch1));
3112 /* inv0 == scratch4 */
3113 if (! TARGET_DIVIDE_INV20U)
3115 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
3117 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
3121 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
3122 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
3124 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
3125 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
3126 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
3127 /* inv1 == scratch4 */
3129 if (TARGET_DIVIDE_INV_MINLAT)
3131 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
3132 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
3133 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
3134 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
3135 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
3136 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
3137 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
3138 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
3139 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
3140 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
3141 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
3145 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
3146 /* Use separate scratch regs for nsb and sign to allow scheduling. */
3147 emit_insn (gen_nsbdi (scratch6,
3148 simplify_gen_subreg (DImode, dividend, SImode, 0)));
3149 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
3150 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
3151 emit_insn (gen_divsi_inv20 (scratch2,
3152 norm32, scratch4, dividend,
3153 scratch6, scratch3, i43,
3154 /* scratch0 may be shared with i2p27. */
3155 scratch0, scratch1, scratch5,
3156 label, label, i2p27));
3158 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
3159 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
3163 (define_insn "divsi_inv20"
3164 [(set (match_operand:DI 0 "register_operand" "=&r")
3165 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
3166 (match_operand:SI 2 "register_operand" "r")
3167 (match_operand:SI 3 "register_operand" "r")
3168 (match_operand:DI 4 "register_operand" "r")
3169 (match_operand:DI 5 "register_operand" "r")
3170 (match_operand:DI 6 "register_operand" "r")
3171 (match_operand:DI 12 "register_operand" "r")
3172 (match_operand 10 "target_operand" "b")
3173 (match_operand 11 "immediate_operand" "i")]
3175 (clobber (match_operand:DI 7 "register_operand" "=&r"))
3176 (clobber (match_operand:DI 8 "register_operand" "=&r"))
3177 (clobber (match_operand:SI 9 "register_operand" "=r"))]
3179 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
3181 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
3182 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
3183 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
3184 %10 label (tr), %11 label (imm)
3186 muls.l inv1, norm32, scratch0 // s2.60
3187 muls.l inv1, dividend, result // s32.30
3188 xor i2p27, result_sign, round_scratch
3189 bge/u dividend_nsb, i43, tr.. (label)
3190 shari scratch0, 16, scratch0 // s-16.44
3191 muls.l sratch0_si, inv1, scratch0 // s-16.74
3192 sub result, round_scratch, result
3193 shari dividend, 14, scratch1 // s19.-14
3194 shari scratch0, 30, scratch0 // s-16.44
3195 muls.l scratch0, scratch1, round_scratch // s15.30
3197 sub result, round_scratch, result */
3199 const bool likely = TARGET_DIVIDE_INV20L;
3202 "muls.l %2, %3, %0" "\n"
3203 " xor %12, %5, %7" "\n"
3204 " bge/l %4, %6, %10" "\n"
3205 " muls.l %2, %1, %8" "\n"
3206 " shari %8, 16, %8" "\n"
3207 " muls.l %8, %2, %8" "\n"
3208 " shari %3, 14, %9" "\n"
3209 " shari %8, 30, %8" "\n"
3210 " muls.l %8, %9, %8" "\n"
3211 " sub %0, %8, %0" "\n"
3212 "%11: add %0, %7, %0";
3215 "muls.l %2, %1, %8" "\n"
3216 " muls.l %2, %3, %0" "\n"
3217 " xor %12, %5, %7" "\n"
3218 " bge/u %4, %6, %10" "\n"
3219 " shari %8, 16, %8" "\n"
3220 " muls.l %8, %2, %8" "\n"
3221 " sub %0, %7, %0" "\n"
3222 " shari %3, 14, %9" "\n"
3223 " shari %8, 30, %8" "\n"
3224 " muls.l %8, %9, %7" "\n"
3225 "%11: sub %0, %7, %0";
3228 (define_insn_and_split "divsi_inv_fp"
3229 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3230 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3231 (match_operand:SI 2 "register_operand" "rf")))
3232 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3233 (clobber (match_operand:SI 4 "register_operand" "=r"))
3234 (clobber (match_operand:SI 5 "register_operand" "=r"))
3235 (clobber (match_operand:DF 6 "register_operand" "=r"))
3236 (clobber (match_operand:DF 7 "register_operand" "=r"))
3237 (clobber (match_operand:DF 8 "register_operand" "=r"))]
3238 "TARGET_SHMEDIA_FPU"
3240 "&& (reload_in_progress || reload_completed)"
3241 [(set (match_dup 0) (match_dup 3))]
3243 [(set_attr "highpart" "must_split")])
3245 ;; If a matching group of divide-by-inverse instructions is in the same
3246 ;; basic block after gcse & loop optimizations, we want to transform them
3247 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3248 (define_insn_and_split "*divsi_inv_fp_combine"
3249 [(set (match_operand:SI 0 "register_operand" "=f")
3250 (div:SI (match_operand:SI 1 "register_operand" "f")
3251 (match_operand:SI 2 "register_operand" "f")))
3252 (use (unspec:SI [(match_dup 1)
3253 (match_operand:SI 3 "" "")
3254 (unspec:SI [(match_operand:SI 4 "" "")
3256 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3257 (match_operand:DI 6 "" "")
3259 (const_int 0)] UNSPEC_DIV_INV_M3))
3260 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3261 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3262 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3263 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3264 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3265 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3268 [(set (match_dup 9) (float:DF (match_dup 1)))
3269 (set (match_dup 10) (float:DF (match_dup 2)))
3270 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3272 (fix:SI (match_dup 11)))
3273 (set (match_dup 0) (match_dup 8))]
3275 if (! fp_arith_reg_operand (operands[1], SImode))
3277 emit_move_insn (operands[7], operands[1]);
3278 operands[1] = operands[7];
3280 if (! fp_arith_reg_operand (operands[2], SImode))
3282 emit_move_insn (operands[8], operands[2]);
3283 operands[2] = operands[8];
3286 [(set_attr "highpart" "must_split")])
3288 ;; -------------------------------------------------------------------------
3289 ;; Multiplication instructions
3290 ;; -------------------------------------------------------------------------
3292 (define_insn "umulhisi3_i"
3293 [(set (reg:SI MACL_REG)
3294 (mult:SI (zero_extend:SI
3295 (match_operand:HI 0 "arith_reg_operand" "r"))
3297 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3300 [(set_attr "type" "smpy")])
3302 (define_insn "mulhisi3_i"
3303 [(set (reg:SI MACL_REG)
3304 (mult:SI (sign_extend:SI
3305 (match_operand:HI 0 "arith_reg_operand" "r"))
3307 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3310 [(set_attr "type" "smpy")])
3312 (define_expand "mulhisi3"
3313 [(set (reg:SI MACL_REG)
3314 (mult:SI (sign_extend:SI
3315 (match_operand:HI 1 "arith_reg_operand" ""))
3317 (match_operand:HI 2 "arith_reg_operand" ""))))
3318 (set (match_operand:SI 0 "arith_reg_operand" "")
3324 macl = gen_rtx_REG (SImode, MACL_REG);
3326 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3327 insn = get_insns ();
3329 /* expand_binop can't find a suitable code in umul_widen_optab to
3330 make a REG_EQUAL note from, so make one here.
3331 See also smulsi3_highpart.
3332 ??? Alternatively, we could put this at the calling site of expand_binop,
3333 i.e. expand_expr. */
3334 /* Use emit_libcall_block for loop invariant code motion and to make
3335 a REG_EQUAL note. */
3336 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3341 (define_expand "umulhisi3"
3342 [(set (reg:SI MACL_REG)
3343 (mult:SI (zero_extend:SI
3344 (match_operand:HI 1 "arith_reg_operand" ""))
3346 (match_operand:HI 2 "arith_reg_operand" ""))))
3347 (set (match_operand:SI 0 "arith_reg_operand" "")
3353 macl = gen_rtx_REG (SImode, MACL_REG);
3355 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3356 insn = get_insns ();
3358 /* expand_binop can't find a suitable code in umul_widen_optab to
3359 make a REG_EQUAL note from, so make one here.
3360 See also smulsi3_highpart.
3361 ??? Alternatively, we could put this at the calling site of expand_binop,
3362 i.e. expand_expr. */
3363 /* Use emit_libcall_block for loop invariant code motion and to make
3364 a REG_EQUAL note. */
3365 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3370 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3371 ;; a call to a routine which clobbers known registers.
3373 [(set (match_operand:SI 1 "register_operand" "=z")
3374 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3375 (clobber (reg:SI MACL_REG))
3376 (clobber (reg:SI T_REG))
3377 (clobber (reg:SI PR_REG))
3378 (clobber (reg:SI R3_REG))
3379 (clobber (reg:SI R2_REG))
3380 (clobber (reg:SI R1_REG))
3381 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3384 [(set_attr "type" "sfunc")
3385 (set_attr "needs_delay_slot" "yes")])
3387 (define_expand "mulsi3_call"
3388 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3389 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3390 (parallel[(set (match_operand:SI 0 "register_operand" "")
3391 (mult:SI (reg:SI R4_REG)
3393 (clobber (reg:SI MACL_REG))
3394 (clobber (reg:SI T_REG))
3395 (clobber (reg:SI PR_REG))
3396 (clobber (reg:SI R3_REG))
3397 (clobber (reg:SI R2_REG))
3398 (clobber (reg:SI R1_REG))
3399 (use (match_operand:SI 3 "register_operand" ""))])]
3403 (define_insn "mul_r"
3404 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3405 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3406 (match_operand:SI 2 "arith_reg_operand" "z")))]
3409 [(set_attr "type" "dmpy")])
3411 (define_insn "mul_l"
3412 [(set (reg:SI MACL_REG)
3413 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3414 (match_operand:SI 1 "arith_reg_operand" "r")))]
3417 [(set_attr "type" "dmpy")])
3419 (define_expand "mulsi3"
3420 [(set (reg:SI MACL_REG)
3421 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
3422 (match_operand:SI 2 "arith_reg_operand" "")))
3423 (set (match_operand:SI 0 "arith_reg_operand" "")
3429 /* The address must be set outside the libcall,
3430 since it goes into a pseudo. */
3431 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3432 rtx addr = force_reg (SImode, sym);
3433 rtx insns = gen_mulsi3_call (operands[0], operands[1],
3439 rtx macl = gen_rtx_REG (SImode, MACL_REG);
3441 emit_insn (gen_mul_l (operands[1], operands[2]));
3442 /* consec_sets_giv can only recognize the first insn that sets a
3443 giv as the giv insn. So we must tag this also with a REG_EQUAL
3445 emit_insn (gen_movsi_i ((operands[0]), macl));
3450 (define_insn "mulsidi3_i"
3451 [(set (reg:SI MACH_REG)
3455 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3456 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3458 (set (reg:SI MACL_REG)
3459 (mult:SI (match_dup 0)
3463 [(set_attr "type" "dmpy")])
3465 (define_expand "mulsidi3"
3466 [(set (match_operand:DI 0 "arith_reg_dest" "")
3467 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3468 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3469 "TARGET_SH2 || TARGET_SHMEDIA"
3473 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3478 (define_insn "mulsidi3_media"
3479 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3480 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3481 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3484 [(set_attr "type" "dmpy_media")
3485 (set_attr "highpart" "ignore")])
3487 (define_insn_and_split "mulsidi3_compact"
3488 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3490 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3491 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3492 (clobber (reg:SI MACH_REG))
3493 (clobber (reg:SI MACL_REG))]
3499 rtx low_dst = gen_lowpart (SImode, operands[0]);
3500 rtx high_dst = gen_highpart (SImode, operands[0]);
3502 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3504 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3505 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3506 /* We need something to tag the possible REG_EQUAL notes on to. */
3507 emit_move_insn (operands[0], operands[0]);
3511 (define_insn "umulsidi3_i"
3512 [(set (reg:SI MACH_REG)
3516 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3517 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3519 (set (reg:SI MACL_REG)
3520 (mult:SI (match_dup 0)
3524 [(set_attr "type" "dmpy")])
3526 (define_expand "umulsidi3"
3527 [(set (match_operand:DI 0 "arith_reg_dest" "")
3528 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3529 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3530 "TARGET_SH2 || TARGET_SHMEDIA"
3534 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3539 (define_insn "umulsidi3_media"
3540 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3541 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3542 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3545 [(set_attr "type" "dmpy_media")
3546 (set_attr "highpart" "ignore")])
3548 (define_insn_and_split "umulsidi3_compact"
3549 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3551 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3552 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3553 (clobber (reg:SI MACH_REG))
3554 (clobber (reg:SI MACL_REG))]
3560 rtx low_dst = gen_lowpart (SImode, operands[0]);
3561 rtx high_dst = gen_highpart (SImode, operands[0]);
3563 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3565 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3566 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3567 /* We need something to tag the possible REG_EQUAL notes on to. */
3568 emit_move_insn (operands[0], operands[0]);
3572 (define_insn "smulsi3_highpart_i"
3573 [(set (reg:SI MACH_REG)
3577 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3578 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3580 (clobber (reg:SI MACL_REG))]
3583 [(set_attr "type" "dmpy")])
3585 (define_expand "smulsi3_highpart"
3587 [(set (reg:SI MACH_REG)
3591 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3592 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3594 (clobber (reg:SI MACL_REG))])
3595 (set (match_operand:SI 0 "arith_reg_operand" "")
3601 mach = gen_rtx_REG (SImode, MACH_REG);
3603 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3604 insn = get_insns ();
3606 /* expand_binop can't find a suitable code in mul_highpart_optab to
3607 make a REG_EQUAL note from, so make one here.
3608 See also {,u}mulhisi.
3609 ??? Alternatively, we could put this at the calling site of expand_binop,
3610 i.e. expand_mult_highpart. */
3611 /* Use emit_libcall_block for loop invariant code motion and to make
3612 a REG_EQUAL note. */
3613 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3618 (define_insn "umulsi3_highpart_i"
3619 [(set (reg:SI MACH_REG)
3623 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3624 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3626 (clobber (reg:SI MACL_REG))]
3629 [(set_attr "type" "dmpy")])
3631 (define_expand "umulsi3_highpart"
3633 [(set (reg:SI MACH_REG)
3637 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3638 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3640 (clobber (reg:SI MACL_REG))])
3641 (set (match_operand:SI 0 "arith_reg_operand" "")
3647 mach = gen_rtx_REG (SImode, MACH_REG);
3649 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3650 insn = get_insns ();
3652 /* Use emit_libcall_block for loop invariant code motion and to make
3653 a REG_EQUAL note. */
3654 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3659 (define_insn_and_split "muldi3"
3660 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3661 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3662 (match_operand:DI 2 "arith_reg_operand" "r")))
3663 (clobber (match_scratch:DI 3 "=&r"))
3664 (clobber (match_scratch:DI 4 "=r"))]
3670 rtx op3_v2si, op2_v2si;
3672 op3_v2si = operands[3];
3673 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3675 op3_v2si = XEXP (op3_v2si, 0);
3676 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3678 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3679 op2_v2si = operands[2];
3680 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3682 op2_v2si = XEXP (op2_v2si, 0);
3683 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3685 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3686 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3687 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3688 emit_insn (gen_umulsidi3_media (operands[4],
3689 sh_gen_truncate (SImode, operands[1], 0),
3690 sh_gen_truncate (SImode, operands[2], 0)));
3691 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3692 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3693 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3694 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3698 ;; -------------------------------------------------------------------------
3699 ;; Logical operations
3700 ;; -------------------------------------------------------------------------
3702 (define_expand "andsi3"
3703 [(set (match_operand:SI 0 "arith_reg_operand" "")
3704 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3705 (match_operand:SI 2 "logical_and_operand" "")))]
3708 /* If it is possible to turn the and insn into a zero extension
3709 already, redundant zero extensions will be folded, which results
3711 Ideally the splitter of *andsi_compact would be enough, if redundant
3712 zero extensions were detected after the combine pass, which does not
3713 happen at the moment. */
3716 if (satisfies_constraint_Jmb (operands[2]))
3718 emit_insn (gen_zero_extendqisi2 (operands[0],
3719 gen_lowpart (QImode, operands[1])));
3722 else if (satisfies_constraint_Jmw (operands[2]))
3724 emit_insn (gen_zero_extendhisi2 (operands[0],
3725 gen_lowpart (HImode, operands[1])));
3731 (define_insn_and_split "*andsi_compact"
3732 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3733 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3734 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3742 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3744 if (satisfies_constraint_Jmb (operands[2]))
3745 operands[1] = gen_lowpart (QImode, operands[1]);
3746 else if (satisfies_constraint_Jmw (operands[2]))
3747 operands[1] = gen_lowpart (HImode, operands[1]);
3751 [(set_attr "type" "arith")])
3753 (define_insn "*andsi3_media"
3754 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3755 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3756 (match_operand:SI 2 "logical_operand" "r,I10")))]
3761 [(set_attr "type" "arith_media")])
3763 (define_insn "*andsi3_bclr"
3764 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3765 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3766 (match_operand:SI 2 "const_int_operand" "Psz")))]
3767 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3769 [(set_attr "type" "arith")])
3771 (define_insn_and_split "anddi3"
3772 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3773 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3774 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3781 && ! logical_operand (operands[2], DImode)"
3784 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3785 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3787 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3790 [(set_attr "type" "arith_media")])
3792 (define_insn "andcsi3"
3793 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3794 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3795 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3798 [(set_attr "type" "arith_media")])
3800 (define_insn "andcdi3"
3801 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3802 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3803 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3806 [(set_attr "type" "arith_media")])
3808 (define_expand "iorsi3"
3809 [(set (match_operand:SI 0 "arith_reg_operand" "")
3810 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3811 (match_operand:SI 2 "logical_operand" "")))]
3815 (define_insn "*iorsi3_compact"
3816 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3817 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3818 (match_operand:SI 2 "logical_operand" "r,K08")))]
3820 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3822 [(set_attr "type" "arith")])
3824 (define_insn "*iorsi3_media"
3825 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3826 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3827 (match_operand:SI 2 "logical_operand" "r,I10")))]
3832 [(set_attr "type" "arith_media")])
3834 (define_insn "*iorsi3_bset"
3835 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3836 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3837 (match_operand:SI 2 "const_int_operand" "Pso")))]
3838 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3840 [(set_attr "type" "arith")])
3842 (define_insn "iordi3"
3843 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3844 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3845 (match_operand:DI 2 "logical_operand" "r,I10")))]
3850 [(set_attr "type" "arith_media")])
3852 (define_insn_and_split "*logical_sidi3"
3853 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3854 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3855 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3856 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3859 "&& reload_completed"
3860 [(set (match_dup 0) (match_dup 3))]
3863 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3864 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3865 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3868 (define_insn_and_split "*logical_sidisi3"
3869 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3870 (truncate:SI (sign_extend:DI
3871 (match_operator:SI 3 "logical_operator"
3872 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3873 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3877 [(set (match_dup 0) (match_dup 3))])
3879 (define_insn_and_split "*logical_sidi3_2"
3880 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3881 (sign_extend:DI (truncate:SI (sign_extend:DI
3882 (match_operator:SI 3 "logical_operator"
3883 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3884 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3888 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3890 (define_expand "xorsi3"
3891 [(set (match_operand:SI 0 "arith_reg_operand" "")
3892 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3893 (match_operand:SI 2 "xor_operand" "")))]
3897 (define_insn "*xorsi3_compact"
3898 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3899 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3900 (match_operand:SI 2 "logical_operand" "K08,r")))]
3903 [(set_attr "type" "arith")])
3905 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
3906 ;; of results where one of the inputs is a T bit store. Notice that this
3907 ;; pattern must not match during reload. If reload picks this pattern it
3908 ;; will be impossible to split it afterwards.
3909 (define_insn_and_split "*logical_op_t"
3910 [(set (match_operand:SI 0 "arith_reg_dest")
3911 (match_operator:SI 3 "logical_operator"
3912 [(match_operand:SI 1 "arith_reg_operand")
3913 (match_operand:SI 2 "t_reg_operand")]))]
3914 "TARGET_SH1 && can_create_pseudo_p ()"
3917 [(set (match_dup 4) (reg:SI T_REG))
3918 (set (match_dup 0) (match_dup 3))]
3920 operands[4] = gen_reg_rtx (SImode);
3921 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3922 operands[1], operands[4]);
3925 (define_insn "*xorsi3_media"
3926 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3927 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3928 (match_operand:SI 2 "xor_operand" "r,I06")))]
3933 [(set_attr "type" "arith_media")])
3935 (define_insn "xordi3"
3936 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3937 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3938 (match_operand:DI 2 "xor_operand" "r,I06")))]
3943 [(set_attr "type" "arith_media")])
3945 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3946 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3948 [(set (match_operand:DI 0 "arith_reg_dest" "")
3949 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3950 [(match_operand 1 "any_register_operand" "")
3951 (match_operand 2 "any_register_operand" "")])))]
3953 [(set (match_dup 5) (match_dup 4))
3954 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3956 enum machine_mode inmode = GET_MODE (operands[1]);
3959 if (GET_CODE (operands[0]) == SUBREG)
3961 offset = SUBREG_BYTE (operands[0]);
3962 operands[0] = SUBREG_REG (operands[0]);
3964 gcc_assert (REG_P (operands[0]));
3965 if (TARGET_BIG_ENDIAN)
3966 offset += 8 - GET_MODE_SIZE (inmode);
3967 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3970 ;; -------------------------------------------------------------------------
3971 ;; Shifts and rotates
3972 ;; -------------------------------------------------------------------------
3974 (define_expand "rotldi3"
3975 [(set (match_operand:DI 0 "arith_reg_dest" "")
3976 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
3977 (match_operand:HI 2 "mextr_bit_offset" "")))]
3980 if (! mextr_bit_offset (operands[2], HImode))
3984 (define_insn "rotldi3_mextr"
3985 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3986 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3987 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3990 static char templ[16];
3991 sprintf (templ, "mextr%d %%1,%%1,%%0",
3992 8 - (int) (INTVAL (operands[2]) >> 3));
3995 [(set_attr "type" "arith_media")])
3997 (define_expand "rotrdi3"
3998 [(set (match_operand:DI 0 "arith_reg_dest" "")
3999 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
4000 (match_operand:HI 2 "mextr_bit_offset" "")))]
4003 if (! mextr_bit_offset (operands[2], HImode))
4007 (define_insn "rotrdi3_mextr"
4008 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4009 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
4010 (match_operand:HI 2 "mextr_bit_offset" "i")))]
4013 static char templ[16];
4014 sprintf (templ, "mextr%d %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
4017 [(set_attr "type" "arith_media")])
4020 [(set (match_operand:DI 0 "arith_reg_dest" "")
4021 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
4022 "ua_address_operand" "")))
4023 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
4025 (clobber (match_operand:DI 3 "register_operand" ""))]
4027 [(match_dup 4) (match_dup 5)]
4029 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
4030 (operands[3], operands[1]));
4031 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
4032 GEN_INT (56), GEN_INT (8));
4035 (define_expand "rotrsi3"
4036 [(set (match_operand:SI 0 "arith_reg_dest")
4037 (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
4038 (match_operand:SI 2 "const_int_operand")))]
4041 HOST_WIDE_INT ival = INTVAL (operands[2]);
4044 emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
4051 (define_insn "rotrsi3_1"
4052 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4053 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4056 (and:SI (match_dup 1) (const_int 1)))]
4059 [(set_attr "type" "arith")])
4061 ;; A slimplified version of rotr for combine.
4062 (define_insn "*rotrsi3_1"
4063 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4064 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
4066 (clobber (reg:SI T_REG))]
4069 [(set_attr "type" "arith")])
4071 (define_insn "rotlsi3_1"
4072 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4073 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4076 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4079 [(set_attr "type" "arith")])
4081 ;; A simplified version of rotl for combine.
4082 (define_insn "*rotlsi3_1"
4083 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4084 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4086 (clobber (reg:SI T_REG))]
4089 [(set_attr "type" "arith")])
4091 (define_insn "rotlsi3_31"
4092 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4093 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
4095 (clobber (reg:SI T_REG))]
4098 [(set_attr "type" "arith")])
4100 (define_insn "rotlsi3_16"
4101 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4102 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
4106 [(set_attr "type" "arith")])
4108 (define_expand "rotlsi3"
4109 [(set (match_operand:SI 0 "arith_reg_dest")
4110 (rotate:SI (match_operand:SI 1 "arith_reg_operand")
4111 (match_operand:SI 2 "const_int_operand")))]
4114 static const char rot_tab[] = {
4115 000, 000, 000, 000, 000, 000, 010, 001,
4116 001, 001, 011, 013, 003, 003, 003, 003,
4117 003, 003, 003, 003, 003, 013, 012, 002,
4118 002, 002, 010, 000, 000, 000, 000, 000,
4121 int count = INTVAL (operands[2]);
4122 int choice = rot_tab[count];
4123 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
4129 emit_move_insn (operands[0], operands[1]);
4130 count -= (count & 16) * 2;
4133 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
4140 parts[0] = gen_reg_rtx (SImode);
4141 parts[1] = gen_reg_rtx (SImode);
4142 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
4143 emit_move_insn (parts[choice-1], operands[1]);
4144 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
4145 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
4146 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
4147 count = (count & ~16) - 8;
4151 for (; count > 0; count--)
4152 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
4153 for (; count < 0; count++)
4154 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4159 (define_insn "rotlhi3_8"
4160 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4161 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
4165 [(set_attr "type" "arith")])
4167 (define_expand "rotlhi3"
4168 [(set (match_operand:HI 0 "arith_reg_operand")
4169 (rotate:HI (match_operand:HI 1 "arith_reg_operand")
4170 (match_operand:HI 2 "const_int_operand")))]
4173 if (INTVAL (operands[2]) != 8)
4177 ;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
4178 ;; They can also be used to implement things like
4180 ;; int x0 = (y >> 1) | (t << 31); // rotcr
4181 ;; int x1 = (y << 1) | t; // rotcl
4182 (define_insn "rotcr"
4183 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4184 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4186 (ashift:SI (match_operand:SI 2 "t_reg_operand")
4189 (and:SI (match_dup 1) (const_int 1)))]
4192 [(set_attr "type" "arith")])
4194 (define_insn "rotcl"
4195 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4196 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4198 (match_operand:SI 2 "t_reg_operand")))
4200 (lshiftrt:SI (match_dup 1) (const_int 31)))]
4203 [(set_attr "type" "arith")])
4205 ;; Simplified rotcr version for combine, which allows arbitrary shift
4206 ;; amounts for the reg. If the shift amount is '1' rotcr can be used
4207 ;; directly. Otherwise we have to insert a shift in between.
4208 (define_insn_and_split "*rotcr"
4209 [(set (match_operand:SI 0 "arith_reg_dest")
4210 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4211 (match_operand:SI 2 "const_int_operand"))
4212 (ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4214 (clobber (reg:SI T_REG))]
4217 "&& can_create_pseudo_p ()"
4220 if (INTVAL (operands[2]) > 1)
4222 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4223 rtx prev_set_t_insn = NULL_RTX;
4224 rtx tmp_t_reg = NULL_RTX;
4226 /* If we're going to emit a shift sequence that clobbers the T_REG,
4227 try to find the previous insn that sets the T_REG and emit the
4228 shift insn before that insn, to remove the T_REG dependency.
4229 If the insn that sets the T_REG cannot be found, store the T_REG
4230 in a temporary reg and restore it after the shift. */
4231 if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4232 && ! sh_dynamicalize_shift_p (shift_count))
4234 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4236 /* Skip the nott insn, which was probably inserted by the splitter
4237 of *rotcr_neg_t. Don't use one of the recog functions
4238 here during insn splitting, since that causes problems in later
4240 if (prev_set_t_insn != NULL_RTX)
4242 rtx pat = PATTERN (prev_set_t_insn);
4243 if (GET_CODE (pat) == SET
4244 && t_reg_operand (XEXP (pat, 0), SImode)
4245 && negt_reg_operand (XEXP (pat, 1), SImode))
4246 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4249 if (! (prev_set_t_insn != NULL_RTX
4250 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4251 && ! reg_referenced_p (get_t_reg_rtx (),
4252 PATTERN (prev_set_t_insn))))
4254 prev_set_t_insn = NULL_RTX;
4255 tmp_t_reg = gen_reg_rtx (SImode);
4256 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4260 rtx shift_result = gen_reg_rtx (SImode);
4261 rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4262 operands[1] = shift_result;
4264 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4265 if (prev_set_t_insn != NULL_RTX)
4266 emit_insn_before (shift_insn, prev_set_t_insn);
4268 emit_insn (shift_insn);
4270 /* Restore T_REG if it has been saved before. */
4271 if (tmp_t_reg != NULL_RTX)
4272 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4275 /* For the rotcr insn to work, operands[3] must be in T_REG.
4276 If it is not we can get it there by shifting it right one bit.
4277 In this case T_REG is not an input for this insn, thus we don't have to
4278 pay attention as of where to insert the shlr insn. */
4279 if (! t_reg_operand (operands[3], SImode))
4281 /* We don't care about the shifted result here, only the T_REG. */
4282 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4283 operands[3] = get_t_reg_rtx ();
4286 emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4290 ;; If combine tries the same as above but with swapped operands, split
4291 ;; it so that it will try the pattern above.
4293 [(set (match_operand:SI 0 "arith_reg_dest")
4294 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4296 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4297 (match_operand:SI 3 "const_int_operand"))))]
4298 "TARGET_SH1 && can_create_pseudo_p ()"
4299 [(parallel [(set (match_dup 0)
4300 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4301 (ashift:SI (match_dup 1) (const_int 31))))
4302 (clobber (reg:SI T_REG))])])
4304 ;; Basically the same as the rotcr pattern above, but for rotcl.
4305 ;; FIXME: Fold copy pasted split code for rotcr and rotcl.
4306 (define_insn_and_split "*rotcl"
4307 [(set (match_operand:SI 0 "arith_reg_dest")
4308 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4309 (match_operand:SI 2 "const_int_operand"))
4310 (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4312 (clobber (reg:SI T_REG))]
4315 "&& can_create_pseudo_p ()"
4318 gcc_assert (INTVAL (operands[2]) > 0);
4320 if (INTVAL (operands[2]) > 1)
4322 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4323 rtx prev_set_t_insn = NULL_RTX;
4324 rtx tmp_t_reg = NULL_RTX;
4326 /* If we're going to emit a shift sequence that clobbers the T_REG,
4327 try to find the previous insn that sets the T_REG and emit the
4328 shift insn before that insn, to remove the T_REG dependency.
4329 If the insn that sets the T_REG cannot be found, store the T_REG
4330 in a temporary reg and restore it after the shift. */
4331 if (sh_ashlsi_clobbers_t_reg_p (shift_count)
4332 && ! sh_dynamicalize_shift_p (shift_count))
4334 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4336 /* Skip the nott insn, which was probably inserted by the splitter
4337 of *rotcl_neg_t. Don't use one of the recog functions
4338 here during insn splitting, since that causes problems in later
4340 if (prev_set_t_insn != NULL_RTX)
4342 rtx pat = PATTERN (prev_set_t_insn);
4343 if (GET_CODE (pat) == SET
4344 && t_reg_operand (XEXP (pat, 0), SImode)
4345 && negt_reg_operand (XEXP (pat, 1), SImode))
4346 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4349 if (! (prev_set_t_insn != NULL_RTX
4350 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4351 && ! reg_referenced_p (get_t_reg_rtx (),
4352 PATTERN (prev_set_t_insn))))
4354 prev_set_t_insn = NULL_RTX;
4355 tmp_t_reg = gen_reg_rtx (SImode);
4356 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4360 rtx shift_result = gen_reg_rtx (SImode);
4361 rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
4362 operands[1] = shift_result;
4364 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4365 if (prev_set_t_insn != NULL_RTX)
4366 emit_insn_before (shift_insn, prev_set_t_insn);
4368 emit_insn (shift_insn);
4370 /* Restore T_REG if it has been saved before. */
4371 if (tmp_t_reg != NULL_RTX)
4372 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4375 /* For the rotcl insn to work, operands[3] must be in T_REG.
4376 If it is not we can get it there by shifting it right one bit.
4377 In this case T_REG is not an input for this insn, thus we don't have to
4378 pay attention as of where to insert the shlr insn. */
4379 if (! t_reg_operand (operands[3], SImode))
4381 /* We don't care about the shifted result here, only the T_REG. */
4382 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4383 operands[3] = get_t_reg_rtx ();
4386 emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
4390 ;; rotcl combine pattern variations
4391 (define_insn_and_split "*rotcl"
4392 [(set (match_operand:SI 0 "arith_reg_dest")
4393 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4394 (match_operand:SI 2 "const_int_operand"))
4395 (match_operand:SI 3 "t_reg_operand")))
4396 (clobber (reg:SI T_REG))]
4399 "&& can_create_pseudo_p ()"
4400 [(parallel [(set (match_dup 0)
4401 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4402 (and:SI (match_dup 3) (const_int 1))))
4403 (clobber (reg:SI T_REG))])])
4405 (define_insn_and_split "*rotcl"
4406 [(set (match_operand:SI 0 "arith_reg_dest")
4407 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4409 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4410 (match_operand:SI 3 "const_int_operand"))))
4411 (clobber (reg:SI T_REG))]
4414 "&& can_create_pseudo_p ()"
4415 [(parallel [(set (match_dup 0)
4416 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4417 (and:SI (match_dup 1) (const_int 1))))
4418 (clobber (reg:SI T_REG))])])
4420 (define_insn_and_split "*rotcl"
4421 [(set (match_operand:SI 0 "arith_reg_dest")
4422 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4423 (match_operand:SI 2 "const_int_operand"))
4424 (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4426 (clobber (reg:SI T_REG))]
4429 "&& can_create_pseudo_p ()"
4430 [(parallel [(set (match_dup 0)
4431 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4432 (and:SI (reg:SI T_REG) (const_int 1))))
4433 (clobber (reg:SI T_REG))])]
4435 /* We don't care about the result of the left shift, only the T_REG. */
4436 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4439 (define_insn_and_split "*rotcl"
4440 [(set (match_operand:SI 0 "arith_reg_dest")
4441 (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
4443 (ashift:SI (match_operand:SI 1 "arith_reg_operand")
4444 (match_operand:SI 2 "const_int_operand"))))
4445 (clobber (reg:SI T_REG))]
4448 "&& can_create_pseudo_p ()"
4449 [(parallel [(set (match_dup 0)
4450 (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
4451 (and:SI (reg:SI T_REG) (const_int 1))))
4452 (clobber (reg:SI T_REG))])]
4454 /* We don't care about the result of the left shift, only the T_REG. */
4455 emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
4458 ;; rotcr combine bridge pattern which will make combine try out more
4459 ;; complex patterns.
4460 (define_insn_and_split "*rotcr"
4461 [(set (match_operand:SI 0 "arith_reg_dest")
4462 (ashift:SI (match_operand:SI 1 "t_reg_operand") (const_int 31)))]
4466 [(set (match_dup 0) (match_dup 1))
4467 (parallel [(set (match_dup 0)
4468 (ior:SI (lshiftrt:SI (match_dup 0) (const_int 1))
4469 (ashift:SI (match_dup 1) (const_int 31))))
4471 (and:SI (match_dup 0) (const_int 1)))])])
4473 (define_insn_and_split "*rotcr"
4474 [(set (match_operand:SI 0 "arith_reg_dest")
4475 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4476 (const_int -2147483648)) ;; 0xffffffff80000000
4477 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4479 (clobber (reg:SI T_REG))]
4482 "&& can_create_pseudo_p ()"
4485 rtx tmp = gen_reg_rtx (SImode);
4486 emit_insn (gen_shll (tmp, operands[1]));
4487 emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4491 ;; rotcr combine patterns for rotating in the negated T_REG value.
4492 (define_insn_and_split "*rotcr_neg_t"
4493 [(set (match_operand:SI 0 "arith_reg_dest")
4494 (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4495 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4496 (match_operand:SI 3 "const_int_operand"))))
4497 (clobber (reg:SI T_REG))]
4500 "&& can_create_pseudo_p ()"
4501 [(parallel [(set (match_dup 0)
4502 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4503 (ashift:SI (reg:SI T_REG) (const_int 31))))
4504 (clobber (reg:SI T_REG))])]
4506 emit_insn (gen_nott (get_t_reg_rtx ()));
4509 (define_insn_and_split "*rotcr_neg_t"
4510 [(set (match_operand:SI 0 "arith_reg_dest")
4511 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4512 (match_operand:SI 2 "const_int_operand"))
4513 (match_operand:SI 3 "negt_reg_shl31_operand")))
4514 (clobber (reg:SI T_REG))]
4517 "&& can_create_pseudo_p ()"
4518 [(parallel [(set (match_dup 0)
4519 (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4520 (ashift:SI (reg:SI T_REG) (const_int 31))))
4521 (clobber (reg:SI T_REG))])]
4523 emit_insn (gen_nott (get_t_reg_rtx ()));
4526 ;; rotcl combine patterns for rotating in the negated T_REG value.
4527 ;; For some strange reason these have to be specified as splits which combine
4528 ;; will pick up. If they are specified as insn_and_split like the
4529 ;; *rotcr_neg_t patterns above, combine would recognize them successfully
4530 ;; but not emit them on non-SH2A targets.
4532 [(set (match_operand:SI 0 "arith_reg_dest")
4533 (ior:SI (match_operand:SI 1 "negt_reg_operand")
4534 (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4535 (match_operand:SI 3 "const_int_operand"))))]
4537 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4538 (parallel [(set (match_dup 0)
4539 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4540 (and:SI (reg:SI T_REG) (const_int 1))))
4541 (clobber (reg:SI T_REG))])])
4544 [(set (match_operand:SI 0 "arith_reg_dest")
4545 (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
4546 (match_operand:SI 3 "const_int_operand"))
4547 (match_operand:SI 1 "negt_reg_operand")))]
4549 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
4550 (parallel [(set (match_dup 0)
4551 (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
4552 (and:SI (reg:SI T_REG) (const_int 1))))
4553 (clobber (reg:SI T_REG))])])
4555 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4556 ;; SImode shift left
4558 (define_expand "ashlsi3"
4559 [(set (match_operand:SI 0 "arith_reg_operand" "")
4560 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4561 (match_operand:SI 2 "shift_count_operand" "")))]
4566 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4570 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4571 operands[2] = force_reg (SImode, operands[2]);
4573 /* If the ashlsi3_* insn is going to clobber the T_REG it must be
4575 if (CONST_INT_P (operands[2])
4576 && sh_ashlsi_clobbers_t_reg_p (operands[2])
4577 && ! sh_dynamicalize_shift_p (operands[2]))
4579 emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4584 /* Expand a library call for the dynamic shift. */
4585 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4587 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4588 rtx funcaddr = gen_reg_rtx (Pmode);
4589 function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4590 emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4596 (define_insn "ashlsi3_k"
4597 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4598 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4599 (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4604 [(set_attr "type" "arith")])
4606 (define_insn_and_split "ashlsi3_d"
4607 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4608 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4609 (match_operand:SI 2 "shift_count_operand" "r")))]
4612 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4613 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4616 if (satisfies_constraint_P27 (operands[2]))
4618 emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
4621 else if (! satisfies_constraint_P27 (operands[2]))
4623 /* This must happen before reload, otherwise the constant will be moved
4624 into a register due to the "r" constraint, after which this split
4625 cannot be done anymore.
4626 Unfortunately the move insn will not always be eliminated.
4627 Also, here we must not create a shift sequence that clobbers the
4629 emit_move_insn (operands[0], operands[1]);
4630 gen_shifty_op (ASHIFT, operands);
4636 [(set_attr "type" "dyn_shift")])
4638 ;; If dynamic shifts are not available use a library function.
4639 ;; By specifying the pattern we reduce the number of call clobbered regs.
4640 ;; In order to make combine understand the truncation of the shift amount
4641 ;; operand we have to allow it to use pseudo regs for the shift operands.
4642 (define_insn "ashlsi3_d_call"
4643 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4644 (ashift:SI (reg:SI R4_REG)
4645 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4647 (use (match_operand:SI 2 "arith_reg_operand" "r"))
4648 (clobber (reg:SI T_REG))
4649 (clobber (reg:SI PR_REG))]
4650 "TARGET_SH1 && !TARGET_DYNSHIFT"
4652 [(set_attr "type" "sfunc")
4653 (set_attr "needs_delay_slot" "yes")])
4655 (define_insn_and_split "ashlsi3_n"
4656 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4657 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4658 (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
4659 "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4661 "&& (reload_completed
4662 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4665 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4667 /* If this pattern was picked and dynamic shifts are supported, switch
4668 to dynamic shift pattern before reload. */
4669 operands[2] = force_reg (SImode, operands[2]);
4670 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4673 gen_shifty_op (ASHIFT, operands);
4678 (define_insn_and_split "ashlsi3_n_clobbers_t"
4679 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4680 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4681 (match_operand:SI 2 "not_p27_shift_count_operand" "")))
4682 (clobber (reg:SI T_REG))]
4683 "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
4685 "&& (reload_completed || INTVAL (operands[2]) == 31
4686 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4689 if (INTVAL (operands[2]) == 31)
4691 /* If the shift amount is 31 we split into a different sequence before
4692 reload so that it gets a chance to allocate R0 for the sequence.
4693 If it fails to do so (due to pressure on R0), it will take one insn
4694 more for the and. */
4695 emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
4696 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4698 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4700 /* If this pattern was picked and dynamic shifts are supported, switch
4701 to dynamic shift pattern before reload. */
4702 operands[2] = force_reg (SImode, operands[2]);
4703 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4706 gen_shifty_op (ASHIFT, operands);
4712 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4713 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4715 (lt:SI (match_dup 1) (const_int 0)))]
4718 [(set_attr "type" "arith")])
4720 (define_insn "*ashlsi_c_void"
4721 [(set (reg:SI T_REG)
4722 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
4723 (clobber (match_scratch:SI 1 "=0"))]
4724 "TARGET_SH1 && cse_not_expected"
4726 [(set_attr "type" "arith")])
4729 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
4731 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
4733 && peep2_reg_dead_p (2, operands[0])
4734 && peep2_reg_dead_p (2, operands[1])"
4737 emit_insn (gen_shll (operands[1], operands[1]));
4741 (define_insn "ashlsi3_media"
4742 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4743 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4744 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4749 [(set_attr "type" "arith_media")
4750 (set_attr "highpart" "ignore")])
4752 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4753 ;; HImode shift left
4755 (define_expand "ashlhi3"
4756 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
4757 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
4758 (match_operand:SI 2 "nonmemory_operand" "")))
4759 (clobber (reg:SI T_REG))])]
4762 if (!CONST_INT_P (operands[2]))
4764 /* It may be possible to call gen_ashlhi3 directly with more generic
4765 operands. Make sure operands[1] is a HImode register here. */
4766 if (!arith_reg_operand (operands[1], HImode))
4767 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4770 (define_insn "ashlhi3_k"
4771 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4772 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
4773 (match_operand:HI 2 "const_int_operand" "M,P27")))]
4774 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
4778 [(set_attr "type" "arith")])
4780 (define_insn_and_split "*ashlhi3_n"
4781 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4782 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
4783 (match_operand:HI 2 "const_int_operand" "n")))
4784 (clobber (reg:SI T_REG))]
4787 "&& reload_completed"
4788 [(use (reg:SI R0_REG))]
4790 gen_shifty_hi_op (ASHIFT, operands);
4794 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4795 ;; DImode shift left
4797 (define_expand "ashldi3"
4798 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4799 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4800 (match_operand:DI 2 "immediate_operand" "")))
4801 (clobber (reg:SI T_REG))])]
4806 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4809 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
4811 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4814 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
4816 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4823 ;; Expander for DImode shift left with SImode operations.
4824 (define_expand "ashldi3_std"
4825 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4826 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4827 (match_operand:DI 2 "const_int_operand" "n")))]
4828 "TARGET_SH1 && INTVAL (operands[2]) < 32"
4830 rtx low_src = gen_lowpart (SImode, operands[1]);
4831 rtx high_src = gen_highpart (SImode, operands[1]);
4832 rtx dst = gen_reg_rtx (DImode);
4833 rtx low_dst = gen_lowpart (SImode, dst);
4834 rtx high_dst = gen_highpart (SImode, dst);
4835 rtx tmp0 = gen_reg_rtx (SImode);
4836 rtx tmp1 = gen_reg_rtx (SImode);
4838 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4839 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
4840 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
4841 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4842 emit_move_insn (operands[0], dst);
4846 (define_insn_and_split "ashldi3_k"
4847 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4848 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
4850 (clobber (reg:SI T_REG))]
4853 "&& reload_completed"
4856 rtx high = gen_highpart (SImode, operands[0]);
4857 rtx low = gen_lowpart (SImode, operands[0]);
4858 emit_insn (gen_shll (low, low));
4859 emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
4863 (define_insn "ashldi3_media"
4864 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4865 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4866 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4871 [(set_attr "type" "arith_media")])
4873 (define_insn "*ashldisi3_media"
4874 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4875 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4876 (match_operand:DI 2 "const_int_operand" "n")))]
4877 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4878 "shlli.l %1, %2, %0"
4879 [(set_attr "type" "arith_media")
4880 (set_attr "highpart" "ignore")])
4882 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4883 ;; SImode arithmetic shift right
4885 ;; We can't do HImode right shifts correctly unless we start out with an
4886 ;; explicit zero / sign extension; doing that would result in worse overall
4887 ;; code, so just let the machine independent code widen the mode.
4888 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
4890 (define_expand "ashrsi3"
4891 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4892 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4893 (match_operand:SI 2 "nonmemory_operand" "")))
4894 (clobber (reg:SI T_REG))])]
4899 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4902 if (expand_ashiftrt (operands))
4909 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4910 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4913 (and:SI (match_dup 1) (const_int 1)))]
4916 [(set_attr "type" "arith")])
4918 (define_insn "ashrsi3_k"
4919 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4920 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4921 (match_operand:SI 2 "const_int_operand" "M")))
4922 (clobber (reg:SI T_REG))]
4923 "TARGET_SH1 && INTVAL (operands[2]) == 1"
4925 [(set_attr "type" "arith")])
4927 (define_insn_and_split "ashrsi2_16"
4928 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4929 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
4934 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
4935 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
4937 operands[2] = gen_lowpart (HImode, operands[0]);
4940 (define_insn_and_split "ashrsi2_31"
4941 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4942 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4944 (clobber (reg:SI T_REG))]
4950 emit_insn (gen_shll (operands[0], operands[1]));
4951 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
4955 (define_insn "ashrsi3_d"
4956 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4957 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4958 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4961 [(set_attr "type" "dyn_shift")])
4963 (define_insn "ashrsi3_n"
4964 [(set (reg:SI R4_REG)
4965 (ashiftrt:SI (reg:SI R4_REG)
4966 (match_operand:SI 0 "const_int_operand" "i")))
4967 (clobber (reg:SI T_REG))
4968 (clobber (reg:SI PR_REG))
4969 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
4972 [(set_attr "type" "sfunc")
4973 (set_attr "needs_delay_slot" "yes")])
4975 (define_insn "ashrsi3_media"
4976 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4977 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4978 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4983 [(set_attr "type" "arith_media")
4984 (set_attr "highpart" "ignore")])
4986 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4987 ;; DImode arithmetic shift right
4989 (define_expand "ashrdi3"
4990 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4991 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4992 (match_operand:DI 2 "immediate_operand" "")))
4993 (clobber (reg:SI T_REG))])]
4998 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
5001 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5005 (define_insn_and_split "ashrdi3_k"
5006 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5007 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5009 (clobber (reg:SI T_REG))]
5012 "&& reload_completed"
5015 rtx high = gen_highpart (SImode, operands[0]);
5016 rtx low = gen_lowpart (SImode, operands[0]);
5017 emit_insn (gen_shar (high, high));
5018 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5022 (define_insn "ashrdi3_media"
5023 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5024 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5025 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5027 && (arith_reg_dest (operands[0], DImode)
5028 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
5032 [(set_attr "type" "arith_media")])
5034 (define_insn "*ashrdisi3_media"
5035 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5036 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5037 (match_operand:DI 2 "const_int_operand" "n")))]
5038 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5039 "shari.l %1, %2, %0"
5040 [(set_attr "type" "arith_media")
5041 (set_attr "highpart" "ignore")])
5043 (define_insn "ashrdisi3_media_high"
5044 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5046 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5047 (match_operand:DI 2 "const_int_operand" "n"))))]
5048 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
5050 [(set_attr "type" "arith_media")])
5052 (define_insn "ashrdisi3_media_opaque"
5053 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5054 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
5055 (match_operand:DI 2 "const_int_operand" "n")]
5059 [(set_attr "type" "arith_media")])
5061 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5062 ;; SImode logical shift right
5064 (define_expand "lshrsi3"
5065 [(set (match_operand:SI 0 "arith_reg_dest" "")
5066 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
5067 (match_operand:SI 2 "shift_count_operand" "")))]
5072 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
5076 /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
5077 here, otherwise the pattern will never match due to the shift amount reg
5080 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
5082 rtx neg_count = force_reg (SImode,
5083 gen_int_mode (- INTVAL (operands[2]), SImode));
5084 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5088 if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
5090 rtx neg_count = gen_reg_rtx (SImode);
5091 emit_insn (gen_negsi2 (neg_count, operands[2]));
5092 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
5096 /* If the lshrsi3_* insn is going to clobber the T_REG it must be
5098 if (CONST_INT_P (operands[2])
5099 && sh_lshrsi_clobbers_t_reg_p (operands[2])
5100 && ! sh_dynamicalize_shift_p (operands[2]))
5102 emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
5107 /* Expand a library call for the dynamic shift. */
5108 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
5110 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
5111 rtx funcaddr = gen_reg_rtx (Pmode);
5112 function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
5113 emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
5118 (define_insn "lshrsi3_k"
5119 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5120 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5121 (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
5124 [(set_attr "type" "arith")])
5126 (define_insn_and_split "lshrsi3_d"
5127 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5128 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5129 (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
5132 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
5133 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5136 if (satisfies_constraint_P27 (operands[2]))
5138 /* This will not be done for a shift amount of 1, because it would
5139 clobber the T_REG. */
5140 emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
5143 else if (! satisfies_constraint_P27 (operands[2]))
5145 /* This must happen before reload, otherwise the constant will be moved
5146 into a register due to the "r" constraint, after which this split
5147 cannot be done anymore.
5148 Unfortunately the move insn will not always be eliminated.
5149 Also, here we must not create a shift sequence that clobbers the
5151 emit_move_insn (operands[0], operands[1]);
5152 gen_shifty_op (LSHIFTRT, operands);
5158 [(set_attr "type" "dyn_shift")])
5160 ;; If dynamic shifts are not available use a library function.
5161 ;; By specifying the pattern we reduce the number of call clobbered regs.
5162 ;; In order to make combine understand the truncation of the shift amount
5163 ;; operand we have to allow it to use pseudo regs for the shift operands.
5164 (define_insn "lshrsi3_d_call"
5165 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
5166 (lshiftrt:SI (reg:SI R4_REG)
5167 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
5169 (use (match_operand:SI 2 "arith_reg_operand" "r"))
5170 (clobber (reg:SI T_REG))
5171 (clobber (reg:SI PR_REG))]
5172 "TARGET_SH1 && !TARGET_DYNSHIFT"
5174 [(set_attr "type" "sfunc")
5175 (set_attr "needs_delay_slot" "yes")])
5177 (define_insn_and_split "lshrsi3_n"
5178 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5179 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5180 (match_operand:SI 2 "not_p27_rshift_count_operand")))]
5181 "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
5183 "&& (reload_completed
5184 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5187 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5189 /* If this pattern was picked and dynamic shifts are supported, switch
5190 to dynamic shift pattern before reload. */
5191 operands[2] = force_reg (SImode,
5192 gen_int_mode (- INTVAL (operands[2]), SImode));
5193 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5196 gen_shifty_op (LSHIFTRT, operands);
5201 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
5202 ;; the shlr pattern.
5203 (define_insn_and_split "lshrsi3_n_clobbers_t"
5204 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5205 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5206 (match_operand:SI 2 "not_p27_rshift_count_operand")))
5207 (clobber (reg:SI T_REG))]
5208 "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
5210 "&& (reload_completed || INTVAL (operands[2]) == 31
5211 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
5214 if (INTVAL (operands[2]) == 31)
5216 emit_insn (gen_shll (operands[0], operands[1]));
5217 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
5219 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
5221 /* If this pattern was picked and dynamic shifts are supported, switch
5222 to dynamic shift pattern before reload. */
5223 operands[2] = force_reg (SImode,
5224 gen_int_mode (- INTVAL (operands[2]), SImode));
5225 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
5228 gen_shifty_op (LSHIFTRT, operands);
5234 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5235 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5238 (and:SI (match_dup 1) (const_int 1)))]
5241 [(set_attr "type" "arith")])
5243 (define_insn "lshrsi3_media"
5244 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5245 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
5246 (match_operand:SI 2 "shift_count_operand" "r,n")))]
5251 [(set_attr "type" "arith_media")
5252 (set_attr "highpart" "ignore")])
5254 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5255 ;; DImode logical shift right
5257 (define_expand "lshrdi3"
5258 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
5259 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
5260 (match_operand:DI 2 "immediate_operand" "")))
5261 (clobber (reg:SI T_REG))])]
5266 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
5269 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
5273 (define_insn_and_split "lshrdi3_k"
5274 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5275 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
5277 (clobber (reg:SI T_REG))]
5280 "&& reload_completed"
5283 rtx high = gen_highpart (SImode, operands[0]);
5284 rtx low = gen_lowpart (SImode, operands[0]);
5285 emit_insn (gen_shlr (high, high));
5286 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
5290 (define_insn "lshrdi3_media"
5291 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5292 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
5293 (match_operand:DI 2 "shift_count_operand" "r,n")))]
5295 && (arith_reg_dest (operands[0], DImode)
5296 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
5300 [(set_attr "type" "arith_media")])
5302 (define_insn "*lshrdisi3_media"
5303 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
5304 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
5305 (match_operand:DI 2 "const_int_operand" "n")))]
5306 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
5307 "shlri.l %1, %2, %0"
5308 [(set_attr "type" "arith_media")
5309 (set_attr "highpart" "ignore")])
5311 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5312 ;; Combined left/right shifts
5315 [(set (match_operand:SI 0 "register_operand" "")
5316 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5317 (match_operand:SI 2 "const_int_operand" ""))
5318 (match_operand:SI 3 "const_int_operand" "")))]
5319 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5320 [(use (reg:SI R0_REG))]
5322 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5328 [(set (match_operand:SI 0 "register_operand" "")
5329 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5330 (match_operand:SI 2 "const_int_operand" ""))
5331 (match_operand:SI 3 "const_int_operand" "")))
5332 (clobber (reg:SI T_REG))]
5333 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
5334 [(use (reg:SI R0_REG))]
5336 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
5342 [(set (match_operand:SI 0 "register_operand" "=r")
5343 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5344 (match_operand:SI 2 "const_int_operand" "n"))
5345 (match_operand:SI 3 "const_int_operand" "n")))
5346 (clobber (reg:SI T_REG))]
5347 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
5349 [(set (attr "length")
5350 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5352 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5354 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5356 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
5358 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
5360 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
5362 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
5363 (const_string "16")]
5364 (const_string "18")))
5365 (set_attr "type" "arith")])
5368 [(set (match_operand:SI 0 "register_operand" "=z")
5369 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
5370 (match_operand:SI 2 "const_int_operand" "n"))
5371 (match_operand:SI 3 "const_int_operand" "n")))
5372 (clobber (reg:SI T_REG))]
5373 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
5375 [(set (attr "length")
5376 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
5378 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
5380 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
5382 (const_string "10")))
5383 (set_attr "type" "arith")])
5385 ;; shift left / and combination with a scratch register: The combine pass
5386 ;; does not accept the individual instructions, even though they are
5387 ;; cheap. But it needs a precise description so that it is usable after
5389 (define_insn "and_shl_scratch"
5390 [(set (match_operand:SI 0 "register_operand" "=r,&r")
5394 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5395 (match_operand:SI 2 "const_int_operand" "N,n"))
5396 (match_operand:SI 3 "" "0,r"))
5397 (match_operand:SI 4 "const_int_operand" "n,n"))
5398 (match_operand:SI 5 "const_int_operand" "n,n")))
5399 (clobber (reg:SI T_REG))]
5402 [(set (attr "length")
5403 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5405 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5407 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5409 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5410 (const_string "10")]
5411 (const_string "12")))
5412 (set_attr "type" "arith")])
5415 [(set (match_operand:SI 0 "register_operand" "")
5419 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5420 (match_operand:SI 2 "const_int_operand" ""))
5421 (match_operand:SI 3 "register_operand" ""))
5422 (match_operand:SI 4 "const_int_operand" ""))
5423 (match_operand:SI 5 "const_int_operand" "")))
5424 (clobber (reg:SI T_REG))]
5426 [(use (reg:SI R0_REG))]
5428 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5430 if (INTVAL (operands[2]))
5432 gen_shifty_op (LSHIFTRT, operands);
5434 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5435 operands[2] = operands[4];
5436 gen_shifty_op (ASHIFT, operands);
5437 if (INTVAL (operands[5]))
5439 operands[2] = operands[5];
5440 gen_shifty_op (LSHIFTRT, operands);
5445 ;; signed left/right shift combination.
5447 [(set (match_operand:SI 0 "register_operand" "")
5449 (ashift:SI (match_operand:SI 1 "register_operand" "")
5450 (match_operand:SI 2 "const_int_operand" ""))
5451 (match_operand:SI 3 "const_int_operand" "")
5453 (clobber (reg:SI T_REG))]
5455 [(use (reg:SI R0_REG))]
5457 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5462 (define_insn "shl_sext_ext"
5463 [(set (match_operand:SI 0 "register_operand" "=r")
5465 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5466 (match_operand:SI 2 "const_int_operand" "n"))
5467 (match_operand:SI 3 "const_int_operand" "n")
5469 (clobber (reg:SI T_REG))]
5470 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5472 [(set (attr "length")
5473 (cond [(match_test "shl_sext_length (insn)")
5475 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5477 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5479 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5481 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5483 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5485 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5487 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5488 (const_string "16")]
5489 (const_string "18")))
5490 (set_attr "type" "arith")])
5492 (define_insn "shl_sext_sub"
5493 [(set (match_operand:SI 0 "register_operand" "=z")
5495 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5496 (match_operand:SI 2 "const_int_operand" "n"))
5497 (match_operand:SI 3 "const_int_operand" "n")
5499 (clobber (reg:SI T_REG))]
5500 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5502 [(set (attr "length")
5503 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5505 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5507 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5509 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5510 (const_string "12")]
5511 (const_string "14")))
5512 (set_attr "type" "arith")])
5514 ;; The xtrct_left and xtrct_right patterns are used in expansions of DImode
5515 ;; shifts by 16, and allow the xtrct instruction to be generated from C
5517 (define_insn "xtrct_left"
5518 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5519 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5521 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5525 [(set_attr "type" "arith")])
5527 (define_insn "xtrct_right"
5528 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5529 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5531 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5535 [(set_attr "type" "arith")])
5537 ;; -------------------------------------------------------------------------
5539 ;; -------------------------------------------------------------------------
5542 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5543 (neg:SI (plus:SI (reg:SI T_REG)
5544 (match_operand:SI 1 "arith_reg_operand" "r"))))
5546 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5550 [(set_attr "type" "arith")])
5552 ;; A simplified version of the negc insn, where the exact value of the
5553 ;; T bit doesn't matter. This is easier for combine to pick up.
5554 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5555 ;; extra patterns for this case.
5556 (define_insn "*negc"
5557 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5558 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5559 (match_operand:SI 2 "t_reg_operand" "")))
5560 (clobber (reg:SI T_REG))]
5563 [(set_attr "type" "arith")])
5565 (define_insn "*negdi_media"
5566 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5567 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5570 [(set_attr "type" "arith_media")])
5572 ;; Don't split into individual negc insns immediately so that neg:DI (abs:DI)
5574 (define_expand "negdi2"
5575 [(parallel [(set (match_operand:DI 0 "arith_reg_dest")
5576 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5577 (clobber (reg:SI T_REG))])]
5580 (define_insn_and_split "*negdi2"
5581 [(set (match_operand:DI 0 "arith_reg_dest")
5582 (neg:DI (match_operand:DI 1 "arith_reg_operand")))
5583 (clobber (reg:SI T_REG))]
5586 "&& can_create_pseudo_p ()"
5589 emit_insn (gen_clrt ());
5590 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5591 gen_lowpart (SImode, operands[1])));
5592 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5593 gen_highpart (SImode, operands[1])));
5597 (define_insn "negsi2"
5598 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5599 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5602 [(set_attr "type" "arith")])
5604 (define_insn_and_split "one_cmplsi2"
5605 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5606 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5609 "&& can_create_pseudo_p ()"
5610 [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
5611 (set (match_dup 0) (reg:SI T_REG))]
5614 If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
5617 (set (reg0) (not:SI (reg0) (reg1)))
5618 (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
5619 (clobber (reg:SI T_REG))])
5621 ... match and combine the sequence manually in the split pass after the
5622 combine pass. Notice that combine does try the target pattern of this
5623 split, but if the pattern is added it interferes with other patterns, in
5624 particular with the div0s comparisons.
5625 This could also be done with a peephole but doing it here before register
5626 allocation can save one temporary.
5627 When we're here, the not:SI pattern obviously has been matched already
5628 and we only have to see whether the following insn is the left shift. */
5630 rtx i = next_nonnote_insn_bb (curr_insn);
5631 if (i == NULL_RTX || !NONJUMP_INSN_P (i))
5634 rtx p = PATTERN (i);
5635 if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
5638 rtx p0 = XVECEXP (p, 0, 0);
5639 rtx p1 = XVECEXP (p, 0, 1);
5641 if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
5642 GET_CODE (p0) == SET
5643 && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
5644 && REG_P (XEXP (XEXP (p0, 1), 0))
5645 && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
5646 && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
5647 && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
5649 /* (clobber (reg:SI T_REG)) */
5650 && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
5651 && REGNO (XEXP (p1, 0)) == T_REG)
5653 operands[0] = XEXP (p0, 0);
5654 set_insn_deleted (i);
5659 [(set_attr "type" "arith")])
5661 (define_expand "one_cmpldi2"
5662 [(set (match_operand:DI 0 "arith_reg_dest" "")
5663 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
5665 "TARGET_SHMEDIA" "")
5667 (define_expand "abs<mode>2"
5668 [(parallel [(set (match_operand:SIDI 0 "arith_reg_dest")
5669 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5670 (clobber (reg:SI T_REG))])]
5673 (define_insn_and_split "*abs<mode>2"
5674 [(set (match_operand:SIDI 0 "arith_reg_dest")
5675 (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand")))
5676 (clobber (reg:SI T_REG))]
5679 "&& can_create_pseudo_p ()"
5682 if (<MODE>mode == SImode)
5683 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5686 rtx high_src = gen_highpart (SImode, operands[1]);
5687 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5690 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5695 (define_insn_and_split "*negabs<mode>2"
5696 [(set (match_operand:SIDI 0 "arith_reg_dest")
5697 (neg:SIDI (abs:SIDI (match_operand:SIDI 1 "arith_reg_operand"))))
5698 (clobber (reg:SI T_REG))]
5701 "&& can_create_pseudo_p ()"
5704 if (<MODE>mode == SImode)
5705 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5708 rtx high_src = gen_highpart (SImode, operands[1]);
5709 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5712 emit_insn (gen_neg<mode>_cond (operands[0], operands[1], operands[1],
5717 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
5718 ;; This can be used as some kind of conditional execution, which is useful
5720 ;; Actually the instruction scheduling should decide whether to use a
5721 ;; zero-offset branch or not for any generic case involving a single
5722 ;; instruction on SH4 202.
5723 (define_insn_and_split "negsi_cond"
5724 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5726 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand" "M,N"))
5727 (match_operand:SI 1 "arith_reg_operand" "0,0")
5728 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
5729 "TARGET_SH1 && TARGET_ZDCBRANCH"
5731 static const char* alt[] =
5741 return alt[which_alternative];
5743 "TARGET_SH1 && ! TARGET_ZDCBRANCH"
5746 rtx skip_neg_label = gen_label_rtx ();
5748 emit_move_insn (operands[0], operands[1]);
5750 emit_jump_insn (INTVAL (operands[3])
5751 ? gen_branch_true (skip_neg_label)
5752 : gen_branch_false (skip_neg_label));
5754 emit_label_after (skip_neg_label,
5755 emit_insn (gen_negsi2 (operands[0], operands[1])));
5758 [(set_attr "type" "arith") ;; poor approximation
5759 (set_attr "length" "4")])
5761 (define_insn_and_split "negdi_cond"
5762 [(set (match_operand:DI 0 "arith_reg_dest")
5764 (eq:SI (reg:SI T_REG) (match_operand:SI 3 "const_int_operand"))
5765 (match_operand:DI 1 "arith_reg_operand")
5766 (neg:DI (match_operand:DI 2 "arith_reg_operand"))))
5767 (clobber (reg:SI T_REG))]
5770 "&& can_create_pseudo_p ()"
5773 rtx skip_neg_label = gen_label_rtx ();
5775 emit_move_insn (operands[0], operands[1]);
5777 emit_jump_insn (INTVAL (operands[3])
5778 ? gen_branch_true (skip_neg_label)
5779 : gen_branch_false (skip_neg_label));
5781 if (!INTVAL (operands[3]))
5782 emit_insn (gen_clrt ());
5784 emit_insn (gen_negc (gen_lowpart (SImode, operands[0]),
5785 gen_lowpart (SImode, operands[1])));
5786 emit_label_after (skip_neg_label,
5787 emit_insn (gen_negc (gen_highpart (SImode, operands[0]),
5788 gen_highpart (SImode, operands[1]))));
5792 (define_expand "bswapsi2"
5793 [(set (match_operand:SI 0 "arith_reg_dest" "")
5794 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
5797 if (! can_create_pseudo_p ())
5801 rtx tmp0 = gen_reg_rtx (SImode);
5802 rtx tmp1 = gen_reg_rtx (SImode);
5804 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
5805 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
5806 emit_insn (gen_swapbsi2 (operands[0], tmp1));
5811 (define_insn "swapbsi2"
5812 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5813 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
5814 (const_int 4294901760))
5815 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5817 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5818 (const_int 255)))))]
5821 [(set_attr "type" "arith")])
5823 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
5824 ;; partial byte swap expressions such as...
5825 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
5826 ;; ...which are currently not handled by the tree optimizers.
5827 ;; The combine pass will not initially try to combine the full expression,
5828 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
5829 ;; pattern acts as an intermediate pattern that will eventually lead combine
5830 ;; to the swapbsi2 pattern above.
5831 ;; As a side effect this also improves code that does (x & 0xFF) << 8
5832 ;; or (x << 8) & 0xFF00.
5833 (define_insn_and_split "*swapbisi2_and_shl8"
5834 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5835 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5838 (match_operand:SI 2 "arith_reg_operand" "r")))]
5839 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5841 "&& can_create_pseudo_p ()"
5844 rtx tmp0 = gen_reg_rtx (SImode);
5845 rtx tmp1 = gen_reg_rtx (SImode);
5847 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
5848 emit_insn (gen_swapbsi2 (tmp1, tmp0));
5849 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
5853 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
5854 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
5855 (define_insn_and_split "*swapbhisi2"
5856 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5857 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5860 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
5861 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5863 "&& can_create_pseudo_p ()"
5866 rtx tmp = gen_reg_rtx (SImode);
5868 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
5869 emit_insn (gen_swapbsi2 (operands[0], tmp));
5873 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
5877 ;; which can be simplified to...
5880 [(set (match_operand:SI 0 "arith_reg_dest" "")
5881 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5882 (const_int 4294901760))
5883 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5885 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5887 (set (match_operand:SI 2 "arith_reg_dest" "")
5889 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
5891 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5892 (const_int 4294901760))
5893 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5895 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5896 (const_int 255)))))])
5898 ;; -------------------------------------------------------------------------
5899 ;; Zero extension instructions
5900 ;; -------------------------------------------------------------------------
5902 (define_insn "zero_extendsidi2"
5903 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5904 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
5906 "addz.l %1, r63, %0"
5907 [(set_attr "type" "arith_media")
5908 (set_attr "highpart" "extend")])
5910 (define_insn "zero_extendhidi2"
5911 [(set (match_operand:DI 0 "register_operand" "=r,r")
5912 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5917 [(set_attr "type" "*,load_media")
5918 (set (attr "highpart")
5919 (cond [(match_test "sh_contains_memref_p (insn)")
5920 (const_string "user")]
5921 (const_string "ignore")))])
5924 [(set (match_operand:DI 0 "register_operand" "")
5925 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5926 "TARGET_SHMEDIA && reload_completed"
5927 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5928 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
5930 if (GET_CODE (operands[1]) == TRUNCATE)
5931 operands[1] = XEXP (operands[1], 0);
5934 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
5935 ;; reload the entire truncate expression.
5936 (define_insn_and_split "*loaddi_trunc"
5937 [(set (match_operand 0 "any_register_operand" "=r")
5938 (truncate (match_operand:DI 1 "memory_operand" "m")))]
5939 "TARGET_SHMEDIA && reload_completed"
5941 "TARGET_SHMEDIA && reload_completed"
5942 [(set (match_dup 0) (match_dup 1))]
5944 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5947 (define_insn "zero_extendqidi2"
5948 [(set (match_operand:DI 0 "register_operand" "=r,r")
5949 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5954 [(set_attr "type" "arith_media,load_media")
5955 (set (attr "highpart")
5956 (cond [(match_test "sh_contains_memref_p (insn)")
5957 (const_string "user")]
5958 (const_string "ignore")))])
5960 (define_expand "zero_extend<mode>si2"
5961 [(set (match_operand:SI 0 "arith_reg_dest")
5962 (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
5964 (define_insn_and_split "*zero_extend<mode>si2_compact"
5965 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5966 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
5969 "&& can_create_pseudo_p ()"
5970 [(set (match_dup 0) (match_dup 2))]
5972 /* Sometimes combine fails to combine a T bit or negated T bit store to a
5973 reg with a following zero extension. In the split pass after combine,
5974 try to figure out how the extended reg was set. If it originated from
5975 the T bit we can replace the zero extension with a reg move, which will
5976 be eliminated. Notice that this also helps the *cbranch_t splitter when
5977 it tries to post-combine tests and conditional branches, as it does not
5978 check for zero extensions. */
5979 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
5980 if (operands[2] == NULL_RTX)
5983 [(set_attr "type" "arith")])
5985 (define_insn "*zero_extendhisi2_media"
5986 [(set (match_operand:SI 0 "register_operand" "=r,r")
5987 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5992 [(set_attr "type" "arith_media,load_media")
5993 (set (attr "highpart")
5994 (cond [(match_test "sh_contains_memref_p (insn)")
5995 (const_string "user")]
5996 (const_string "ignore")))])
5999 [(set (match_operand:SI 0 "register_operand" "")
6000 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6001 "TARGET_SHMEDIA && reload_completed"
6002 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6003 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
6005 rtx op1 = operands[1];
6007 if (GET_CODE (op1) == TRUNCATE)
6008 op1 = XEXP (op1, 0);
6010 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6011 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6014 (define_insn "*zero_extendqisi2_media"
6015 [(set (match_operand:SI 0 "register_operand" "=r,r")
6016 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6021 [(set_attr "type" "arith_media,load_media")
6022 (set (attr "highpart")
6023 (cond [(match_test "sh_contains_memref_p (insn)")
6024 (const_string "user")]
6025 (const_string "ignore")))])
6027 (define_insn "zero_extendqihi2"
6028 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6029 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6032 [(set_attr "type" "arith")])
6034 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
6035 ;; They could also be used for simple memory addresses like @Rn by setting
6036 ;; the displacement value to zero. However, doing so too early results in
6037 ;; missed opportunities for other optimizations such as post-inc or index
6038 ;; addressing loads.
6039 ;; Although the 'zero_extend_movu_operand' predicate does not allow simple
6040 ;; register addresses (an address without a displacement, index, post-inc),
6041 ;; zero-displacement addresses might be generated during reload, wich are
6042 ;; simplified to simple register addresses in turn. Thus, we have to
6043 ;; provide the Sdd and Sra alternatives in the patterns.
6044 (define_insn "*zero_extend<mode>si2_disp_mem"
6045 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
6047 (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
6051 movu.<bw> @(0,%t1),%0"
6052 [(set_attr "type" "load")
6053 (set_attr "length" "4")])
6055 ;; Convert the zero extending loads in sequences such as:
6056 ;; movu.b @(1,r5),r0 movu.w @(2,r5),r0
6057 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6059 ;; back to sign extending loads like:
6060 ;; mov.b @(1,r5),r0 mov.w @(2,r5),r0
6061 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
6063 ;; if the extension type is irrelevant. The sign extending mov.{b|w} insn
6064 ;; is only 2 bytes in size if the displacement is {K04|K05}.
6065 ;; If the displacement is greater it doesn't matter, so we convert anyways.
6067 [(set (match_operand:SI 0 "arith_reg_dest" "")
6068 (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
6069 (set (match_operand 2 "nonimmediate_operand" "")
6070 (match_operand 3 "arith_reg_operand" ""))]
6072 && REGNO (operands[0]) == REGNO (operands[3])
6073 && peep2_reg_dead_p (2, operands[0])
6074 && GET_MODE_SIZE (GET_MODE (operands[2]))
6075 <= GET_MODE_SIZE (GET_MODE (operands[1]))"
6076 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
6077 (set (match_dup 2) (match_dup 3))])
6079 ;; Fold sequences such as
6083 ;; movu.b @(0,r3),r7
6084 ;; This does not reduce the code size but the number of instructions is
6085 ;; halved, which results in faster code.
6087 [(set (match_operand:SI 0 "arith_reg_dest" "")
6088 (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
6089 (set (match_operand:SI 2 "arith_reg_dest" "")
6090 (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
6092 && GET_MODE (operands[1]) == GET_MODE (operands[3])
6093 && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
6094 && REGNO (operands[0]) == REGNO (operands[3])
6095 && (REGNO (operands[2]) == REGNO (operands[0])
6096 || peep2_reg_dead_p (2, operands[0]))"
6097 [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
6100 = replace_equiv_address (operands[1],
6101 gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
6105 ;; -------------------------------------------------------------------------
6106 ;; Sign extension instructions
6107 ;; -------------------------------------------------------------------------
6109 ;; ??? This should be a define expand.
6110 ;; ??? Or perhaps it should be dropped?
6112 ;; convert_move generates good code for SH[1-4].
6113 (define_insn "extendsidi2"
6114 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6115 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
6121 [(set_attr "type" "arith_media,load_media,fpconv_media")
6122 (set (attr "highpart")
6123 (cond [(match_test "sh_contains_memref_p (insn)")
6124 (const_string "user")]
6125 (const_string "extend")))])
6127 (define_insn "extendhidi2"
6128 [(set (match_operand:DI 0 "register_operand" "=r,r")
6129 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6134 [(set_attr "type" "*,load_media")
6135 (set (attr "highpart")
6136 (cond [(match_test "sh_contains_memref_p (insn)")
6137 (const_string "user")]
6138 (const_string "ignore")))])
6141 [(set (match_operand:DI 0 "register_operand" "")
6142 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
6143 "TARGET_SHMEDIA && reload_completed"
6144 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
6145 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6147 if (GET_CODE (operands[1]) == TRUNCATE)
6148 operands[1] = XEXP (operands[1], 0);
6151 (define_insn "extendqidi2"
6152 [(set (match_operand:DI 0 "register_operand" "=r,r")
6153 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6158 [(set_attr "type" "*,load_media")
6159 (set (attr "highpart")
6160 (cond [(match_test "sh_contains_memref_p (insn)")
6161 (const_string "user")]
6162 (const_string "ignore")))])
6165 [(set (match_operand:DI 0 "register_operand" "")
6166 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
6167 "TARGET_SHMEDIA && reload_completed"
6168 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
6169 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6171 if (GET_CODE (operands[1]) == TRUNCATE)
6172 operands[1] = XEXP (operands[1], 0);
6175 (define_expand "extend<mode>si2"
6176 [(set (match_operand:SI 0 "arith_reg_dest")
6177 (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
6179 (define_insn "*extendhisi2_media"
6180 [(set (match_operand:SI 0 "register_operand" "=r,r")
6181 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
6186 [(set_attr "type" "arith_media,load_media")
6187 (set (attr "highpart")
6188 (cond [(match_test "sh_contains_memref_p (insn)")
6189 (const_string "user")]
6190 (const_string "ignore")))])
6193 [(set (match_operand:SI 0 "register_operand" "")
6194 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
6195 "TARGET_SHMEDIA && reload_completed"
6196 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
6197 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
6199 rtx op1 = operands[1];
6200 if (GET_CODE (op1) == TRUNCATE)
6201 op1 = XEXP (op1, 0);
6203 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6204 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6207 (define_insn_and_split "*extend<mode>si2_compact_reg"
6208 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6209 (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
6212 "&& can_create_pseudo_p ()"
6213 [(set (match_dup 0) (match_dup 2))]
6215 /* Sometimes combine fails to combine a T bit or negated T bit store to a
6216 reg with a following sign extension. In the split pass after combine,
6217 try to figure the extended reg was set. If it originated from the T
6218 bit we can replace the sign extension with a reg move, which will be
6220 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
6221 if (operands[2] == NULL_RTX)
6224 [(set_attr "type" "arith")])
6226 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
6228 (define_insn "*extend<mode>si2_compact_mem_disp"
6229 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
6233 (match_operand:SI 1 "arith_reg_operand" "%r,r")
6234 (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
6235 "TARGET_SH1 && ! TARGET_SH2A
6236 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6238 mov.<bw> @(%O2,%1),%0
6240 [(set_attr "type" "load")])
6242 (define_insn "*extend<mode>si2_compact_mem_disp"
6243 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
6247 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6248 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
6249 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6251 mov.<bw> @(%O2,%1),%0
6253 mov.<bw> @(%O2,%1),%0"
6254 [(set_attr "type" "load")
6255 (set_attr "length" "2,2,4")])
6257 ;; The *_snd patterns will take care of other QImode/HImode addressing
6258 ;; modes than displacement addressing. They must be defined _after_ the
6259 ;; displacement addressing patterns. Otherwise the displacement addressing
6260 ;; patterns will not be picked.
6261 (define_insn "*extend<mode>si2_compact_snd"
6262 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6264 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
6267 [(set_attr "type" "load")])
6269 (define_insn "*extendqisi2_media"
6270 [(set (match_operand:SI 0 "register_operand" "=r,r")
6271 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
6276 [(set_attr "type" "arith_media,load_media")
6277 (set (attr "highpart")
6278 (cond [(match_test "sh_contains_memref_p (insn)")
6279 (const_string "user")]
6280 (const_string "ignore")))])
6283 [(set (match_operand:SI 0 "register_operand" "")
6284 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
6285 "TARGET_SHMEDIA && reload_completed"
6286 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
6287 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
6289 rtx op1 = operands[1];
6290 if (GET_CODE (op1) == TRUNCATE)
6291 op1 = XEXP (op1, 0);
6293 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
6294 subreg_lowpart_offset (SImode, GET_MODE (op1)));
6297 (define_expand "extendqihi2"
6298 [(set (match_operand:HI 0 "arith_reg_dest" "")
6299 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
6303 (define_insn "*extendqihi2_compact_reg"
6304 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
6305 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
6308 [(set_attr "type" "arith")])
6310 ;; It would seem useful to combine the truncXi patterns into the movXi
6311 ;; patterns, but unary operators are ignored when matching constraints,
6312 ;; so we need separate patterns.
6313 (define_insn "truncdisi2"
6314 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
6315 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
6324 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,
6325 fpconv_media,fmove_media")
6326 (set (attr "highpart")
6327 (cond [(match_test "sh_contains_memref_p (insn)")
6328 (const_string "user")]
6329 (const_string "extend")))])
6331 (define_insn "truncdihi2"
6332 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
6333 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
6336 static const char* alt[] =
6338 "shlli %1,48,%0" "\n"
6343 return alt[which_alternative];
6345 [(set_attr "type" "arith_media,store_media")
6346 (set_attr "length" "8,4")
6347 (set (attr "highpart")
6348 (cond [(match_test "sh_contains_memref_p (insn)")
6349 (const_string "user")]
6350 (const_string "extend")))])
6352 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
6353 ; Because we use zero extension, we can't provide signed QImode compares
6354 ; using a simple compare or conditional branch insn.
6355 (define_insn "truncdiqi2"
6356 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
6357 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
6362 [(set_attr "type" "arith_media,store")
6363 (set (attr "highpart")
6364 (cond [(match_test "sh_contains_memref_p (insn)")
6365 (const_string "user")]
6366 (const_string "extend")))])
6368 ;; -------------------------------------------------------------------------
6369 ;; Move instructions
6370 ;; -------------------------------------------------------------------------
6372 ;; define push and pop so it is easy for sh.c
6373 ;; We can't use push and pop on SHcompact because the stack must always
6374 ;; be 8-byte aligned.
6375 (define_expand "push"
6376 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6377 (match_operand:SI 0 "register_operand" "r,l,x"))]
6378 "TARGET_SH1 && ! TARGET_SH5"
6381 (define_expand "pop"
6382 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6383 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6384 "TARGET_SH1 && ! TARGET_SH5"
6387 (define_expand "push_e"
6388 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6389 (match_operand:SF 0 "" ""))
6390 (use (reg:PSI FPSCR_REG))
6391 (clobber (scratch:SI))])]
6392 "TARGET_SH1 && ! TARGET_SH5"
6395 (define_insn "push_fpul"
6396 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6397 "TARGET_SH2E && ! TARGET_SH5"
6399 [(set_attr "type" "fstore")
6400 (set_attr "late_fp_use" "yes")
6401 (set_attr "hit_stack" "yes")])
6403 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6405 (define_expand "push_4"
6406 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6407 (match_operand:DF 0 "" ""))
6408 (use (reg:PSI FPSCR_REG))
6409 (clobber (scratch:SI))])]
6410 "TARGET_SH1 && ! TARGET_SH5"
6413 (define_expand "pop_e"
6414 [(parallel [(set (match_operand:SF 0 "" "")
6415 (mem:SF (post_inc:SI (reg:SI SP_REG))))
6416 (use (reg:PSI FPSCR_REG))
6417 (clobber (scratch:SI))])]
6418 "TARGET_SH1 && ! TARGET_SH5"
6421 (define_insn "pop_fpul"
6422 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6423 "TARGET_SH2E && ! TARGET_SH5"
6425 [(set_attr "type" "load")
6426 (set_attr "hit_stack" "yes")])
6428 (define_expand "pop_4"
6429 [(parallel [(set (match_operand:DF 0 "" "")
6430 (mem:DF (post_inc:SI (reg:SI SP_REG))))
6431 (use (reg:PSI FPSCR_REG))
6432 (clobber (scratch:SI))])]
6433 "TARGET_SH1 && ! TARGET_SH5"
6436 (define_expand "push_fpscr"
6440 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
6441 gen_rtx_PRE_DEC (Pmode,
6442 stack_pointer_rtx)),
6444 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6448 (define_expand "pop_fpscr"
6452 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
6453 gen_frame_mem (PSImode,
6454 gen_rtx_POST_INC (Pmode,
6455 stack_pointer_rtx))));
6456 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6460 ;; The clrt and sett patterns can happen as the result of optimization and
6462 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6463 ;; In this case they might not disappear completely, because the T reg is
6464 ;; a fixed hard reg.
6465 ;; When DImode operations that use the T reg as carry/borrow are split into
6466 ;; individual SImode operations, the T reg is usually cleared before the
6467 ;; first SImode insn.
6469 [(set (reg:SI T_REG) (const_int 0))]
6472 [(set_attr "type" "mt_group")])
6475 [(set (reg:SI T_REG) (const_int 1))]
6478 [(set_attr "type" "mt_group")])
6480 ;; Use the combine pass to transform sequences such as
6484 ;; mov.l @(r0,r4),r0
6490 ;; See also PR 39423.
6491 ;; Notice that these patterns have a T_REG clobber, because the shift
6492 ;; sequence that will be split out might clobber the T_REG. Ideally, the
6493 ;; clobber would be added conditionally, depending on the result of
6494 ;; sh_ashlsi_clobbers_t_reg_p. When splitting out the shifts we must go
6495 ;; through the ashlsi3 expander in order to get the right shift insn --
6496 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6497 ;; FIXME: Combine never tries this kind of patterns for DImode.
6498 (define_insn_and_split "*movsi_index_disp_load"
6499 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6500 (match_operand:SI 1 "mem_index_disp_operand" "m"))
6501 (clobber (reg:SI T_REG))]
6504 "&& can_create_pseudo_p ()"
6505 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6506 (set (match_dup 0) (match_dup 7))]
6508 rtx mem = operands[1];
6509 rtx plus0_rtx = XEXP (mem, 0);
6510 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6511 rtx mult_rtx = XEXP (plus1_rtx, 0);
6513 operands[1] = XEXP (mult_rtx, 0);
6514 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6515 operands[3] = XEXP (plus1_rtx, 1);
6516 operands[4] = XEXP (plus0_rtx, 1);
6517 operands[5] = gen_reg_rtx (SImode);
6518 operands[6] = gen_reg_rtx (SImode);
6520 replace_equiv_address (mem,
6521 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6523 emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6526 (define_insn_and_split "*movhi_index_disp_load"
6527 [(set (match_operand:SI 0 "arith_reg_dest")
6528 (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6529 (clobber (reg:SI T_REG))]
6532 "&& can_create_pseudo_p ()"
6535 rtx mem = operands[1];
6536 rtx plus0_rtx = XEXP (mem, 0);
6537 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6538 rtx mult_rtx = XEXP (plus1_rtx, 0);
6540 rtx op_1 = XEXP (mult_rtx, 0);
6541 rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6542 rtx op_3 = XEXP (plus1_rtx, 1);
6543 rtx op_4 = XEXP (plus0_rtx, 1);
6544 rtx op_5 = gen_reg_rtx (SImode);
6545 rtx op_6 = gen_reg_rtx (SImode);
6546 rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6548 emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6549 emit_insn (gen_addsi3 (op_6, op_5, op_3));
6551 if (<CODE> == SIGN_EXTEND)
6553 emit_insn (gen_extendhisi2 (operands[0], op_7));
6556 else if (<CODE> == ZERO_EXTEND)
6558 /* On SH2A the movu.w insn can be used for zero extending loads. */
6560 emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
6563 emit_insn (gen_extendhisi2 (operands[0], op_7));
6564 emit_insn (gen_zero_extendhisi2 (operands[0],
6565 gen_lowpart (HImode, operands[0])));
6573 (define_insn_and_split "*mov<mode>_index_disp_store"
6574 [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
6575 (match_operand:HISI 1 "arith_reg_operand" "r"))
6576 (clobber (reg:SI T_REG))]
6579 "&& can_create_pseudo_p ()"
6580 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6581 (set (match_dup 7) (match_dup 1))]
6583 rtx mem = operands[0];
6584 rtx plus0_rtx = XEXP (mem, 0);
6585 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6586 rtx mult_rtx = XEXP (plus1_rtx, 0);
6588 operands[0] = XEXP (mult_rtx, 0);
6589 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6590 operands[3] = XEXP (plus1_rtx, 1);
6591 operands[4] = XEXP (plus0_rtx, 1);
6592 operands[5] = gen_reg_rtx (SImode);
6593 operands[6] = gen_reg_rtx (SImode);
6595 replace_equiv_address (mem,
6596 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6598 emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
6601 ;; t/r must come after r/r, lest reload will try to reload stuff like
6602 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
6603 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
6604 (define_insn "movsi_i"
6605 [(set (match_operand:SI 0 "general_movdst_operand"
6606 "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
6607 (match_operand:SI 1 "general_movsrc_operand"
6608 "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
6612 && (register_operand (operands[0], SImode)
6613 || register_operand (operands[1], SImode))"
6629 [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,
6630 pstore,gp_mac,prset,mem_mac,pload,pcload_si")
6631 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
6633 ;; t/r must come after r/r, lest reload will try to reload stuff like
6634 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
6635 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
6636 ;; will require a reload.
6637 ;; ??? We can't include f/f because we need the proper FPSCR setting when
6638 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
6639 (define_insn "movsi_ie"
6640 [(set (match_operand:SI 0 "general_movdst_operand"
6641 "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
6642 (match_operand:SI 1 "general_movsrc_operand"
6643 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
6644 "(TARGET_SH2E || TARGET_SH2A)
6645 && (register_operand (operands[0], SImode)
6646 || register_operand (operands[1], SImode))"
6671 ! move optimized away"
6672 [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,
6673 mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,
6674 pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
6675 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
6676 (set_attr_alternative "length"
6683 (match_test "TARGET_SH2A")
6684 (const_int 4) (const_int 2))
6688 (match_test "TARGET_SH2A")
6689 (const_int 4) (const_int 2))
6706 (define_insn "movsi_i_lowpart"
6707 [(set (strict_low_part
6708 (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
6709 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
6711 && (register_operand (operands[0], SImode)
6712 || register_operand (operands[1], SImode))"
6722 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
6724 (define_insn_and_split "load_ra"
6725 [(set (match_operand:SI 0 "general_movdst_operand" "")
6726 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
6729 "&& ! currently_expanding_to_rtl"
6730 [(set (match_dup 0) (match_dup 1))]
6732 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
6733 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
6736 ;; The '?'s in the following constraints may not reflect the time taken
6737 ;; to perform the move. They are there to discourage the use of floating-
6738 ;; point registers for storing integer values.
6739 (define_insn "*movsi_media"
6740 [(set (match_operand:SI 0 "general_movdst_operand"
6741 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
6742 (match_operand:SI 1 "general_movsrc_operand"
6743 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6745 && (register_operand (operands[0], SImode)
6746 || sh_register_operand (operands[1], SImode)
6747 || GET_CODE (operands[1]) == TRUNCATE)"
6762 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6763 fload_media,fstore_media,fload_media,fpconv_media,
6764 fmove_media,ptabs_media,gettr_media,pt_media")
6765 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
6766 (set (attr "highpart")
6767 (cond [(match_test "sh_contains_memref_p (insn)")
6768 (const_string "user")]
6769 (const_string "ignore")))])
6771 (define_insn "*movsi_media_nofpu"
6772 [(set (match_operand:SI 0 "general_movdst_operand"
6773 "=r,r,r,r,m,*b,r,*b")
6774 (match_operand:SI 1 "general_movsrc_operand"
6775 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
6777 && (register_operand (operands[0], SImode)
6778 || sh_register_operand (operands[1], SImode)
6779 || GET_CODE (operands[1]) == TRUNCATE)"
6789 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
6790 ptabs_media,gettr_media,pt_media")
6791 (set_attr "length" "4,4,8,4,4,4,4,12")
6792 (set (attr "highpart")
6793 (cond [(match_test "sh_contains_memref_p (insn)")
6794 (const_string "user")]
6795 (const_string "ignore")))])
6797 (define_expand "movsi_const"
6798 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6799 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6800 (const_int 16)] UNSPEC_EXTRACT_S16)))
6802 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
6803 (const:SI (unspec:SI [(match_dup 1)
6804 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6805 "TARGET_SHMEDIA && reload_completed
6806 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6808 if (GET_CODE (operands[1]) == LABEL_REF
6809 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
6810 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
6811 else if (GOTOFF_P (operands[1]))
6813 rtx unspec = XEXP (operands[1], 0);
6815 if (! UNSPEC_GOTOFF_P (unspec))
6817 unspec = XEXP (unspec, 0);
6818 if (! UNSPEC_GOTOFF_P (unspec))
6821 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
6822 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
6823 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
6827 (define_expand "movsi_const_16bit"
6828 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6829 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6830 (const_int 0)] UNSPEC_EXTRACT_S16)))]
6831 "TARGET_SHMEDIA && flag_pic && reload_completed
6832 && GET_CODE (operands[1]) == SYMBOL_REF"
6836 [(set (match_operand:SI 0 "arith_reg_dest" "")
6837 (match_operand:SI 1 "immediate_operand" ""))]
6838 "TARGET_SHMEDIA && reload_completed
6839 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6842 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
6844 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6850 [(set (match_operand:SI 0 "register_operand" "")
6851 (match_operand:SI 1 "immediate_operand" ""))]
6852 "TARGET_SHMEDIA && reload_completed
6853 && ((CONST_INT_P (operands[1])
6854 && ! satisfies_constraint_I16 (operands[1]))
6855 || GET_CODE (operands[1]) == CONST_DOUBLE)"
6856 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6858 (define_expand "movsi"
6859 [(set (match_operand:SI 0 "general_movdst_operand" "")
6860 (match_operand:SI 1 "general_movsrc_operand" ""))]
6863 prepare_move_operands (operands, SImode);
6866 (define_expand "ic_invalidate_line"
6867 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
6868 (match_dup 1)] UNSPEC_ICACHE)
6869 (clobber (scratch:SI))])]
6870 "TARGET_HARD_SH4 || TARGET_SH5"
6874 emit_insn (gen_ic_invalidate_line_media (operands[0]));
6877 else if (TARGET_SHCOMPACT)
6879 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
6880 operands[1] = force_reg (Pmode, operands[1]);
6881 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
6884 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
6886 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
6889 operands[0] = force_reg (Pmode, operands[0]);
6890 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
6894 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
6895 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
6896 ;; the requirement *1*00 for associative address writes. The alignment of
6897 ;; %0 implies that its least significant bit is cleared,
6898 ;; thus we clear the V bit of a matching entry if there is one.
6899 (define_insn "ic_invalidate_line_i"
6900 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
6901 (match_operand:SI 1 "register_operand" "r")]
6903 (clobber (match_scratch:SI 2 "=&r"))]
6906 return "ocbwb @%0" "\n"
6907 " extu.w %0,%2" "\n"
6911 [(set_attr "length" "8")
6912 (set_attr "type" "cwb")])
6914 (define_insn "ic_invalidate_line_sh4a"
6915 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6917 "TARGET_SH4A_ARCH || TARGET_SH4_300"
6919 return "ocbwb @%0" "\n"
6923 [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
6924 (set_attr "type" "cwb")])
6926 ;; ??? could make arg 0 an offsettable memory operand to allow to save
6927 ;; an add in the code that calculates the address.
6928 (define_insn "ic_invalidate_line_media"
6929 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
6933 return "ocbwb %0,0" "\n"
6938 [(set_attr "length" "16")
6939 (set_attr "type" "invalidate_line_media")])
6941 (define_insn "ic_invalidate_line_compact"
6942 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6943 (match_operand:SI 1 "register_operand" "r")]
6945 (clobber (reg:SI PR_REG))]
6948 [(set_attr "type" "sfunc")
6949 (set_attr "needs_delay_slot" "yes")])
6951 (define_expand "initialize_trampoline"
6952 [(match_operand:SI 0 "" "")
6953 (match_operand:SI 1 "" "")
6954 (match_operand:SI 2 "" "")]
6959 tramp = force_reg (Pmode, operands[0]);
6960 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
6962 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
6963 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
6965 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
6969 (define_insn "initialize_trampoline_compact"
6970 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6971 (match_operand:SI 1 "register_operand" "r")
6972 (reg:SI R2_REG) (reg:SI R3_REG)]
6975 (clobber (reg:SI PR_REG))]
6978 [(set_attr "type" "sfunc")
6979 (set_attr "needs_delay_slot" "yes")])
6981 (define_expand "movhi"
6982 [(set (match_operand:HI 0 "general_movdst_operand" "")
6983 (match_operand:HI 1 "general_movsrc_operand" ""))]
6986 prepare_move_operands (operands, HImode);
6989 (define_expand "movqi"
6990 [(set (match_operand:QI 0 "general_operand" "")
6991 (match_operand:QI 1 "general_operand" ""))]
6994 prepare_move_operands (operands, QImode);
6997 ;; Specifying the displacement addressing load / store patterns separately
6998 ;; before the generic movqi / movhi pattern allows controlling the order
6999 ;; in which load / store insns are selected in a more fine grained way.
7000 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
7001 ;; "enabled" attribute as it is done in other targets.
7002 (define_insn "*mov<mode>_store_mem_disp04"
7004 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
7005 (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
7006 (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
7007 "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
7009 mov.<bw> %2,@(%O1,%0)
7011 [(set_attr "type" "store")])
7013 (define_insn "*mov<mode>_store_mem_disp12"
7015 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
7016 (match_operand:SI 1 "const_int_operand" "<disp12>")))
7017 (match_operand:QIHI 2 "arith_reg_operand" "r"))]
7018 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
7019 "mov.<bw> %2,@(%O1,%0)"
7020 [(set_attr "type" "store")
7021 (set_attr "length" "4")])
7023 (define_insn "*mov<mode>_load_mem_disp04"
7024 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
7026 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
7027 (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
7028 "TARGET_SH1 && ! TARGET_SH2A
7029 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
7031 mov.<bw> @(%O2,%1),%0
7033 [(set_attr "type" "load")])
7035 (define_insn "*mov<mode>_load_mem_disp12"
7036 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
7039 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
7040 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
7041 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
7043 mov.<bw> @(%O2,%1),%0
7045 mov.<bw> @(%O2,%1),%0"
7046 [(set_attr "type" "load")
7047 (set_attr "length" "2,2,4")])
7049 ;; The order of the constraint alternatives is important here.
7050 ;; Q/r has to come first, otherwise PC relative loads might wrongly get
7051 ;; placed into delay slots. Since there is no QImode PC relative load, the
7052 ;; Q constraint and general_movsrc_operand will reject it for QImode.
7053 ;; The Snd alternatives should come before Sdd in order to avoid a preference
7054 ;; of using r0 als the register operand for addressing modes other than
7055 ;; displacement addressing.
7056 ;; The Sdd alternatives allow only r0 as register operand, even though on
7057 ;; SH2A any register could be allowed by switching to a 32 bit insn.
7058 ;; Generally sticking to the r0 is preferrable, since it generates smaller
7059 ;; code. Obvious r0 reloads can then be eliminated with a peephole on SH2A.
7060 (define_insn "*mov<mode>"
7061 [(set (match_operand:QIHI 0 "general_movdst_operand"
7062 "=r,r,r,Snd,r, Sdd,z, r,l")
7063 (match_operand:QIHI 1 "general_movsrc_operand"
7064 "Q,r,i,r, Snd,z, Sdd,l,r"))]
7066 && (arith_reg_operand (operands[0], <MODE>mode)
7067 || arith_reg_operand (operands[1], <MODE>mode))"
7078 [(set_attr "type" "pcload,move,movi8,store,load,store,load,prget,prset")
7079 (set (attr "length")
7080 (cond [(and (match_operand 0 "displacement_mem_operand")
7081 (not (match_operand 0 "short_displacement_mem_operand")))
7083 (and (match_operand 1 "displacement_mem_operand")
7084 (not (match_operand 1 "short_displacement_mem_operand")))
7088 (define_insn "*movqi_media"
7089 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
7090 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
7092 && (arith_reg_operand (operands[0], QImode)
7093 || extend_reg_or_0_operand (operands[1], QImode))"
7099 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
7100 (set (attr "highpart")
7101 (cond [(match_test "sh_contains_memref_p (insn)")
7102 (const_string "user")]
7103 (const_string "ignore")))])
7105 (define_expand "reload_inqi"
7106 [(set (match_operand:SI 2 "" "=&r")
7107 (match_operand:QI 1 "inqhi_operand" ""))
7108 (set (match_operand:QI 0 "arith_reg_operand" "=r")
7109 (truncate:QI (match_dup 3)))]
7112 rtx inner = XEXP (operands[1], 0);
7113 int regno = REGNO (inner);
7115 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7116 operands[1] = gen_rtx_REG (SImode, regno);
7117 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7120 (define_insn "*movhi_media"
7121 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
7122 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
7124 && (arith_reg_operand (operands[0], HImode)
7125 || arith_reg_or_0_operand (operands[1], HImode))"
7132 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
7133 (set (attr "highpart")
7134 (cond [(match_test "sh_contains_memref_p (insn)")
7135 (const_string "user")]
7136 (const_string "ignore")))])
7139 [(set (match_operand:HI 0 "register_operand" "")
7140 (match_operand:HI 1 "immediate_operand" ""))]
7141 "TARGET_SHMEDIA && reload_completed
7142 && ! satisfies_constraint_I16 (operands[1])"
7143 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
7145 (define_expand "reload_inhi"
7146 [(set (match_operand:SI 2 "" "=&r")
7147 (match_operand:HI 1 "inqhi_operand" ""))
7148 (set (match_operand:HI 0 "arith_reg_operand" "=r")
7149 (truncate:HI (match_dup 3)))]
7152 rtx inner = XEXP (operands[1], 0);
7153 int regno = REGNO (inner);
7155 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
7156 operands[1] = gen_rtx_REG (SImode, regno);
7157 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
7160 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
7161 ;; compiled with -m2 -ml -O3 -funroll-loops
7162 (define_insn "*movdi_i"
7163 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
7164 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
7166 && (arith_reg_operand (operands[0], DImode)
7167 || arith_reg_operand (operands[1], DImode))"
7169 return output_movedouble (insn, operands, DImode);
7171 [(set_attr "length" "4")
7172 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
7174 ;; If the output is a register and the input is memory or a register, we have
7175 ;; to be careful and see which word needs to be loaded first.
7177 [(set (match_operand:DI 0 "general_movdst_operand" "")
7178 (match_operand:DI 1 "general_movsrc_operand" ""))]
7179 "TARGET_SH1 && reload_completed"
7180 [(set (match_dup 2) (match_dup 3))
7181 (set (match_dup 4) (match_dup 5))]
7185 if ((MEM_P (operands[0])
7186 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7187 || (MEM_P (operands[1])
7188 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7191 switch (GET_CODE (operands[0]))
7194 regno = REGNO (operands[0]);
7197 regno = subreg_regno (operands[0]);
7207 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7209 operands[2] = operand_subword (operands[0], 0, 0, DImode);
7210 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7211 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7212 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7216 operands[2] = operand_subword (operands[0], 1, 0, DImode);
7217 operands[3] = operand_subword (operands[1], 1, 0, DImode);
7218 operands[4] = operand_subword (operands[0], 0, 0, DImode);
7219 operands[5] = operand_subword (operands[1], 0, 0, DImode);
7222 if (operands[2] == 0 || operands[3] == 0
7223 || operands[4] == 0 || operands[5] == 0)
7227 ;; The '?'s in the following constraints may not reflect the time taken
7228 ;; to perform the move. They are there to discourage the use of floating-
7229 ;; point registers for storing integer values.
7230 (define_insn "*movdi_media"
7231 [(set (match_operand:DI 0 "general_movdst_operand"
7232 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
7233 (match_operand:DI 1 "general_movsrc_operand"
7234 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
7236 && (register_operand (operands[0], DImode)
7237 || sh_register_operand (operands[1], DImode))"
7252 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7253 fload_media,fstore_media,fload_media,dfpconv_media,
7254 fmove_media,ptabs_media,gettr_media,pt_media")
7255 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
7257 (define_insn "*movdi_media_nofpu"
7258 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
7259 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
7261 && (register_operand (operands[0], DImode)
7262 || sh_register_operand (operands[1], DImode))"
7272 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,
7273 ptabs_media,gettr_media,pt_media")
7274 (set_attr "length" "4,4,16,4,4,4,4,*")])
7276 (define_insn "*movdi_media_I16"
7277 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
7278 (match_operand:DI 1 "const_int_operand" "I16"))]
7279 "TARGET_SHMEDIA && reload_completed"
7281 [(set_attr "type" "arith_media")
7282 (set_attr "length" "4")])
7285 [(set (match_operand:DI 0 "arith_reg_dest" "")
7286 (match_operand:DI 1 "immediate_operand" ""))]
7287 "TARGET_SHMEDIA && reload_completed
7288 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7289 [(set (match_dup 0) (match_dup 1))]
7293 if (TARGET_SHMEDIA64)
7294 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
7296 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
7298 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
7303 (define_expand "movdi_const"
7304 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7305 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7306 (const_int 48)] UNSPEC_EXTRACT_S16)))
7308 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7309 (const:DI (unspec:DI [(match_dup 1)
7310 (const_int 32)] UNSPEC_EXTRACT_U16))))
7312 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7313 (const:DI (unspec:DI [(match_dup 1)
7314 (const_int 16)] UNSPEC_EXTRACT_U16))))
7316 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7317 (const:DI (unspec:DI [(match_dup 1)
7318 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7319 "TARGET_SHMEDIA64 && reload_completed
7320 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7322 sh_mark_label (operands[1], 4);
7325 (define_expand "movdi_const_32bit"
7326 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7327 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7328 (const_int 16)] UNSPEC_EXTRACT_S16)))
7330 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
7331 (const:DI (unspec:DI [(match_dup 1)
7332 (const_int 0)] UNSPEC_EXTRACT_U16))))]
7333 "TARGET_SHMEDIA32 && reload_completed
7334 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
7336 sh_mark_label (operands[1], 2);
7339 (define_expand "movdi_const_16bit"
7340 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7341 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
7342 (const_int 0)] UNSPEC_EXTRACT_S16)))]
7343 "TARGET_SHMEDIA && flag_pic && reload_completed
7344 && GET_CODE (operands[1]) == SYMBOL_REF"
7348 [(set (match_operand:DI 0 "ext_dest_operand" "")
7349 (match_operand:DI 1 "immediate_operand" ""))]
7350 "TARGET_SHMEDIA && reload_completed
7351 && CONST_INT_P (operands[1])
7352 && ! satisfies_constraint_I16 (operands[1])"
7353 [(set (match_dup 0) (match_dup 2))
7356 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
7357 unsigned HOST_WIDE_INT low = val;
7358 unsigned HOST_WIDE_INT high = val;
7359 unsigned HOST_WIDE_INT sign;
7360 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7362 /* Zero-extend the 16 least-significant bits. */
7365 /* Arithmetic shift right the word by 16 bits. */
7367 if (GET_CODE (operands[0]) == SUBREG
7368 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7377 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7383 /* If we can't generate the constant with a two-insn movi / shori
7384 sequence, try some other strategies. */
7385 if (! CONST_OK_FOR_I16 (high))
7387 /* Try constant load / left shift. We know VAL != 0. */
7388 val2 = val ^ (val-1);
7391 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7393 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7394 || (! CONST_OK_FOR_I16 (high >> 16)
7395 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7397 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7398 operands[1] = gen_ashldi3_media (operands[0], operands[0],
7399 GEN_INT (trailing_zeroes));
7403 /* Try constant load / right shift. */
7404 val2 = (val >> 15) + 1;
7405 if (val2 == (val2 & -val2))
7407 int shift = 49 - exact_log2 (val2);
7409 val2 = trunc_int_for_mode (val << shift, DImode);
7410 if (CONST_OK_FOR_I16 (val2))
7412 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7418 val2 = val & 0xffff;
7419 if ((val >> 16 & 0xffff) == val2
7420 && (val >> 32 & 0xffff) == val2
7421 && (val >> 48 & 0xffff) == val2)
7423 val2 = (HOST_WIDE_INT) val >> 48;
7424 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7425 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7428 /* Try movi / mshflo.l */
7429 val2 = (HOST_WIDE_INT) val >> 32;
7430 if (val2 == ((unsigned HOST_WIDE_INT)
7431 trunc_int_for_mode (val, SImode)))
7433 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7437 /* Try movi / mshflo.l w/ r63. */
7438 val2 = val + ((HOST_WIDE_INT) -1 << 32);
7439 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7441 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7447 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7450 operands[2] = GEN_INT (val2);
7454 [(set (match_operand:DI 0 "ext_dest_operand" "")
7455 (match_operand:DI 1 "immediate_operand" ""))]
7456 "TARGET_SHMEDIA && reload_completed
7457 && GET_CODE (operands[1]) == CONST_DOUBLE"
7458 [(set (match_dup 0) (match_dup 2))
7460 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7462 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7463 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7464 unsigned HOST_WIDE_INT val = low;
7465 unsigned HOST_WIDE_INT sign;
7467 /* Zero-extend the 16 least-significant bits. */
7469 operands[1] = GEN_INT (val);
7471 /* Arithmetic shift right the double-word by 16 bits. */
7473 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7476 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7480 /* This will only be true if high is a sign-extension of low, i.e.,
7481 it must be either 0 or (unsigned)-1, and be zero iff the
7482 most-significant bit of low is set. */
7483 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7484 operands[2] = GEN_INT (low);
7486 operands[2] = immed_double_const (low, high, DImode);
7489 (define_insn "shori_media"
7490 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7491 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7493 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7494 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7498 [(set_attr "type" "arith_media,*")])
7500 (define_insn "*shori_media_si"
7501 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7502 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7504 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7508 (define_expand "movdi"
7509 [(set (match_operand:DI 0 "general_movdst_operand" "")
7510 (match_operand:DI 1 "general_movsrc_operand" ""))]
7513 prepare_move_operands (operands, DImode);
7516 (define_insn "movdf_media"
7517 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7518 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7520 && (register_operand (operands[0], DFmode)
7521 || sh_register_operand (operands[1], DFmode))"
7532 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,
7533 fload_media,fstore_media,load_media,store_media")])
7535 (define_insn "movdf_media_nofpu"
7536 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7537 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7539 && (register_operand (operands[0], DFmode)
7540 || sh_register_operand (operands[1], DFmode))"
7546 [(set_attr "type" "arith_media,*,load_media,store_media")])
7549 [(set (match_operand:DF 0 "arith_reg_dest" "")
7550 (match_operand:DF 1 "immediate_operand" ""))]
7551 "TARGET_SHMEDIA && reload_completed"
7552 [(set (match_dup 3) (match_dup 2))]
7554 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7556 REAL_VALUE_TYPE value;
7558 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7559 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7561 if (HOST_BITS_PER_WIDE_INT >= 64)
7562 operands[2] = immed_double_const ((unsigned long) values[endian]
7563 | ((HOST_WIDE_INT) values[1 - endian]
7567 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7568 operands[2] = immed_double_const (values[endian], values[1 - endian],
7572 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7575 ;; FIXME: This should be a define_insn_and_split.
7576 (define_insn "movdf_k"
7577 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7578 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7580 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7581 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7582 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7583 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7584 && (arith_reg_operand (operands[0], DFmode)
7585 || arith_reg_operand (operands[1], DFmode))"
7587 return output_movedouble (insn, operands, DFmode);
7589 [(set_attr "length" "4")
7590 (set_attr "type" "move,pcload,load,store")])
7592 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7593 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7594 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7595 ;; the d/m/c/X alternative, which is split later into single-precision
7596 ;; instructions. And when not optimizing, no splits are done before fixing
7597 ;; up pcloads, so we need usable length information for that.
7598 (define_insn "movdf_i4"
7599 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7600 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
7601 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
7602 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
7603 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7604 && (arith_reg_operand (operands[0], DFmode)
7605 || arith_reg_operand (operands[1], DFmode))"
7607 switch (which_alternative)
7611 return "fmov %1,%0";
7612 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7613 return "fmov %R1,%R0" "\n"
7616 return "fmov %S1,%S0" "\n"
7620 return "fmov.d %1,%0";
7625 [(set_attr_alternative "length"
7626 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7628 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7629 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7630 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7632 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7633 ;; We can't use 4-byte push/pop on SHcompact, so we have to
7634 ;; increment or decrement r15 explicitly.
7636 (match_test "TARGET_SHCOMPACT")
7637 (const_int 10) (const_int 8))
7639 (match_test "TARGET_SHCOMPACT")
7640 (const_int 10) (const_int 8))])
7641 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7642 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7643 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7644 (const_string "double")
7645 (const_string "none")))])
7647 ;; Moving DFmode between fp/general registers through memory
7648 ;; (the top of the stack) is faster than moving through fpul even for
7649 ;; little endian. Because the type of an instruction is important for its
7650 ;; scheduling, it is beneficial to split these operations, rather than
7651 ;; emitting them in one single chunk, even if this will expose a stack
7652 ;; use that will prevent scheduling of other stack accesses beyond this
7655 [(set (match_operand:DF 0 "register_operand" "")
7656 (match_operand:DF 1 "register_operand" ""))
7657 (use (match_operand:PSI 2 "fpscr_operand" ""))
7658 (clobber (match_scratch:SI 3 "=X"))]
7659 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7660 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7665 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7667 emit_move_insn (stack_pointer_rtx,
7668 plus_constant (Pmode, stack_pointer_rtx, -8));
7669 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7672 tos = gen_tmp_stack_mem (DFmode,
7673 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7674 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
7675 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7676 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7677 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7678 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7680 tos = gen_tmp_stack_mem (DFmode,
7681 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7682 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
7683 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7684 emit_move_insn (stack_pointer_rtx,
7685 plus_constant (Pmode, stack_pointer_rtx, 8));
7687 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7691 ;; local-alloc sometimes allocates scratch registers even when not required,
7692 ;; so we must be prepared to handle these.
7694 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7696 [(set (match_operand:DF 0 "general_movdst_operand" "")
7697 (match_operand:DF 1 "general_movsrc_operand" ""))
7698 (use (match_operand:PSI 2 "fpscr_operand" ""))
7699 (clobber (match_scratch:SI 3 ""))]
7700 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7702 && true_regnum (operands[0]) < 16
7703 && true_regnum (operands[1]) < 16"
7704 [(set (match_dup 0) (match_dup 1))]
7706 /* If this was a reg <-> mem operation with base + index reg addressing,
7707 we have to handle this in a special way. */
7708 rtx mem = operands[0];
7710 if (! memory_operand (mem, DFmode))
7715 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7716 mem = SUBREG_REG (mem);
7719 rtx addr = XEXP (mem, 0);
7720 if (GET_CODE (addr) == PLUS
7721 && REG_P (XEXP (addr, 0))
7722 && REG_P (XEXP (addr, 1)))
7725 rtx reg0 = gen_rtx_REG (Pmode, 0);
7726 rtx regop = operands[store_p], word0 ,word1;
7728 if (GET_CODE (regop) == SUBREG)
7729 alter_subreg (®op, true);
7730 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7734 mem = copy_rtx (mem);
7735 PUT_MODE (mem, SImode);
7736 word0 = gen_rtx_SUBREG (SImode, regop, 0);
7737 alter_subreg (&word0, true);
7738 word1 = gen_rtx_SUBREG (SImode, regop, 4);
7739 alter_subreg (&word1, true);
7740 if (store_p || ! refers_to_regno_p (REGNO (word0),
7741 REGNO (word0) + 1, addr, 0))
7744 ? gen_movsi_ie (mem, word0)
7745 : gen_movsi_ie (word0, mem));
7746 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7747 mem = copy_rtx (mem);
7749 ? gen_movsi_ie (mem, word1)
7750 : gen_movsi_ie (word1, mem));
7751 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7755 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7756 emit_insn (gen_movsi_ie (word1, mem));
7757 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7758 mem = copy_rtx (mem);
7759 emit_insn (gen_movsi_ie (word0, mem));
7766 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7768 [(set (match_operand:DF 0 "register_operand" "")
7769 (match_operand:DF 1 "memory_operand" ""))
7770 (use (match_operand:PSI 2 "fpscr_operand" ""))
7771 (clobber (reg:SI R0_REG))]
7772 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7773 [(parallel [(set (match_dup 0) (match_dup 1))
7775 (clobber (scratch:SI))])]
7778 (define_expand "reload_indf__frn"
7779 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7780 (match_operand:DF 1 "immediate_operand" "FQ"))
7781 (use (reg:PSI FPSCR_REG))
7782 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7786 (define_expand "reload_outdf__RnFRm"
7787 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7788 (match_operand:DF 1 "register_operand" "af,r"))
7789 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7793 ;; Simplify no-op moves.
7795 [(set (match_operand:SF 0 "register_operand" "")
7796 (match_operand:SF 1 "register_operand" ""))
7797 (use (match_operand:PSI 2 "fpscr_operand" ""))
7798 (clobber (match_scratch:SI 3 ""))]
7799 "TARGET_SH2E && reload_completed
7800 && true_regnum (operands[0]) == true_regnum (operands[1])"
7801 [(set (match_dup 0) (match_dup 0))]
7804 ;; fmovd substitute post-reload splits
7806 [(set (match_operand:DF 0 "register_operand" "")
7807 (match_operand:DF 1 "register_operand" ""))
7808 (use (match_operand:PSI 2 "fpscr_operand" ""))
7809 (clobber (match_scratch:SI 3 ""))]
7810 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7811 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7812 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7815 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7816 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7817 gen_rtx_REG (SFmode, src), operands[2]));
7818 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7819 gen_rtx_REG (SFmode, src + 1), operands[2]));
7824 [(set (match_operand:DF 0 "register_operand" "")
7825 (mem:DF (match_operand:SI 1 "register_operand" "")))
7826 (use (match_operand:PSI 2 "fpscr_operand" ""))
7827 (clobber (match_scratch:SI 3 ""))]
7828 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7829 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7830 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7833 int regno = true_regnum (operands[0]);
7835 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7837 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7838 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7839 regno + SH_REG_MSW_OFFSET),
7840 mem2, operands[2]));
7841 add_reg_note (insn, REG_INC, operands[1]);
7842 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7843 regno + SH_REG_LSW_OFFSET),
7844 change_address (mem, SFmode, NULL_RTX),
7850 [(set (match_operand:DF 0 "register_operand" "")
7851 (match_operand:DF 1 "memory_operand" ""))
7852 (use (match_operand:PSI 2 "fpscr_operand" ""))
7853 (clobber (match_scratch:SI 3 ""))]
7854 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7855 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7858 int regno = true_regnum (operands[0]);
7860 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7861 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
7862 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
7864 operands[1] = copy_rtx (mem2);
7865 addr = XEXP (mem2, 0);
7867 switch (GET_CODE (addr))
7870 /* This is complicated. If the register is an arithmetic register
7871 we can just fall through to the REG+DISP case below. Otherwise
7872 we have to use a combination of POST_INC and REG addressing... */
7873 if (! arith_reg_operand (operands[1], SFmode))
7875 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7876 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
7877 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7879 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7881 /* If we have modified the stack pointer, the value that we have
7882 read with post-increment might be modified by an interrupt,
7883 so write it back. */
7884 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7885 emit_insn (gen_push_e (reg0));
7887 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0),
7894 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7895 operands[1] = copy_rtx (operands[1]);
7896 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7897 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7901 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7902 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7904 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7905 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7917 [(set (match_operand:DF 0 "memory_operand" "")
7918 (match_operand:DF 1 "register_operand" ""))
7919 (use (match_operand:PSI 2 "fpscr_operand" ""))
7920 (clobber (match_scratch:SI 3 ""))]
7921 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7922 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7925 int regno = true_regnum (operands[1]);
7927 rtx reg0 = gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET);
7928 rtx reg1 = gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET);
7930 operands[0] = copy_rtx (operands[0]);
7931 PUT_MODE (operands[0], SFmode);
7932 addr = XEXP (operands[0], 0);
7934 switch (GET_CODE (addr))
7937 /* This is complicated. If the register is an arithmetic register
7938 we can just fall through to the REG+DISP case below. Otherwise
7939 we have to use a combination of REG and PRE_DEC addressing... */
7940 if (! arith_reg_operand (operands[0], SFmode))
7942 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
7943 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7945 operands[0] = copy_rtx (operands[0]);
7946 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
7948 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7949 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7955 /* Since REG+DISP addressing has already been decided upon by gcc
7956 we can rely upon it having chosen an arithmetic register as the
7957 register component of the address. Just emit the lower numbered
7958 register first, to the lower address, then the higher numbered
7959 register to the higher address. */
7960 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7962 operands[0] = copy_rtx (operands[0]);
7963 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
7965 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7969 /* This is easy. Output the word to go to the higher address
7970 first (ie the word in the higher numbered register) then the
7971 word to go to the lower address. */
7973 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7974 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7976 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7977 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7989 ;; If the output is a register and the input is memory or a register, we have
7990 ;; to be careful and see which word needs to be loaded first.
7992 [(set (match_operand:DF 0 "general_movdst_operand" "")
7993 (match_operand:DF 1 "general_movsrc_operand" ""))]
7994 "TARGET_SH1 && reload_completed"
7995 [(set (match_dup 2) (match_dup 3))
7996 (set (match_dup 4) (match_dup 5))]
8000 if ((MEM_P (operands[0])
8001 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
8002 || (MEM_P (operands[1])
8003 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
8006 switch (GET_CODE (operands[0]))
8009 regno = REGNO (operands[0]);
8012 regno = subreg_regno (operands[0]);
8022 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8024 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
8025 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
8026 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
8027 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
8031 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
8032 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
8033 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
8034 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
8037 if (operands[2] == 0 || operands[3] == 0
8038 || operands[4] == 0 || operands[5] == 0)
8042 (define_expand "movdf"
8043 [(set (match_operand:DF 0 "general_movdst_operand" "")
8044 (match_operand:DF 1 "general_movsrc_operand" ""))]
8047 prepare_move_operands (operands, DFmode);
8050 if (TARGET_SHMEDIA_FPU)
8051 emit_insn (gen_movdf_media (operands[0], operands[1]));
8053 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
8056 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8058 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8063 ;;This is incompatible with the way gcc uses subregs.
8064 ;;(define_insn "movv2sf_i"
8065 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
8066 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
8067 ;; "TARGET_SHMEDIA_FPU
8068 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
8069 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
8073 ;; fst%M0.p %m0, %1"
8074 ;; [(set_attr "type" "*,fload_media,fstore_media")])
8075 (define_insn_and_split "movv2sf_i"
8076 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8077 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8078 "TARGET_SHMEDIA_FPU"
8080 "TARGET_SHMEDIA_FPU && reload_completed"
8081 [(set (match_dup 0) (match_dup 1))]
8083 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
8084 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
8087 (define_expand "movv2sf"
8088 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
8089 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
8090 "TARGET_SHMEDIA_FPU"
8092 prepare_move_operands (operands, V2SFmode);
8095 (define_expand "addv2sf3"
8096 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8097 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8098 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8099 "TARGET_SHMEDIA_FPU"
8101 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
8105 (define_expand "subv2sf3"
8106 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8107 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8108 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8109 "TARGET_SHMEDIA_FPU"
8111 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
8115 (define_expand "mulv2sf3"
8116 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8117 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8118 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8119 "TARGET_SHMEDIA_FPU"
8121 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
8125 (define_expand "divv2sf3"
8126 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
8127 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
8128 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
8129 "TARGET_SHMEDIA_FPU"
8131 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
8135 (define_insn_and_split "*movv4sf_i"
8136 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
8137 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
8138 "TARGET_SHMEDIA_FPU"
8140 "&& reload_completed"
8143 for (int i = 0; i < 4/2; i++)
8147 if (MEM_P (operands[0]))
8148 x = adjust_address (operands[0], V2SFmode,
8149 i * GET_MODE_SIZE (V2SFmode));
8151 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
8153 if (MEM_P (operands[1]))
8154 y = adjust_address (operands[1], V2SFmode,
8155 i * GET_MODE_SIZE (V2SFmode));
8157 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
8159 emit_insn (gen_movv2sf_i (x, y));
8164 [(set_attr "length" "8")])
8166 (define_expand "movv4sf"
8167 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
8168 (match_operand:V4SF 1 "general_operand" ""))]
8169 "TARGET_SHMEDIA_FPU"
8171 prepare_move_operands (operands, V4SFmode);
8174 (define_insn_and_split "*movv16sf_i"
8175 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8176 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8177 "TARGET_SHMEDIA_FPU"
8179 "&& reload_completed"
8182 for (int i = 0; i < 16/2; i++)
8186 if (MEM_P (operands[0]))
8187 x = adjust_address (operands[0], V2SFmode,
8188 i * GET_MODE_SIZE (V2SFmode));
8191 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
8192 alter_subreg (&x, true);
8195 if (MEM_P (operands[1]))
8196 y = adjust_address (operands[1], V2SFmode,
8197 i * GET_MODE_SIZE (V2SFmode));
8200 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
8201 alter_subreg (&y, true);
8204 emit_insn (gen_movv2sf_i (x, y));
8209 [(set_attr "length" "32")])
8211 (define_expand "movv16sf"
8212 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
8213 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
8214 "TARGET_SHMEDIA_FPU"
8216 prepare_move_operands (operands, V16SFmode);
8219 (define_insn "movsf_media"
8220 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
8221 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
8223 && (register_operand (operands[0], SFmode)
8224 || sh_register_operand (operands[1], SFmode))"
8235 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
8236 (set (attr "highpart")
8237 (cond [(match_test "sh_contains_memref_p (insn)")
8238 (const_string "user")]
8239 (const_string "ignore")))])
8241 (define_insn "movsf_media_nofpu"
8242 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
8243 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
8245 && (register_operand (operands[0], SFmode)
8246 || sh_register_operand (operands[1], SFmode))"
8252 [(set_attr "type" "arith_media,*,load_media,store_media")
8253 (set (attr "highpart")
8254 (cond [(match_test "sh_contains_memref_p (insn)")
8255 (const_string "user")]
8256 (const_string "ignore")))])
8259 [(set (match_operand:SF 0 "arith_reg_dest" "")
8260 (match_operand:SF 1 "immediate_operand" ""))]
8261 "TARGET_SHMEDIA && reload_completed
8262 && ! FP_REGISTER_P (true_regnum (operands[0]))"
8263 [(set (match_dup 3) (match_dup 2))]
8266 REAL_VALUE_TYPE value;
8268 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
8269 REAL_VALUE_TO_TARGET_SINGLE (value, values);
8270 operands[2] = GEN_INT (values);
8272 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8275 (define_insn "movsf_i"
8276 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
8277 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
8280 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
8281 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
8282 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
8283 && (arith_reg_operand (operands[0], SFmode)
8284 || arith_reg_operand (operands[1], SFmode))"
8293 [(set_attr "type" "move,move,pcload,load,store,move,move")])
8295 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
8296 ;; update_flow_info would not know where to put REG_EQUAL notes
8297 ;; when the destination changes mode.
8298 (define_insn "movsf_ie"
8299 [(set (match_operand:SF 0 "general_movdst_operand"
8300 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
8301 (match_operand:SF 1 "general_movsrc_operand"
8302 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
8303 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
8304 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
8306 && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode)
8307 || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode)
8308 || arith_reg_operand (operands[3], SImode))"
8328 ! move optimized away"
8329 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
8330 store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
8331 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
8332 (set_attr_alternative "length"
8339 (match_test "TARGET_SH2A")
8340 (const_int 4) (const_int 2))
8342 (match_test "TARGET_SH2A")
8343 (const_int 4) (const_int 2))
8346 (match_test "TARGET_SH2A")
8347 (const_int 4) (const_int 2))
8349 (match_test "TARGET_SH2A")
8350 (const_int 4) (const_int 2))
8360 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
8361 (const_string "single")
8362 (const_string "single")))])
8365 [(set (match_operand:SF 0 "register_operand" "")
8366 (match_operand:SF 1 "register_operand" ""))
8367 (use (match_operand:PSI 2 "fpscr_operand" ""))
8368 (clobber (reg:SI FPUL_REG))]
8370 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8372 (clobber (scratch:SI))])
8373 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8375 (clobber (scratch:SI))])]
8378 (define_expand "movsf"
8379 [(set (match_operand:SF 0 "general_movdst_operand" "")
8380 (match_operand:SF 1 "general_movsrc_operand" ""))]
8383 prepare_move_operands (operands, SFmode);
8386 if (TARGET_SHMEDIA_FPU)
8387 emit_insn (gen_movsf_media (operands[0], operands[1]));
8389 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8394 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
8399 (define_insn "mov_nop"
8400 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8403 [(set_attr "length" "0")
8404 (set_attr "type" "nil")])
8406 (define_expand "reload_insf__frn"
8407 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8408 (match_operand:SF 1 "immediate_operand" "FQ"))
8409 (use (reg:PSI FPSCR_REG))
8410 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8414 (define_expand "reload_insi__i_fpul"
8415 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8416 (match_operand:SI 1 "immediate_operand" "i"))
8417 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8421 (define_expand "ptabs"
8422 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8425 if (!TARGET_PT_FIXED)
8427 rtx eq = operands[1];
8429 /* ??? For canonical RTL we really should remove any CONST from EQ
8430 before wrapping it in the AND, and finally wrap the EQ into a
8431 const if is constant. However, for reload we must expose the
8432 input register or symbolic constant, and we can't have
8433 different insn structures outside of the operands for different
8434 alternatives of the same pattern. */
8435 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8438 = (gen_rtx_IF_THEN_ELSE
8441 gen_rtx_MEM (PDImode, operands[1]),
8442 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8443 PDImode, operands[1])));
8447 ;; expanded by ptabs expander.
8448 (define_insn "*extendsipdi_media"
8449 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8450 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8454 (mem:PDI (match_dup 1))
8455 (sign_extend:PDI (match_dup 1))))]
8456 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8460 [(set_attr "type" "ptabs_media,pt_media")
8461 (set_attr "length" "4,*")])
8463 (define_insn "*truncdipdi_media"
8464 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8465 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8469 (mem:PDI (match_dup 1))
8470 (truncate:PDI (match_dup 1))))]
8471 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8475 [(set_attr "type" "ptabs_media,pt_media")
8476 (set_attr "length" "4,*")])
8478 (define_insn "*movsi_y"
8479 [(set (match_operand:SI 0 "register_operand" "=y,y")
8480 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8481 (clobber (match_scratch:SI 2 "=&z,r"))]
8483 && (reload_in_progress || reload_completed)"
8485 [(set_attr "length" "4")
8486 (set_attr "type" "pcload,move")])
8489 [(set (match_operand:SI 0 "register_operand" "")
8490 (match_operand:SI 1 "immediate_operand" ""))
8491 (clobber (match_operand:SI 2 "register_operand" ""))]
8493 [(set (match_dup 2) (match_dup 1))
8494 (set (match_dup 0) (match_dup 2))]
8497 ;; ------------------------------------------------------------------------
8498 ;; Define the real conditional branch instructions.
8499 ;; ------------------------------------------------------------------------
8501 (define_expand "branch_true"
8502 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8503 (label_ref (match_operand 0))
8507 (define_expand "branch_false"
8508 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8509 (label_ref (match_operand 0))
8513 (define_insn_and_split "*cbranch_t"
8514 [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8515 (label_ref (match_operand 0))
8519 return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8524 /* Try to canonicalize the branch condition if it is not one of:
8525 (ne (reg:SI T_REG) (const_int 0))
8526 (eq (reg:SI T_REG) (const_int 0))
8528 Instead of splitting out a new insn, we modify the current insn's
8529 operands as needed. This preserves things such as REG_DEAD notes. */
8531 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
8532 && REG_P (XEXP (operands[1], 0)) && REGNO (XEXP (operands[1], 0)) == T_REG
8533 && XEXP (operands[1], 1) == const0_rtx)
8536 int branch_cond = sh_eval_treg_value (operands[1]);
8537 rtx new_cond_rtx = NULL_RTX;
8539 if (branch_cond == 0)
8540 new_cond_rtx = gen_rtx_EQ (VOIDmode, get_t_reg_rtx (), const0_rtx);
8541 else if (branch_cond == 1)
8542 new_cond_rtx = gen_rtx_NE (VOIDmode, get_t_reg_rtx (), const0_rtx);
8544 if (new_cond_rtx != NULL_RTX)
8545 validate_change (curr_insn, &XEXP (XEXP (PATTERN (curr_insn), 1), 0),
8546 new_cond_rtx, false);
8549 [(set_attr "type" "cbranch")])
8551 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8552 ;; which destination is too far away.
8553 ;; The const_int_operand is distinct for each branch target; it avoids
8554 ;; unwanted matches with redundant_insn.
8555 (define_insn "block_branch_redirect"
8556 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8559 [(set_attr "length" "0")])
8561 ;; This one has the additional purpose to record a possible scratch register
8562 ;; for the following branch.
8563 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8564 ;; because the insn then might be deemed dead and deleted. And we can't
8565 ;; make the use in the jump insn explicit because that would disable
8566 ;; delay slot scheduling from the target.
8567 (define_insn "indirect_jump_scratch"
8568 [(set (match_operand:SI 0 "register_operand" "=r")
8569 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8570 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8573 [(set_attr "length" "0")])
8575 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8576 ;; being pulled into the delay slot of a condbranch that has been made to
8577 ;; jump around the unconditional jump because it was out of range.
8578 (define_insn "stuff_delay_slot"
8580 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8581 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8584 [(set_attr "length" "0")
8585 (set_attr "cond_delay_slot" "yes")])
8587 ;; Conditional branch insns
8589 (define_expand "cbranchint4_media"
8591 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8592 [(match_operand 1 "" "")
8593 (match_operand 2 "" "")])
8594 (match_operand 3 "" "")
8598 enum machine_mode mode = GET_MODE (operands[1]);
8599 if (mode == VOIDmode)
8600 mode = GET_MODE (operands[2]);
8601 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8603 operands[1] = force_reg (mode, operands[1]);
8604 if (CONSTANT_P (operands[2])
8605 && (! satisfies_constraint_I06 (operands[2])))
8606 operands[2] = force_reg (mode, operands[2]);
8610 if (operands[1] != const0_rtx)
8611 operands[1] = force_reg (mode, operands[1]);
8612 if (operands[2] != const0_rtx)
8613 operands[2] = force_reg (mode, operands[2]);
8615 switch (GET_CODE (operands[0]))
8621 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8622 VOIDmode, operands[2], operands[1]);
8623 operands[1] = XEXP (operands[0], 0);
8624 operands[2] = XEXP (operands[0], 1);
8627 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8628 VOIDmode, operands[1], operands[2]);
8631 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8634 (define_expand "cbranchfp4_media"
8636 (if_then_else (match_operator 0 "sh_float_comparison_operator"
8637 [(match_operand 1 "" "")
8638 (match_operand 2 "" "")])
8639 (match_operand 3 "" "")
8643 rtx tmp = gen_reg_rtx (SImode);
8645 if (GET_CODE (operands[0]) == NE)
8646 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8648 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8649 operands[1], operands[2]);
8651 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8653 if (GET_CODE (cmp) == GET_CODE (operands[0]))
8654 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8656 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8658 operands[2] = const0_rtx;
8659 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8662 (define_insn "*beq_media_i"
8664 (if_then_else (match_operator 3 "equality_comparison_operator"
8665 [(match_operand:DI 1 "arith_reg_operand" "r,r")
8666 (match_operand:DI 2 "arith_operand" "r,I06")])
8667 (match_operand 0 "target_operand" "b,b")
8672 b%o3i%' %1, %2, %0%>"
8673 [(set_attr "type" "cbranch_media")])
8675 (define_insn "*beq_media_i32"
8677 (if_then_else (match_operator 3 "equality_comparison_operator"
8678 [(match_operand:SI 1 "arith_reg_operand" "r,r")
8679 (match_operand:SI 2 "arith_operand" "r,I06")])
8680 (match_operand 0 "target_operand" "b,b")
8685 b%o3i%' %1, %2, %0%>"
8686 [(set_attr "type" "cbranch_media")])
8688 (define_insn "*bgt_media_i"
8690 (if_then_else (match_operator 3 "greater_comparison_operator"
8691 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8692 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8693 (match_operand 0 "target_operand" "b")
8696 "b%o3%' %N1, %N2, %0%>"
8697 [(set_attr "type" "cbranch_media")])
8699 (define_insn "*bgt_media_i32"
8701 (if_then_else (match_operator 3 "greater_comparison_operator"
8702 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8703 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8704 (match_operand 0 "target_operand" "b")
8707 "b%o3%' %N1, %N2, %0%>"
8708 [(set_attr "type" "cbranch_media")])
8710 ;; These are only needed to make invert_jump() happy - otherwise, jump
8711 ;; optimization will be silently disabled.
8712 (define_insn "*blt_media_i"
8714 (if_then_else (match_operator 3 "less_comparison_operator"
8715 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8716 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8717 (match_operand 0 "target_operand" "b")
8720 "b%o3%' %N2, %N1, %0%>"
8721 [(set_attr "type" "cbranch_media")])
8723 (define_insn "*blt_media_i32"
8725 (if_then_else (match_operator 3 "less_comparison_operator"
8726 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8727 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8728 (match_operand 0 "target_operand" "b")
8731 "b%o3%' %N2, %N1, %0%>"
8732 [(set_attr "type" "cbranch_media")])
8734 ;; combiner splitter for test-and-branch on single bit in register. This
8735 ;; is endian dependent because the non-paradoxical subreg looks different
8740 (match_operator 3 "equality_comparison_operator"
8743 (subreg:DI (match_operand:SI 1 "extend_reg_operand" "") 0)
8745 (match_operand 2 "const_int_operand" "")) 0)
8747 (match_operand 0 "target_operand" "")
8749 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8750 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8751 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8752 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8754 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8755 operands[6] = (GET_CODE (operands[3]) == EQ
8756 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8757 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8760 ; operand 0 is the loop count pseudo register
8761 ; operand 1 is the label to jump to at the top of the loop
8762 (define_expand "doloop_end"
8763 [(parallel [(set (pc)
8764 (if_then_else (ne:SI (match_operand:SI 0 "" "")
8766 (label_ref (match_operand 1 "" ""))
8769 (plus:SI (match_dup 0) (const_int -1)))
8770 (clobber (reg:SI T_REG))])]
8773 if (GET_MODE (operands[0]) != SImode)
8775 emit_jump_insn (gen_doloop_end_split (operands[0], operands[1], operands[0]));
8779 (define_insn_and_split "doloop_end_split"
8781 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8783 (label_ref (match_operand 1 "" ""))
8785 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8786 (plus:SI (match_dup 2) (const_int -1)))
8787 (clobber (reg:SI T_REG))]
8791 [(parallel [(set (reg:SI T_REG)
8792 (eq:SI (match_dup 2) (const_int 1)))
8793 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8794 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8795 (label_ref (match_dup 1))
8798 [(set_attr "type" "cbranch")])
8800 ;; ------------------------------------------------------------------------
8801 ;; Jump and linkage insns
8802 ;; ------------------------------------------------------------------------
8804 (define_insn "jump_compact"
8806 (label_ref (match_operand 0 "" "")))]
8807 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
8809 /* The length is 16 if the delay slot is unfilled. */
8810 if (get_attr_length(insn) > 4)
8811 return output_far_jump(insn, operands[0]);
8815 [(set_attr "type" "jump")
8816 (set_attr "needs_delay_slot" "yes")])
8818 ;; ??? It would be much saner to explicitly use the scratch register
8819 ;; in the jump insn, and have indirect_jump_scratch only set it,
8820 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8821 ;; from the target then, as it uses simplejump_p.
8822 ;;(define_insn "jump_compact_far"
8824 ;; (label_ref (match_operand 0 "" "")))
8825 ;; (use (match_operand 1 "register_operand" "r")]
8827 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
8828 ;; [(set_attr "type" "jump")
8829 ;; (set_attr "needs_delay_slot" "yes")])
8831 (define_insn "jump_media"
8833 (match_operand 0 "target_operand" "b"))]
8836 [(set_attr "type" "jump_media")])
8838 (define_expand "jump"
8840 (label_ref (match_operand 0 "" "")))]
8844 emit_jump_insn (gen_jump_compact (operands[0]));
8845 else if (TARGET_SHMEDIA)
8847 if (reload_in_progress || reload_completed)
8849 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode, operands[0])));
8854 (define_insn "force_mode_for_call"
8855 [(use (reg:PSI FPSCR_REG))]
8858 [(set_attr "length" "0")
8859 (set (attr "fp_mode")
8860 (if_then_else (eq_attr "fpu_single" "yes")
8861 (const_string "single") (const_string "double")))])
8863 (define_insn "calli"
8864 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8865 (match_operand 1 "" ""))
8866 (use (reg:PSI FPSCR_REG))
8867 (clobber (reg:SI PR_REG))]
8870 if (TARGET_SH2A && (dbr_sequence_length () == 0))
8875 [(set_attr "type" "call")
8876 (set (attr "fp_mode")
8877 (if_then_else (eq_attr "fpu_single" "yes")
8878 (const_string "single") (const_string "double")))
8879 (set_attr "needs_delay_slot" "yes")
8880 (set_attr "fp_set" "unknown")])
8882 ;; This is TBR relative jump instruction for SH2A architecture.
8883 ;; Its use is enabled by assigning an attribute "function_vector"
8884 ;; and the vector number to a function during its declaration.
8885 (define_insn "calli_tbr_rel"
8886 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
8887 (match_operand 1 "" ""))
8888 (use (reg:PSI FPSCR_REG))
8889 (clobber (reg:SI PR_REG))]
8890 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
8892 unsigned HOST_WIDE_INT vect_num;
8893 vect_num = sh2a_get_function_vector_number (operands[0]);
8894 operands[2] = GEN_INT (vect_num * 4);
8896 return "jsr/n @@(%O2,tbr)";
8898 [(set_attr "type" "call")
8899 (set (attr "fp_mode")
8900 (if_then_else (eq_attr "fpu_single" "yes")
8901 (const_string "single") (const_string "double")))
8902 (set_attr "needs_delay_slot" "no")
8903 (set_attr "fp_set" "unknown")])
8905 ;; This is a pc-rel call, using bsrf, for use with PIC.
8906 (define_insn "calli_pcrel"
8907 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8908 (match_operand 1 "" ""))
8909 (use (reg:PSI FPSCR_REG))
8910 (use (reg:SI PIC_REG))
8911 (use (match_operand 2 "" ""))
8912 (clobber (reg:SI PR_REG))]
8915 return "bsrf %0" "\n"
8918 [(set_attr "type" "call")
8919 (set (attr "fp_mode")
8920 (if_then_else (eq_attr "fpu_single" "yes")
8921 (const_string "single") (const_string "double")))
8922 (set_attr "needs_delay_slot" "yes")
8923 (set_attr "fp_set" "unknown")])
8925 (define_insn_and_split "call_pcrel"
8926 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8927 (match_operand 1 "" ""))
8928 (use (reg:PSI FPSCR_REG))
8929 (use (reg:SI PIC_REG))
8930 (clobber (reg:SI PR_REG))
8931 (clobber (match_scratch:SI 2 "=r"))]
8937 rtx lab = PATTERN (gen_call_site ());
8939 if (SYMBOL_REF_LOCAL_P (operands[0]))
8940 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8942 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
8943 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
8946 [(set_attr "type" "call")
8947 (set (attr "fp_mode")
8948 (if_then_else (eq_attr "fpu_single" "yes")
8949 (const_string "single") (const_string "double")))
8950 (set_attr "needs_delay_slot" "yes")
8951 (set_attr "fp_set" "unknown")])
8953 (define_insn "call_compact"
8954 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8955 (match_operand 1 "" ""))
8956 (match_operand 2 "immediate_operand" "n")
8957 (use (reg:SI R0_REG))
8958 (use (reg:SI R1_REG))
8959 (use (reg:PSI FPSCR_REG))
8960 (clobber (reg:SI PR_REG))]
8961 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8963 [(set_attr "type" "call")
8964 (set (attr "fp_mode")
8965 (if_then_else (eq_attr "fpu_single" "yes")
8966 (const_string "single") (const_string "double")))
8967 (set_attr "needs_delay_slot" "yes")])
8969 (define_insn "call_compact_rettramp"
8970 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8971 (match_operand 1 "" ""))
8972 (match_operand 2 "immediate_operand" "n")
8973 (use (reg:SI R0_REG))
8974 (use (reg:SI R1_REG))
8975 (use (reg:PSI FPSCR_REG))
8976 (clobber (reg:SI R10_REG))
8977 (clobber (reg:SI PR_REG))]
8978 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8980 [(set_attr "type" "call")
8981 (set (attr "fp_mode")
8982 (if_then_else (eq_attr "fpu_single" "yes")
8983 (const_string "single") (const_string "double")))
8984 (set_attr "needs_delay_slot" "yes")])
8986 (define_insn "call_media"
8987 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
8988 (match_operand 1 "" ""))
8989 (clobber (reg:DI PR_MEDIA_REG))]
8992 [(set_attr "type" "jump_media")])
8994 (define_insn "call_valuei"
8995 [(set (match_operand 0 "" "=rf")
8996 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8997 (match_operand 2 "" "")))
8998 (use (reg:PSI FPSCR_REG))
8999 (clobber (reg:SI PR_REG))]
9002 if (TARGET_SH2A && (dbr_sequence_length () == 0))
9007 [(set_attr "type" "call")
9008 (set (attr "fp_mode")
9009 (if_then_else (eq_attr "fpu_single" "yes")
9010 (const_string "single") (const_string "double")))
9011 (set_attr "needs_delay_slot" "yes")
9012 (set_attr "fp_set" "unknown")])
9014 ;; This is TBR relative jump instruction for SH2A architecture.
9015 ;; Its use is enabled by assigning an attribute "function_vector"
9016 ;; and the vector number to a function during its declaration.
9017 (define_insn "call_valuei_tbr_rel"
9018 [(set (match_operand 0 "" "=rf")
9019 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9020 (match_operand 2 "" "")))
9021 (use (reg:PSI FPSCR_REG))
9022 (clobber (reg:SI PR_REG))]
9023 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
9025 unsigned HOST_WIDE_INT vect_num;
9026 vect_num = sh2a_get_function_vector_number (operands[1]);
9027 operands[3] = GEN_INT (vect_num * 4);
9029 return "jsr/n @@(%O3,tbr)";
9031 [(set_attr "type" "call")
9032 (set (attr "fp_mode")
9033 (if_then_else (eq_attr "fpu_single" "yes")
9034 (const_string "single") (const_string "double")))
9035 (set_attr "needs_delay_slot" "no")
9036 (set_attr "fp_set" "unknown")])
9038 (define_insn "call_valuei_pcrel"
9039 [(set (match_operand 0 "" "=rf")
9040 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9041 (match_operand 2 "" "")))
9042 (use (reg:PSI FPSCR_REG))
9043 (use (reg:SI PIC_REG))
9044 (use (match_operand 3 "" ""))
9045 (clobber (reg:SI PR_REG))]
9048 return "bsrf %1" "\n"
9051 [(set_attr "type" "call")
9052 (set (attr "fp_mode")
9053 (if_then_else (eq_attr "fpu_single" "yes")
9054 (const_string "single") (const_string "double")))
9055 (set_attr "needs_delay_slot" "yes")
9056 (set_attr "fp_set" "unknown")])
9058 (define_insn_and_split "call_value_pcrel"
9059 [(set (match_operand 0 "" "=rf")
9060 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9061 (match_operand 2 "" "")))
9062 (use (reg:PSI FPSCR_REG))
9063 (use (reg:SI PIC_REG))
9064 (clobber (reg:SI PR_REG))
9065 (clobber (match_scratch:SI 3 "=r"))]
9071 rtx lab = PATTERN (gen_call_site ());
9073 if (SYMBOL_REF_LOCAL_P (operands[1]))
9074 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9076 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
9077 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
9078 operands[2], copy_rtx (lab)));
9081 [(set_attr "type" "call")
9082 (set (attr "fp_mode")
9083 (if_then_else (eq_attr "fpu_single" "yes")
9084 (const_string "single") (const_string "double")))
9085 (set_attr "needs_delay_slot" "yes")
9086 (set_attr "fp_set" "unknown")])
9088 (define_insn "call_value_compact"
9089 [(set (match_operand 0 "" "=rf")
9090 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9091 (match_operand 2 "" "")))
9092 (match_operand 3 "immediate_operand" "n")
9093 (use (reg:SI R0_REG))
9094 (use (reg:SI R1_REG))
9095 (use (reg:PSI FPSCR_REG))
9096 (clobber (reg:SI PR_REG))]
9097 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9099 [(set_attr "type" "call")
9100 (set (attr "fp_mode")
9101 (if_then_else (eq_attr "fpu_single" "yes")
9102 (const_string "single") (const_string "double")))
9103 (set_attr "needs_delay_slot" "yes")])
9105 (define_insn "call_value_compact_rettramp"
9106 [(set (match_operand 0 "" "=rf")
9107 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9108 (match_operand 2 "" "")))
9109 (match_operand 3 "immediate_operand" "n")
9110 (use (reg:SI R0_REG))
9111 (use (reg:SI R1_REG))
9112 (use (reg:PSI FPSCR_REG))
9113 (clobber (reg:SI R10_REG))
9114 (clobber (reg:SI PR_REG))]
9115 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9117 [(set_attr "type" "call")
9118 (set (attr "fp_mode")
9119 (if_then_else (eq_attr "fpu_single" "yes")
9120 (const_string "single") (const_string "double")))
9121 (set_attr "needs_delay_slot" "yes")])
9123 (define_insn "call_value_media"
9124 [(set (match_operand 0 "" "=rf")
9125 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
9126 (match_operand 2 "" "")))
9127 (clobber (reg:DI PR_MEDIA_REG))]
9130 [(set_attr "type" "jump_media")])
9132 (define_expand "call"
9133 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9134 (match_operand 1 "" ""))
9135 (match_operand 2 "" "")
9136 (use (reg:PSI FPSCR_REG))
9137 (clobber (reg:SI PR_REG))])]
9142 operands[0] = shmedia_prepare_call_address (operands[0], 0);
9143 emit_call_insn (gen_call_media (operands[0], operands[1]));
9146 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
9148 rtx cookie_rtx = operands[2];
9149 long cookie = INTVAL (cookie_rtx);
9150 rtx func = XEXP (operands[0], 0);
9155 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9157 rtx reg = gen_reg_rtx (Pmode);
9159 emit_insn (gen_symGOTPLT2reg (reg, func));
9163 func = legitimize_pic_address (func, Pmode, 0);
9166 r0 = gen_rtx_REG (SImode, R0_REG);
9167 r1 = gen_rtx_REG (SImode, R1_REG);
9169 /* Since such a call function may use all call-clobbered
9170 registers, we force a mode switch earlier, so that we don't
9171 run out of registers when adjusting fpscr for the call. */
9172 emit_insn (gen_force_mode_for_call ());
9175 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9176 operands[0] = force_reg (SImode, operands[0]);
9178 emit_move_insn (r0, func);
9179 emit_move_insn (r1, cookie_rtx);
9181 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9182 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
9185 emit_call_insn (gen_call_compact (operands[0], operands[1],
9190 else if (TARGET_SHCOMPACT && flag_pic
9191 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9192 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9194 rtx reg = gen_reg_rtx (Pmode);
9196 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
9197 XEXP (operands[0], 0) = reg;
9199 if (!flag_pic && TARGET_SH2A
9200 && MEM_P (operands[0])
9201 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9203 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
9205 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
9210 if (flag_pic && TARGET_SH2
9211 && MEM_P (operands[0])
9212 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
9214 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
9219 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9220 operands[1] = operands[2];
9223 emit_call_insn (gen_calli (operands[0], operands[1]));
9227 (define_insn "call_pop_compact"
9228 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9229 (match_operand 1 "" ""))
9230 (match_operand 2 "immediate_operand" "n")
9231 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9232 (match_operand 3 "immediate_operand" "n")))
9233 (use (reg:SI R0_REG))
9234 (use (reg:SI R1_REG))
9235 (use (reg:PSI FPSCR_REG))
9236 (clobber (reg:SI PR_REG))]
9237 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9239 [(set_attr "type" "call")
9240 (set (attr "fp_mode")
9241 (if_then_else (eq_attr "fpu_single" "yes")
9242 (const_string "single") (const_string "double")))
9243 (set_attr "needs_delay_slot" "yes")])
9245 (define_insn "call_pop_compact_rettramp"
9246 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
9247 (match_operand 1 "" ""))
9248 (match_operand 2 "immediate_operand" "n")
9249 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9250 (match_operand 3 "immediate_operand" "n")))
9251 (use (reg:SI R0_REG))
9252 (use (reg:SI R1_REG))
9253 (use (reg:PSI FPSCR_REG))
9254 (clobber (reg:SI R10_REG))
9255 (clobber (reg:SI PR_REG))]
9256 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
9258 [(set_attr "type" "call")
9259 (set (attr "fp_mode")
9260 (if_then_else (eq_attr "fpu_single" "yes")
9261 (const_string "single") (const_string "double")))
9262 (set_attr "needs_delay_slot" "yes")])
9264 (define_expand "call_pop"
9265 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9266 (match_operand 1 "" ""))
9267 (match_operand 2 "" "")
9268 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9269 (match_operand 3 "" "")))])]
9277 gcc_assert (operands[2] && INTVAL (operands[2]));
9278 cookie_rtx = operands[2];
9279 cookie = INTVAL (cookie_rtx);
9280 func = XEXP (operands[0], 0);
9284 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9286 rtx reg = gen_reg_rtx (Pmode);
9287 emit_insn (gen_symGOTPLT2reg (reg, func));
9291 func = legitimize_pic_address (func, Pmode, 0);
9294 r0 = gen_rtx_REG (SImode, R0_REG);
9295 r1 = gen_rtx_REG (SImode, R1_REG);
9297 /* Since such a call function may use all call-clobbered
9298 registers, we force a mode switch earlier, so that we don't
9299 run out of registers when adjusting fpscr for the call. */
9300 emit_insn (gen_force_mode_for_call ());
9302 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9304 operands[0] = force_reg (SImode, operands[0]);
9306 emit_move_insn (r0, func);
9307 emit_move_insn (r1, cookie_rtx);
9309 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9310 emit_call_insn (gen_call_pop_compact_rettramp
9311 (operands[0], operands[1], operands[2], operands[3]));
9313 emit_call_insn (gen_call_pop_compact
9314 (operands[0], operands[1], operands[2], operands[3]));
9319 (define_expand "call_value"
9320 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9321 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9322 (match_operand 2 "" "")))
9323 (match_operand 3 "" "")
9324 (use (reg:PSI FPSCR_REG))
9325 (clobber (reg:SI PR_REG))])]
9330 operands[1] = shmedia_prepare_call_address (operands[1], 0);
9331 emit_call_insn (gen_call_value_media (operands[0], operands[1],
9335 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9337 rtx cookie_rtx = operands[3];
9338 long cookie = INTVAL (cookie_rtx);
9339 rtx func = XEXP (operands[1], 0);
9344 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9346 rtx reg = gen_reg_rtx (Pmode);
9348 emit_insn (gen_symGOTPLT2reg (reg, func));
9352 func = legitimize_pic_address (func, Pmode, 0);
9355 r0 = gen_rtx_REG (SImode, R0_REG);
9356 r1 = gen_rtx_REG (SImode, R1_REG);
9358 /* Since such a call function may use all call-clobbered
9359 registers, we force a mode switch earlier, so that we don't
9360 run out of registers when adjusting fpscr for the call. */
9361 emit_insn (gen_force_mode_for_call ());
9364 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9365 operands[1] = force_reg (SImode, operands[1]);
9367 emit_move_insn (r0, func);
9368 emit_move_insn (r1, cookie_rtx);
9370 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9371 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9376 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9377 operands[2], operands[3]));
9381 else if (TARGET_SHCOMPACT && flag_pic
9382 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9383 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9385 rtx reg = gen_reg_rtx (Pmode);
9387 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9388 XEXP (operands[1], 0) = reg;
9390 if (!flag_pic && TARGET_SH2A
9391 && MEM_P (operands[1])
9392 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9394 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9396 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9397 XEXP (operands[1], 0), operands[2]));
9401 if (flag_pic && TARGET_SH2
9402 && MEM_P (operands[1])
9403 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9405 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9410 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9412 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9416 (define_insn "sibcalli"
9417 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9418 (match_operand 1 "" ""))
9419 (use (reg:PSI FPSCR_REG))
9423 [(set_attr "needs_delay_slot" "yes")
9424 (set (attr "fp_mode")
9425 (if_then_else (eq_attr "fpu_single" "yes")
9426 (const_string "single") (const_string "double")))
9427 (set_attr "type" "jump_ind")])
9429 (define_insn "sibcalli_pcrel"
9430 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9431 (match_operand 1 "" ""))
9432 (use (match_operand 2 "" ""))
9433 (use (reg:PSI FPSCR_REG))
9437 return "braf %0" "\n"
9440 [(set_attr "needs_delay_slot" "yes")
9441 (set (attr "fp_mode")
9442 (if_then_else (eq_attr "fpu_single" "yes")
9443 (const_string "single") (const_string "double")))
9444 (set_attr "type" "jump_ind")])
9446 ;; This uses an unspec to describe that the symbol_ref is very close.
9447 (define_insn "sibcalli_thunk"
9448 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9450 (match_operand 1 "" ""))
9451 (use (reg:PSI FPSCR_REG))
9455 [(set_attr "needs_delay_slot" "yes")
9456 (set (attr "fp_mode")
9457 (if_then_else (eq_attr "fpu_single" "yes")
9458 (const_string "single") (const_string "double")))
9459 (set_attr "type" "jump")
9460 (set_attr "length" "2")])
9462 (define_insn_and_split "sibcall_pcrel"
9463 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9464 (match_operand 1 "" ""))
9465 (use (reg:PSI FPSCR_REG))
9466 (clobber (match_scratch:SI 2 "=k"))
9473 rtx lab = PATTERN (gen_call_site ());
9476 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9477 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9479 SIBLING_CALL_P (call_insn) = 1;
9482 [(set_attr "needs_delay_slot" "yes")
9483 (set (attr "fp_mode")
9484 (if_then_else (eq_attr "fpu_single" "yes")
9485 (const_string "single") (const_string "double")))
9486 (set_attr "type" "jump_ind")])
9488 (define_insn "sibcall_compact"
9489 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9490 (match_operand 1 "" ""))
9492 (use (match_operand:SI 2 "register_operand" "z,x"))
9493 (use (reg:SI R1_REG))
9494 (use (reg:PSI FPSCR_REG))
9495 ;; We want to make sure the `x' above will only match MACH_REG
9496 ;; because sibcall_epilogue may clobber MACL_REG.
9497 (clobber (reg:SI MACL_REG))]
9500 static const char* alt[] =
9507 return alt[which_alternative];
9509 [(set_attr "needs_delay_slot" "yes,no")
9510 (set_attr "length" "2,4")
9511 (set (attr "fp_mode") (const_string "single"))
9512 (set_attr "type" "jump_ind")])
9514 (define_insn "sibcall_media"
9515 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9516 (match_operand 1 "" ""))
9517 (use (reg:SI PR_MEDIA_REG))
9521 [(set_attr "type" "jump_media")])
9523 (define_expand "sibcall"
9525 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9526 (match_operand 1 "" ""))
9527 (match_operand 2 "" "")
9528 (use (reg:PSI FPSCR_REG))
9534 operands[0] = shmedia_prepare_call_address (operands[0], 1);
9535 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9538 else if (TARGET_SHCOMPACT && operands[2]
9539 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9541 rtx cookie_rtx = operands[2];
9542 long cookie = INTVAL (cookie_rtx);
9543 rtx func = XEXP (operands[0], 0);
9548 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9550 rtx reg = gen_reg_rtx (Pmode);
9552 emit_insn (gen_symGOT2reg (reg, func));
9556 func = legitimize_pic_address (func, Pmode, 0);
9559 /* FIXME: if we could tell whether all argument registers are
9560 already taken, we could decide whether to force the use of
9561 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9562 simple way to tell. We could use the CALL_COOKIE, but we
9563 can't currently tell a register used for regular argument
9564 passing from one that is unused. If we leave it up to reload
9565 to decide which register to use, it seems to always choose
9566 R0_REG, which leaves no available registers in SIBCALL_REGS
9567 to hold the address of the trampoline. */
9568 mach = gen_rtx_REG (SImode, MACH_REG);
9569 r1 = gen_rtx_REG (SImode, R1_REG);
9571 /* Since such a call function may use all call-clobbered
9572 registers, we force a mode switch earlier, so that we don't
9573 run out of registers when adjusting fpscr for the call. */
9574 emit_insn (gen_force_mode_for_call ());
9577 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9578 operands[0] = force_reg (SImode, operands[0]);
9580 /* We don't need a return trampoline, since the callee will
9581 return directly to the upper caller. */
9582 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9584 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9585 cookie_rtx = GEN_INT (cookie);
9588 emit_move_insn (mach, func);
9589 emit_move_insn (r1, cookie_rtx);
9591 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9594 else if (TARGET_SHCOMPACT && flag_pic
9595 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9596 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9598 rtx reg = gen_reg_rtx (Pmode);
9600 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9601 XEXP (operands[0], 0) = reg;
9603 if (flag_pic && TARGET_SH2
9604 && MEM_P (operands[0])
9605 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9606 /* The PLT needs the PIC register, but the epilogue would have
9607 to restore it, so we can only use PC-relative PIC calls for
9608 static functions. */
9609 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9611 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9615 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9617 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9621 (define_insn "sibcall_valuei"
9622 [(set (match_operand 0 "" "=rf")
9623 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9624 (match_operand 2 "" "")))
9625 (use (reg:PSI FPSCR_REG))
9629 [(set_attr "needs_delay_slot" "yes")
9630 (set (attr "fp_mode")
9631 (if_then_else (eq_attr "fpu_single" "yes")
9632 (const_string "single") (const_string "double")))
9633 (set_attr "type" "jump_ind")])
9635 (define_insn "sibcall_valuei_pcrel"
9636 [(set (match_operand 0 "" "=rf")
9637 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9638 (match_operand 2 "" "")))
9639 (use (match_operand 3 "" ""))
9640 (use (reg:PSI FPSCR_REG))
9644 return "braf %1" "\n"
9647 [(set_attr "needs_delay_slot" "yes")
9648 (set (attr "fp_mode")
9649 (if_then_else (eq_attr "fpu_single" "yes")
9650 (const_string "single") (const_string "double")))
9651 (set_attr "type" "jump_ind")])
9653 (define_insn_and_split "sibcall_value_pcrel"
9654 [(set (match_operand 0 "" "=rf")
9655 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9656 (match_operand 2 "" "")))
9657 (use (reg:PSI FPSCR_REG))
9658 (clobber (match_scratch:SI 3 "=k"))
9665 rtx lab = PATTERN (gen_call_site ());
9668 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9669 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9673 SIBLING_CALL_P (call_insn) = 1;
9676 [(set_attr "needs_delay_slot" "yes")
9677 (set (attr "fp_mode")
9678 (if_then_else (eq_attr "fpu_single" "yes")
9679 (const_string "single") (const_string "double")))
9680 (set_attr "type" "jump_ind")])
9682 (define_insn "sibcall_value_compact"
9683 [(set (match_operand 0 "" "=rf,rf")
9684 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9685 (match_operand 2 "" "")))
9687 (use (match_operand:SI 3 "register_operand" "z,x"))
9688 (use (reg:SI R1_REG))
9689 (use (reg:PSI FPSCR_REG))
9690 ;; We want to make sure the `x' above will only match MACH_REG
9691 ;; because sibcall_epilogue may clobber MACL_REG.
9692 (clobber (reg:SI MACL_REG))]
9695 static const char* alt[] =
9702 return alt[which_alternative];
9704 [(set_attr "needs_delay_slot" "yes,no")
9705 (set_attr "length" "2,4")
9706 (set (attr "fp_mode") (const_string "single"))
9707 (set_attr "type" "jump_ind")])
9709 (define_insn "sibcall_value_media"
9710 [(set (match_operand 0 "" "=rf")
9711 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9712 (match_operand 2 "" "")))
9713 (use (reg:SI PR_MEDIA_REG))
9717 [(set_attr "type" "jump_media")])
9719 (define_expand "sibcall_value"
9721 [(set (match_operand 0 "arith_reg_operand" "")
9722 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9723 (match_operand 2 "" "")))
9724 (match_operand 3 "" "")
9725 (use (reg:PSI FPSCR_REG))
9731 operands[1] = shmedia_prepare_call_address (operands[1], 1);
9732 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9736 else if (TARGET_SHCOMPACT && operands[3]
9737 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9739 rtx cookie_rtx = operands[3];
9740 long cookie = INTVAL (cookie_rtx);
9741 rtx func = XEXP (operands[1], 0);
9746 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9748 rtx reg = gen_reg_rtx (Pmode);
9750 emit_insn (gen_symGOT2reg (reg, func));
9754 func = legitimize_pic_address (func, Pmode, 0);
9757 /* FIXME: if we could tell whether all argument registers are
9758 already taken, we could decide whether to force the use of
9759 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9760 simple way to tell. We could use the CALL_COOKIE, but we
9761 can't currently tell a register used for regular argument
9762 passing from one that is unused. If we leave it up to reload
9763 to decide which register to use, it seems to always choose
9764 R0_REG, which leaves no available registers in SIBCALL_REGS
9765 to hold the address of the trampoline. */
9766 mach = gen_rtx_REG (SImode, MACH_REG);
9767 r1 = gen_rtx_REG (SImode, R1_REG);
9769 /* Since such a call function may use all call-clobbered
9770 registers, we force a mode switch earlier, so that we don't
9771 run out of registers when adjusting fpscr for the call. */
9772 emit_insn (gen_force_mode_for_call ());
9775 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9776 operands[1] = force_reg (SImode, operands[1]);
9778 /* We don't need a return trampoline, since the callee will
9779 return directly to the upper caller. */
9780 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9782 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9783 cookie_rtx = GEN_INT (cookie);
9786 emit_move_insn (mach, func);
9787 emit_move_insn (r1, cookie_rtx);
9789 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9790 operands[2], mach));
9793 else if (TARGET_SHCOMPACT && flag_pic
9794 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9795 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9797 rtx reg = gen_reg_rtx (Pmode);
9799 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9800 XEXP (operands[1], 0) = reg;
9802 if (flag_pic && TARGET_SH2
9803 && MEM_P (operands[1])
9804 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9805 /* The PLT needs the PIC register, but the epilogue would have
9806 to restore it, so we can only use PC-relative PIC calls for
9807 static functions. */
9808 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9810 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9811 XEXP (operands[1], 0),
9816 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9818 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9822 (define_insn "call_value_pop_compact"
9823 [(set (match_operand 0 "" "=rf")
9824 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9825 (match_operand 2 "" "")))
9826 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9827 (match_operand 4 "immediate_operand" "n")))
9828 (match_operand 3 "immediate_operand" "n")
9829 (use (reg:SI R0_REG))
9830 (use (reg:SI R1_REG))
9831 (use (reg:PSI FPSCR_REG))
9832 (clobber (reg:SI PR_REG))]
9833 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9835 [(set_attr "type" "call")
9836 (set (attr "fp_mode")
9837 (if_then_else (eq_attr "fpu_single" "yes")
9838 (const_string "single") (const_string "double")))
9839 (set_attr "needs_delay_slot" "yes")])
9841 (define_insn "call_value_pop_compact_rettramp"
9842 [(set (match_operand 0 "" "=rf")
9843 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9844 (match_operand 2 "" "")))
9845 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9846 (match_operand 4 "immediate_operand" "n")))
9847 (match_operand 3 "immediate_operand" "n")
9848 (use (reg:SI R0_REG))
9849 (use (reg:SI R1_REG))
9850 (use (reg:PSI FPSCR_REG))
9851 (clobber (reg:SI R10_REG))
9852 (clobber (reg:SI PR_REG))]
9853 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9855 [(set_attr "type" "call")
9856 (set (attr "fp_mode")
9857 (if_then_else (eq_attr "fpu_single" "yes")
9858 (const_string "single") (const_string "double")))
9859 (set_attr "needs_delay_slot" "yes")])
9861 (define_expand "call_value_pop"
9862 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9863 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9864 (match_operand 2 "" "")))
9865 (match_operand 3 "" "")
9866 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9867 (match_operand 4 "" "")))])]
9875 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
9876 cookie_rtx = operands[3];
9877 cookie = INTVAL (cookie_rtx);
9878 func = XEXP (operands[1], 0);
9882 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9884 rtx reg = gen_reg_rtx (Pmode);
9886 emit_insn (gen_symGOTPLT2reg (reg, func));
9890 func = legitimize_pic_address (func, Pmode, 0);
9893 r0 = gen_rtx_REG (SImode, R0_REG);
9894 r1 = gen_rtx_REG (SImode, R1_REG);
9896 /* Since such a call function may use all call-clobbered
9897 registers, we force a mode switch earlier, so that we don't
9898 run out of registers when adjusting fpscr for the call. */
9899 emit_insn (gen_force_mode_for_call ());
9901 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9903 operands[1] = force_reg (SImode, operands[1]);
9905 emit_move_insn (r0, func);
9906 emit_move_insn (r1, cookie_rtx);
9908 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9909 emit_call_insn (gen_call_value_pop_compact_rettramp
9910 (operands[0], operands[1], operands[2],
9911 operands[3], operands[4]));
9913 emit_call_insn (gen_call_value_pop_compact
9914 (operands[0], operands[1], operands[2],
9915 operands[3], operands[4]));
9920 (define_expand "sibcall_epilogue"
9924 sh_expand_epilogue (true);
9925 if (TARGET_SHCOMPACT)
9929 /* If epilogue clobbers r0, preserve it in macl. */
9930 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9931 if ((set = single_set (insn))
9932 && REG_P (SET_DEST (set))
9933 && REGNO (SET_DEST (set)) == R0_REG)
9935 rtx r0 = gen_rtx_REG (SImode, R0_REG);
9936 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
9938 /* We can't tell at this point whether the sibcall is a
9939 sibcall_compact and, if it is, whether it uses r0 or
9940 mach as operand 2, so let the instructions that
9941 preserve r0 be optimized away if r0 turns out to be
9943 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
9944 emit_move_insn (r0, tmp);
9951 (define_insn "indirect_jump_compact"
9953 (match_operand:SI 0 "arith_reg_operand" "r"))]
9956 [(set_attr "needs_delay_slot" "yes")
9957 (set_attr "type" "jump_ind")])
9959 (define_expand "indirect_jump"
9961 (match_operand 0 "register_operand" ""))]
9964 if (GET_MODE (operands[0]) != Pmode)
9965 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
9968 ;; The use of operand 1 / 2 helps us distinguish case table jumps
9969 ;; which can be present in structured code from indirect jumps which can not
9970 ;; be present in structured code. This allows -fprofile-arcs to work.
9972 ;; For SH1 processors.
9973 (define_insn "casesi_jump_1"
9975 (match_operand:SI 0 "register_operand" "r"))
9976 (use (label_ref (match_operand 1 "" "")))]
9979 [(set_attr "needs_delay_slot" "yes")
9980 (set_attr "type" "jump_ind")])
9982 ;; For all later processors.
9983 (define_insn "casesi_jump_2"
9984 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
9985 (label_ref (match_operand 1 "" ""))))
9986 (use (label_ref (match_operand 2 "" "")))]
9988 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
9990 [(set_attr "needs_delay_slot" "yes")
9991 (set_attr "type" "jump_ind")])
9993 (define_insn "casesi_jump_media"
9994 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
9995 (use (label_ref (match_operand 1 "" "")))]
9998 [(set_attr "type" "jump_media")])
10000 ;; Call subroutine returning any type.
10001 ;; ??? This probably doesn't work.
10002 (define_expand "untyped_call"
10003 [(parallel [(call (match_operand 0 "" "")
10005 (match_operand 1 "" "")
10006 (match_operand 2 "" "")])]
10007 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
10009 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10011 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10013 rtx set = XVECEXP (operands[2], 0, i);
10014 emit_move_insn (SET_DEST (set), SET_SRC (set));
10017 /* The optimizer does not know that the call sets the function value
10018 registers we stored in the result block. We avoid problems by
10019 claiming that all hard registers are used and clobbered at this
10021 emit_insn (gen_blockage ());
10026 ;; ------------------------------------------------------------------------
10028 ;; ------------------------------------------------------------------------
10030 (define_insn "dect"
10031 [(set (reg:SI T_REG)
10032 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
10033 (set (match_operand:SI 0 "arith_reg_dest" "=r")
10034 (plus:SI (match_dup 1) (const_int -1)))]
10037 [(set_attr "type" "arith")])
10044 ;; Load address of a label. This is only generated by the casesi expand,
10045 ;; and by machine_dependent_reorg (fixing up fp moves).
10046 ;; This must use unspec, because this only works for labels that are
10048 (define_insn "mova"
10049 [(set (reg:SI R0_REG)
10050 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
10053 [(set_attr "in_delay_slot" "no")
10054 (set_attr "type" "arith")])
10056 ;; machine_dependent_reorg will make this a `mova'.
10057 (define_insn "mova_const"
10058 [(set (reg:SI R0_REG)
10059 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
10062 [(set_attr "in_delay_slot" "no")
10063 (set_attr "type" "arith")])
10065 (define_expand "GOTaddr2picreg"
10066 [(set (reg:SI R0_REG)
10067 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
10069 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
10070 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10073 if (TARGET_VXWORKS_RTP)
10075 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
10076 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
10077 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
10081 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
10082 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
10084 if (TARGET_SHMEDIA)
10086 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
10087 rtx pic = operands[0];
10088 rtx lab = PATTERN (gen_call_site ());
10091 equiv = operands[1];
10092 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
10093 UNSPEC_PCREL_SYMOFF);
10094 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
10096 if (Pmode == SImode)
10098 emit_insn (gen_movsi_const (pic, operands[1]));
10099 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
10103 emit_insn (gen_movdi_const (pic, operands[1]));
10104 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
10107 insn = emit_move_insn (operands[0], tr);
10109 set_unique_reg_note (insn, REG_EQUAL, equiv);
10115 ;; A helper for GOTaddr2picreg to finish up the initialization of the
10117 (define_expand "vxworks_picreg"
10118 [(set (reg:SI PIC_REG)
10119 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
10120 (set (reg:SI R0_REG)
10121 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
10122 (set (reg:SI PIC_REG)
10123 (mem:SI (reg:SI PIC_REG)))
10124 (set (reg:SI PIC_REG)
10125 (mem:SI (plus:SI (reg:SI PIC_REG)
10126 (reg:SI R0_REG))))]
10127 "TARGET_VXWORKS_RTP")
10129 (define_insn "*ptb"
10130 [(set (match_operand 0 "target_reg_operand" "=b")
10131 (const (unspec [(match_operand 1 "" "Csy")]
10132 UNSPEC_DATALABEL)))]
10133 "TARGET_SHMEDIA && flag_pic
10134 && satisfies_constraint_Csy (operands[1])"
10135 "ptb/u datalabel %1, %0"
10136 [(set_attr "type" "ptabs_media")
10137 (set_attr "length" "*")])
10139 (define_insn "ptrel_si"
10140 [(set (match_operand:SI 0 "target_reg_operand" "=b")
10141 (plus:SI (match_operand:SI 1 "register_operand" "r")
10143 (match_operand:SI 2 "" "")]
10145 "%O2: ptrel/u %1, %0"
10146 [(set_attr "type" "ptabs_media")])
10148 (define_insn "ptrel_di"
10149 [(set (match_operand:DI 0 "target_reg_operand" "=b")
10150 (plus:DI (match_operand:DI 1 "register_operand" "r")
10152 (match_operand:DI 2 "" "")]
10154 "%O2: ptrel/u %1, %0"
10155 [(set_attr "type" "ptabs_media")])
10157 (define_expand "builtin_setjmp_receiver"
10158 [(match_operand 0 "" "")]
10161 emit_insn (gen_GOTaddr2picreg ());
10165 (define_expand "call_site"
10166 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
10169 static HOST_WIDE_INT i = 0;
10170 operands[0] = GEN_INT (i);
10174 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
10175 ;; in symGOT_load expand.
10176 (define_insn_and_split "chk_guard_add"
10177 [(set (match_operand:SI 0 "register_operand" "=&r")
10178 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
10183 "TARGET_SH1 && reload_completed"
10184 [(set (match_dup 0) (reg:SI PIC_REG))
10185 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
10187 [(set_attr "type" "arith")])
10189 (define_expand "sym_label2reg"
10190 [(set (match_operand:SI 0 "" "")
10191 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
10192 (const (plus:SI (match_operand:SI 2 "" "")
10197 (define_expand "symGOT_load"
10198 [(set (match_dup 2) (match_operand 1 "" ""))
10199 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
10200 (set (match_operand 0 "" "") (mem (match_dup 3)))]
10205 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10206 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
10208 if (TARGET_SHMEDIA)
10210 rtx reg = operands[2];
10212 if (Pmode == DImode)
10215 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
10217 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
10222 emit_insn (gen_movsi_const (reg, operands[1]));
10224 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
10228 emit_move_insn (operands[2], operands[1]);
10230 /* When stack protector inserts codes after the result is set to
10231 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
10232 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
10233 when rX is a GOT address for the guard symbol. Ugly but doesn't
10234 matter because this is a rare situation. */
10235 if (!TARGET_SHMEDIA
10236 && flag_stack_protect
10237 && GET_CODE (operands[1]) == CONST
10238 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
10239 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
10240 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
10241 "__stack_chk_guard") == 0)
10242 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
10244 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
10245 gen_rtx_REG (Pmode, PIC_REG)));
10247 /* N.B. This is not constant for a GOTPLT relocation. */
10248 mem = gen_rtx_MEM (Pmode, operands[3]);
10249 MEM_NOTRAP_P (mem) = 1;
10250 /* ??? Should we have a special alias set for the GOT? */
10251 emit_move_insn (operands[0], mem);
10256 (define_expand "sym2GOT"
10257 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
10261 (define_expand "symGOT2reg"
10262 [(match_operand 0 "" "") (match_operand 1 "" "")]
10267 gotsym = gen_sym2GOT (operands[1]);
10268 PUT_MODE (gotsym, Pmode);
10269 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
10271 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
10276 (define_expand "symGOTPLT2reg"
10277 [(match_operand 0 "" "") (match_operand 1 "" "")]
10280 rtx pltsym = gen_rtx_CONST (Pmode,
10281 gen_rtx_UNSPEC (Pmode,
10282 gen_rtvec (1, operands[1]),
10284 emit_insn (gen_symGOT_load (operands[0], pltsym));
10288 (define_expand "sym2GOTOFF"
10289 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10293 (define_expand "symGOTOFF2reg"
10294 [(match_operand 0 "" "") (match_operand 1 "" "")]
10297 rtx gotoffsym, insn;
10298 rtx t = (!can_create_pseudo_p ()
10300 : gen_reg_rtx (GET_MODE (operands[0])));
10302 gotoffsym = gen_sym2GOTOFF (operands[1]);
10303 PUT_MODE (gotoffsym, Pmode);
10304 emit_move_insn (t, gotoffsym);
10305 insn = emit_move_insn (operands[0],
10306 gen_rtx_PLUS (Pmode, t,
10307 gen_rtx_REG (Pmode, PIC_REG)));
10309 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10314 (define_expand "symPLT_label2reg"
10315 [(set (match_operand:SI 0 "" "")
10318 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10319 (const:SI (plus:SI (match_operand:SI 2 "" "")
10320 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10321 ;; Even though the PIC register is not really used by the call
10322 ;; sequence in which this is expanded, the PLT code assumes the PIC
10323 ;; register is set, so we must not skip its initialization. Since
10324 ;; we only use this expand as part of calling sequences, and never
10325 ;; to take the address of a function, this is the best point to
10326 ;; insert the (use). Using the PLT to take the address of a
10327 ;; function would be wrong, not only because the PLT entry could
10328 ;; then be called from a function that doesn't initialize the PIC
10329 ;; register to the proper GOT, but also because pointers to the
10330 ;; same function might not compare equal, should they be set by
10331 ;; different shared libraries.
10332 (use (reg:SI PIC_REG))]
10336 (define_expand "sym2PIC"
10337 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10341 ;; -------------------------------------------------------------------------
10342 ;; TLS code generation.
10344 ;; FIXME: The multi-insn asm blocks should be converted to use
10345 ;; define_insn_and_split.
10346 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10347 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10350 (define_insn "tls_global_dynamic"
10351 [(set (match_operand:SI 0 "register_operand" "=&z")
10352 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10355 (use (reg:PSI FPSCR_REG))
10356 (use (reg:SI PIC_REG))
10357 (clobber (reg:SI PR_REG))
10358 (clobber (scratch:SI))]
10361 return "mov.l 1f,r4" "\n"
10363 " mov.l 2f,r1" "\n"
10370 "1: .long %a1@TLSGD" "\n"
10371 "2: .long __tls_get_addr@PLT" "\n"
10374 [(set_attr "type" "tls_load")
10375 (set_attr "length" "26")])
10377 (define_insn "tls_local_dynamic"
10378 [(set (match_operand:SI 0 "register_operand" "=&z")
10379 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10382 (use (reg:PSI FPSCR_REG))
10383 (use (reg:SI PIC_REG))
10384 (clobber (reg:SI PR_REG))
10385 (clobber (scratch:SI))]
10388 return "mov.l 1f,r4" "\n"
10390 " mov.l 2f,r1" "\n"
10397 "1: .long %a1@TLSLDM" "\n"
10398 "2: .long __tls_get_addr@PLT" "\n"
10401 [(set_attr "type" "tls_load")
10402 (set_attr "length" "26")])
10404 (define_expand "sym2DTPOFF"
10405 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10409 (define_expand "symDTPOFF2reg"
10410 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10414 rtx t = (!can_create_pseudo_p ()
10416 : gen_reg_rtx (GET_MODE (operands[0])));
10418 dtpoffsym = gen_sym2DTPOFF (operands[1]);
10419 PUT_MODE (dtpoffsym, Pmode);
10420 emit_move_insn (t, dtpoffsym);
10421 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10425 (define_expand "sym2GOTTPOFF"
10426 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10430 (define_insn "tls_initial_exec"
10431 [(set (match_operand:SI 0 "register_operand" "=&r")
10432 (unspec:SI [(match_operand:SI 1 "" "")]
10434 (use (reg:SI GBR_REG))
10435 (use (reg:SI PIC_REG))
10436 (clobber (reg:SI R0_REG))]
10439 return "mov.l 1f,r0" "\n"
10441 " mov.l @(r0,r12),r0" "\n"
10445 "1: .long %a1" "\n"
10448 [(set_attr "type" "tls_load")
10449 (set_attr "length" "16")])
10451 (define_expand "sym2TPOFF"
10452 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10456 (define_expand "symTPOFF2reg"
10457 [(match_operand 0 "" "") (match_operand 1 "" "")]
10462 tpoffsym = gen_sym2TPOFF (operands[1]);
10463 PUT_MODE (tpoffsym, Pmode);
10464 emit_move_insn (operands[0], tpoffsym);
10468 ;;------------------------------------------------------------------------------
10469 ;; Thread pointer getter and setter.
10471 ;; On SH the thread pointer is kept in the GBR.
10472 ;; These patterns are usually expanded from the respective built-in functions.
10473 (define_expand "get_thread_pointersi"
10474 [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10477 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10478 (define_insn "store_gbr"
10479 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10482 [(set_attr "type" "tls_load")])
10484 (define_expand "set_thread_pointersi"
10485 [(set (reg:SI GBR_REG)
10486 (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10490 (define_insn "load_gbr"
10491 [(set (reg:SI GBR_REG)
10492 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10496 [(set_attr "type" "move")])
10498 ;;------------------------------------------------------------------------------
10499 ;; Thread pointer relative memory loads and stores.
10501 ;; On SH there are GBR displacement address modes which can be utilized to
10502 ;; access memory behind the thread pointer.
10503 ;; Since we do not allow using GBR for general purpose memory accesses, these
10504 ;; GBR addressing modes are formed by the combine pass.
10505 ;; This could be done with fewer patterns than below by using a mem predicate
10506 ;; for the GBR mem, but then reload would try to reload addresses with a
10507 ;; zero displacement for some strange reason.
10509 (define_insn "*mov<mode>_gbr_load"
10510 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10511 (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10512 (match_operand:QIHISI 1 "gbr_displacement"))))]
10514 "mov.<bwl> @(%O1,gbr),%0"
10515 [(set_attr "type" "load")])
10517 (define_insn "*mov<mode>_gbr_load"
10518 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10519 (mem:QIHISI (reg:SI GBR_REG)))]
10521 "mov.<bwl> @(0,gbr),%0"
10522 [(set_attr "type" "load")])
10524 (define_insn "*mov<mode>_gbr_load"
10525 [(set (match_operand:SI 0 "register_operand" "=z")
10527 (mem:QIHI (plus:SI (reg:SI GBR_REG)
10528 (match_operand:QIHI 1 "gbr_displacement")))))]
10530 "mov.<bw> @(%O1,gbr),%0"
10531 [(set_attr "type" "load")])
10533 (define_insn "*mov<mode>_gbr_load"
10534 [(set (match_operand:SI 0 "register_operand" "=z")
10535 (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10537 "mov.<bw> @(0,gbr),%0"
10538 [(set_attr "type" "load")])
10540 (define_insn "*mov<mode>_gbr_store"
10541 [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10542 (match_operand:QIHISI 0 "gbr_displacement")))
10543 (match_operand:QIHISI 1 "register_operand" "z"))]
10545 "mov.<bwl> %1,@(%O0,gbr)"
10546 [(set_attr "type" "store")])
10548 (define_insn "*mov<mode>_gbr_store"
10549 [(set (mem:QIHISI (reg:SI GBR_REG))
10550 (match_operand:QIHISI 0 "register_operand" "z"))]
10552 "mov.<bwl> %0,@(0,gbr)"
10553 [(set_attr "type" "store")])
10555 ;; DImode memory accesses have to be split in two SImode accesses.
10556 ;; Split them before reload, so that it gets a better chance to figure out
10557 ;; how to deal with the R0 restriction for the individual SImode accesses.
10558 ;; Do not match this insn during or after reload because it can't be split
10560 (define_insn_and_split "*movdi_gbr_load"
10561 [(set (match_operand:DI 0 "register_operand")
10562 (match_operand:DI 1 "gbr_address_mem"))]
10563 "TARGET_SH1 && can_create_pseudo_p ()"
10566 [(set (match_dup 3) (match_dup 5))
10567 (set (match_dup 4) (match_dup 6))]
10569 /* Swap low/high part load order on little endian, so that the result reg
10570 of the second load can be used better. */
10571 int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10572 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10573 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10574 operands[4 - off] = gen_highpart (SImode, operands[0]);
10575 operands[6 - off] = gen_highpart (SImode, operands[1]);
10578 (define_insn_and_split "*movdi_gbr_store"
10579 [(set (match_operand:DI 0 "gbr_address_mem")
10580 (match_operand:DI 1 "register_operand"))]
10581 "TARGET_SH1 && can_create_pseudo_p ()"
10584 [(set (match_dup 3) (match_dup 5))
10585 (set (match_dup 4) (match_dup 6))]
10587 /* Swap low/high part store order on big endian, so that stores of function
10588 call results can save a reg copy. */
10589 int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10590 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10591 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10592 operands[4 - off] = gen_highpart (SImode, operands[0]);
10593 operands[6 - off] = gen_highpart (SImode, operands[1]);
10596 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10597 ;; in particular when the displacements are in the range of the regular move
10598 ;; insns. Thus, in the first split pass after the combine pass we search
10599 ;; for missed opportunities and try to fix them up ourselves.
10600 ;; If an equivalent GBR address can be determined the load / store is split
10601 ;; into one of the GBR load / store patterns.
10602 ;; All of that must happen before reload (GBR address modes use R0 as the
10603 ;; other operand) and there's no point of doing it if the GBR is not
10604 ;; referenced in a function at all.
10606 [(set (match_operand:QIHISIDI 0 "register_operand")
10607 (match_operand:QIHISIDI 1 "memory_operand"))]
10608 "TARGET_SH1 && !reload_in_progress && !reload_completed
10609 && df_regs_ever_live_p (GBR_REG)"
10610 [(set (match_dup 0) (match_dup 1))]
10612 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10613 if (gbr_mem != NULL_RTX)
10614 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10620 [(set (match_operand:SI 0 "register_operand")
10621 (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10622 "TARGET_SH1 && !reload_in_progress && !reload_completed
10623 && df_regs_ever_live_p (GBR_REG)"
10624 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10626 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10627 if (gbr_mem != NULL_RTX)
10628 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10633 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10634 ;; Split those so that a GBR load can be used.
10636 [(set (match_operand:SI 0 "register_operand")
10637 (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10638 "TARGET_SH2A && !reload_in_progress && !reload_completed
10639 && df_regs_ever_live_p (GBR_REG)"
10640 [(set (match_dup 2) (match_dup 1))
10641 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10643 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10644 if (gbr_mem != NULL_RTX)
10646 operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10647 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10654 [(set (match_operand:QIHISIDI 0 "memory_operand")
10655 (match_operand:QIHISIDI 1 "register_operand"))]
10656 "TARGET_SH1 && !reload_in_progress && !reload_completed
10657 && df_regs_ever_live_p (GBR_REG)"
10658 [(set (match_dup 0) (match_dup 1))]
10660 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10661 if (gbr_mem != NULL_RTX)
10662 operands[0] = replace_equiv_address (operands[0], gbr_mem);
10667 ;;------------------------------------------------------------------------------
10668 ;; case instruction for switch statements.
10670 ;; operand 0 is index
10671 ;; operand 1 is the minimum bound
10672 ;; operand 2 is the maximum bound - minimum bound + 1
10673 ;; operand 3 is CODE_LABEL for the table;
10674 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10675 (define_expand "casesi"
10676 [(match_operand:SI 0 "arith_reg_operand" "")
10677 (match_operand:SI 1 "arith_reg_operand" "")
10678 (match_operand:SI 2 "arith_reg_operand" "")
10679 (match_operand 3 "" "") (match_operand 4 "" "")]
10682 rtx reg = gen_reg_rtx (SImode);
10683 rtx reg2 = gen_reg_rtx (SImode);
10684 if (TARGET_SHMEDIA)
10686 rtx reg = gen_reg_rtx (DImode);
10687 rtx reg2 = gen_reg_rtx (DImode);
10688 rtx reg3 = gen_reg_rtx (Pmode);
10689 rtx reg4 = gen_reg_rtx (Pmode);
10690 rtx reg5 = gen_reg_rtx (Pmode);
10693 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10694 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10695 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10697 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10698 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0],
10700 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10701 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10702 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10703 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10704 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10705 (Pmode, operands[3])));
10706 /* Messy: can we subreg to clean this up? */
10707 if (Pmode == DImode)
10708 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10710 load = gen_casesi_load_media (reg4,
10711 gen_rtx_SUBREG (DImode, reg3, 0),
10712 reg2, operands[3]);
10713 PUT_MODE (SET_SRC (load), Pmode);
10715 /* ??? The following add could be eliminated if we used ptrel. */
10716 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10717 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10721 operands[1] = copy_to_mode_reg (SImode, operands[1]);
10722 operands[2] = copy_to_mode_reg (SImode, operands[2]);
10723 /* If optimizing, casesi_worker depends on the mode of the instruction
10724 before label it 'uses' - operands[3]. */
10725 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10727 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10729 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10731 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10732 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10733 operands[3], but to lab. We will fix this up in
10734 machine_dependent_reorg. */
10739 (define_expand "casesi_0"
10740 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10741 (set (match_dup 4) (minus:SI (match_dup 4)
10742 (match_operand:SI 1 "arith_operand" "")))
10743 (set (reg:SI T_REG)
10744 (gtu:SI (match_dup 4)
10745 (match_operand:SI 2 "arith_reg_operand" "")))
10747 (if_then_else (ne (reg:SI T_REG)
10749 (label_ref (match_operand 3 "" ""))
10754 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10755 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10756 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10757 (define_insn "casesi_worker_0"
10758 [(set (match_operand:SI 0 "register_operand" "=r,r")
10759 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10760 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10761 (clobber (match_scratch:SI 3 "=X,1"))
10762 (clobber (match_scratch:SI 4 "=&z,z"))]
10767 [(set (match_operand:SI 0 "register_operand" "")
10768 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10769 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10770 (clobber (match_scratch:SI 3 ""))
10771 (clobber (match_scratch:SI 4 ""))]
10772 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10773 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10774 (parallel [(set (match_dup 0)
10775 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10776 (label_ref (match_dup 2))] UNSPEC_CASESI))
10777 (clobber (match_dup 3))])
10778 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10780 if (GET_CODE (operands[2]) == CODE_LABEL)
10781 LABEL_NUSES (operands[2])++;
10785 [(set (match_operand:SI 0 "register_operand" "")
10786 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10787 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10788 (clobber (match_scratch:SI 3 ""))
10789 (clobber (match_scratch:SI 4 ""))]
10790 "TARGET_SH2 && reload_completed"
10791 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10792 (parallel [(set (match_dup 0)
10793 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10794 (label_ref (match_dup 2))] UNSPEC_CASESI))
10795 (clobber (match_dup 3))])]
10797 if (GET_CODE (operands[2]) == CODE_LABEL)
10798 LABEL_NUSES (operands[2])++;
10801 (define_insn "casesi_worker_1"
10802 [(set (match_operand:SI 0 "register_operand" "=r,r")
10803 (unspec:SI [(reg:SI R0_REG)
10804 (match_operand:SI 1 "register_operand" "0,r")
10805 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10806 (clobber (match_scratch:SI 3 "=X,1"))]
10809 rtx diff_vec = PATTERN (NEXT_INSN (operands[2]));
10811 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10813 switch (GET_MODE (diff_vec))
10816 return "shll2 %1" "\n"
10817 " mov.l @(r0,%1),%0";
10819 return "add %1,%1" "\n"
10820 " mov.w @(r0,%1),%0";
10822 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10823 return "mov.b @(r0,%1),%0" "\n"
10826 return "mov.b @(r0,%1),%0";
10829 gcc_unreachable ();
10832 [(set_attr "length" "4")])
10834 (define_insn "casesi_worker_2"
10835 [(set (match_operand:SI 0 "register_operand" "=r,r")
10836 (unspec:SI [(reg:SI R0_REG)
10837 (match_operand:SI 1 "register_operand" "0,r")
10838 (label_ref (match_operand 2 "" ""))
10839 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
10840 (clobber (match_operand:SI 4 "" "=X,1"))]
10841 "TARGET_SH2 && reload_completed && flag_pic"
10843 rtx diff_vec = PATTERN (NEXT_INSN (operands[2]));
10844 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10846 switch (GET_MODE (diff_vec))
10849 return "shll2 %1" "\n"
10851 " mova %O3,r0" "\n"
10852 " mov.l @(r0,%1),%0";
10854 return "add %1,%1" "\n"
10856 " mova %O3,r0" "\n"
10857 " mov.w @(r0,%1),%0";
10859 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10860 return "add r0,%1" "\n"
10861 " mova %O3,r0" "\n"
10862 " mov.b @(r0,%1),%0" "\n"
10865 return "add r0,%1" "\n"
10866 " mova %O3,r0" "\n"
10867 " mov.b @(r0,%1),%0";
10869 gcc_unreachable ();
10872 [(set_attr "length" "8")])
10874 (define_insn "casesi_shift_media"
10875 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10876 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
10877 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
10881 rtx diff_vec = PATTERN (NEXT_INSN (operands[2]));
10883 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10885 switch (GET_MODE (diff_vec))
10888 return "shlli %1, 2, %0";
10890 return "shlli %1, 1, %0";
10892 if (rtx_equal_p (operands[0], operands[1]))
10894 return "add %1, r63, %0";
10896 gcc_unreachable ();
10899 [(set_attr "type" "arith_media")])
10901 (define_insn "casesi_load_media"
10902 [(set (match_operand 0 "any_arith_reg_dest" "=r")
10903 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
10904 (match_operand:DI 2 "arith_reg_operand" "r")
10905 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
10908 rtx diff_vec = PATTERN (NEXT_INSN (operands[3]));
10910 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10912 switch (GET_MODE (diff_vec))
10915 return "ldx.l %1, %2, %0";
10918 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10919 return "ldx.uw %1, %2, %0";
10921 return "ldx.w %1, %2, %0";
10923 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10924 return "ldx.ub %1, %2, %0";
10925 return "ldx.b %1, %2, %0";
10927 gcc_unreachable ();
10930 [(set_attr "type" "load_media")])
10932 (define_expand "simple_return"
10934 "sh_can_use_simple_return_p ()")
10936 (define_expand "return"
10938 "reload_completed && epilogue_completed"
10940 if (TARGET_SHMEDIA)
10942 emit_jump_insn (gen_return_media ());
10946 if (TARGET_SHCOMPACT
10947 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
10949 emit_jump_insn (gen_shcompact_return_tramp ());
10954 (define_insn "*<code>_i"
10956 "TARGET_SH1 && ! (TARGET_SHCOMPACT
10957 && (crtl->args.info.call_cookie
10958 & CALL_COOKIE_RET_TRAMP (1)))
10959 && reload_completed
10960 && ! sh_cfun_trap_exit_p ()"
10962 if (TARGET_SH2A && (dbr_sequence_length () == 0)
10963 && !current_function_interrupt)
10968 [(set_attr "type" "return")
10969 (set_attr "needs_delay_slot" "yes")])
10971 ;; trapa has no delay slot.
10972 (define_insn "*return_trapa"
10974 "TARGET_SH1 && !TARGET_SHCOMPACT
10975 && reload_completed"
10977 [(set_attr "type" "return")])
10979 (define_expand "shcompact_return_tramp"
10982 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10984 rtx reg = gen_rtx_REG (Pmode, R0_REG);
10986 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
10987 emit_jump_insn (gen_shcompact_return_tramp_i ());
10991 (define_insn "shcompact_return_tramp_i"
10992 [(parallel [(return) (use (reg:SI R0_REG))])]
10994 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10996 [(set_attr "type" "jump_ind")
10997 (set_attr "needs_delay_slot" "yes")])
10999 (define_insn "return_media_i"
11000 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
11001 "TARGET_SHMEDIA && reload_completed"
11003 [(set_attr "type" "jump_media")])
11005 (define_insn "return_media_rte"
11007 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
11009 [(set_attr "type" "jump_media")])
11011 (define_expand "return_media"
11013 "TARGET_SHMEDIA && reload_completed"
11015 int tr_regno = sh_media_register_for_return ();
11018 if (current_function_interrupt)
11020 emit_jump_insn (gen_return_media_rte ());
11025 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
11027 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
11028 tr_regno = TR0_REG;
11029 tr = gen_rtx_REG (Pmode, tr_regno);
11030 emit_move_insn (tr, r18);
11033 tr = gen_rtx_REG (Pmode, tr_regno);
11035 emit_jump_insn (gen_return_media_i (tr));
11039 (define_insn "shcompact_preserve_incoming_args"
11040 [(set (match_operand:SI 0 "register_operand" "+r")
11041 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
11044 [(set_attr "length" "0")])
11046 (define_insn "shcompact_incoming_args"
11047 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
11048 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
11049 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
11050 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
11051 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
11052 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
11053 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
11054 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
11055 (set (mem:BLK (reg:SI MACL_REG))
11056 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
11057 (use (reg:SI R0_REG))
11058 (clobber (reg:SI R0_REG))
11059 (clobber (reg:SI MACL_REG))
11060 (clobber (reg:SI MACH_REG))
11061 (clobber (reg:SI PR_REG))]
11064 [(set_attr "needs_delay_slot" "yes")])
11066 (define_insn "shmedia_save_restore_regs_compact"
11067 [(set (reg:SI SP_REG)
11068 (plus:SI (reg:SI SP_REG)
11069 (match_operand:SI 0 "immediate_operand" "i")))
11070 (use (reg:SI R0_REG))
11071 (clobber (reg:SI PR_REG))]
11073 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
11074 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
11076 [(set_attr "needs_delay_slot" "yes")])
11078 (define_expand "prologue"
11082 sh_expand_prologue ();
11086 (define_expand "epilogue"
11090 sh_expand_epilogue (false);
11092 || (TARGET_SHCOMPACT
11093 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
11095 emit_jump_insn (gen_return ());
11100 (define_expand "eh_return"
11101 [(use (match_operand 0 "register_operand" ""))]
11104 rtx ra = operands[0];
11106 if (TARGET_SHMEDIA64)
11107 emit_insn (gen_eh_set_ra_di (ra));
11109 emit_insn (gen_eh_set_ra_si (ra));
11114 ;; Clobber the return address on the stack. We can't expand this
11115 ;; until we know where it will be put in the stack frame.
11117 (define_insn "eh_set_ra_si"
11118 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
11120 (clobber (match_scratch:SI 1 "=&r"))]
11121 "! TARGET_SHMEDIA64"
11124 (define_insn "eh_set_ra_di"
11125 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
11127 (clobber (match_scratch:DI 1 "=&r"))]
11132 [(unspec_volatile [(match_operand 0 "register_operand" "")]
11134 (clobber (match_scratch 1 ""))]
11138 sh_set_return_address (operands[0], operands[1]);
11142 (define_insn "blockage"
11143 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11146 [(set_attr "length" "0")])
11148 ;; Define movml instructions for SH2A target. Currently they are
11149 ;; used to push and pop all banked registers only.
11151 (define_insn "movml_push_banked"
11152 [(set (match_operand:SI 0 "register_operand" "=r")
11153 (plus (match_dup 0) (const_int -32)))
11154 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
11155 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
11156 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
11157 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
11158 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
11159 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
11160 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
11161 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
11162 "TARGET_SH2A && REGNO (operands[0]) == 15"
11164 [(set_attr "in_delay_slot" "no")])
11166 (define_insn "movml_pop_banked"
11167 [(set (match_operand:SI 0 "register_operand" "=r")
11168 (plus (match_dup 0) (const_int 32)))
11169 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
11170 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
11171 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
11172 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
11173 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
11174 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
11175 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
11176 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
11177 "TARGET_SH2A && REGNO (operands[0]) == 15"
11179 [(set_attr "in_delay_slot" "no")])
11181 ;; ------------------------------------------------------------------------
11182 ;; Scc instructions
11183 ;; ------------------------------------------------------------------------
11185 (define_insn "movt"
11186 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11187 (match_operand:SI 1 "t_reg_operand"))]
11190 [(set_attr "type" "arith")])
11192 (define_insn "movrt"
11193 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11194 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11197 [(set_attr "type" "arith")])
11199 (define_expand "cstore4_media"
11200 [(set (match_operand:SI 0 "register_operand" "=r")
11201 (match_operator:SI 1 "sh_float_comparison_operator"
11202 [(match_operand 2 "logical_operand" "")
11203 (match_operand 3 "cmp_operand" "")]))]
11206 enum machine_mode mode = GET_MODE (operands[2]);
11207 enum rtx_code code = GET_CODE (operands[1]);
11209 if (mode == VOIDmode)
11210 mode = GET_MODE (operands[3]);
11211 if (operands[2] == const0_rtx)
11213 if (code == EQ || code == NE)
11214 operands[2] = operands[3], operands[3] = const0_rtx;
11217 operands[2] = force_reg (mode, operands[2]);
11218 if (operands[3] != const0_rtx)
11219 operands[3] = force_reg (mode, operands[3]);
11225 swap = invert = !FLOAT_MODE_P (mode);
11230 swap = FLOAT_MODE_P (mode), invert = !swap;
11235 swap = true, invert = false;
11242 swap = invert = false;
11246 swap = invert = true;
11250 gcc_unreachable ();
11255 rtx tem = operands[2];
11256 operands[2] = operands[3];
11258 code = swap_condition (code);
11263 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
11264 code = reverse_condition (code);
11265 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11266 emit_insn (gen_cstore4_media (tem, operands[1],
11267 operands[2], operands[3]));
11270 operands[3] = const0_rtx;
11273 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
11276 (define_expand "cstoresi4"
11277 [(set (match_operand:SI 0 "register_operand" "=r")
11278 (match_operator:SI 1 "comparison_operator"
11279 [(match_operand:SI 2 "cmpsi_operand" "")
11280 (match_operand:SI 3 "arith_operand" "")]))]
11281 "TARGET_SH1 || TARGET_SHMEDIA"
11283 if (TARGET_SHMEDIA)
11285 emit_insn (gen_cstore4_media (operands[0], operands[1],
11286 operands[2], operands[3]));
11290 if (sh_expand_t_scc (operands))
11293 if (! currently_expanding_to_rtl)
11296 sh_emit_compare_and_set (operands, SImode);
11300 (define_expand "cstoredi4"
11301 [(set (match_operand:SI 0 "register_operand" "=r")
11302 (match_operator:SI 1 "comparison_operator"
11303 [(match_operand:DI 2 "arith_operand" "")
11304 (match_operand:DI 3 "arith_operand" "")]))]
11305 "TARGET_SH2 || TARGET_SHMEDIA"
11307 if (TARGET_SHMEDIA)
11309 emit_insn (gen_cstore4_media (operands[0], operands[1],
11310 operands[2], operands[3]));
11314 if (sh_expand_t_scc (operands))
11317 if (! currently_expanding_to_rtl)
11320 sh_emit_compare_and_set (operands, DImode);
11324 ;; Move the complement of the T reg to a reg.
11325 ;; On SH2A the movrt insn can be used.
11326 ;; On anything else than SH2A this has to be done with multiple instructions.
11327 ;; One obvious way would be:
11332 ;; However, this puts pressure on r0 in most cases and thus the following is
11338 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11339 ;; becomes a one instruction operation. Moreover, care must be taken that
11340 ;; the insn can still be combined with inverted compare and branch code
11341 ;; around it. On the other hand, if a function returns the complement of
11342 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11343 ;; lead to better code.
11344 (define_expand "movnegt"
11345 [(set (match_operand:SI 0 "arith_reg_dest" "")
11346 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11350 emit_insn (gen_movrt (operands[0], operands[1]));
11353 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11354 emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11359 (define_insn "movrt_negc"
11360 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11361 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11362 (set (reg:SI T_REG) (const_int 1))
11363 (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11366 [(set_attr "type" "arith")])
11368 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11369 ;; pattern can be used by the combine pass. Using a scratch reg for the
11370 ;; -1 constant results in slightly better register allocations compared to
11371 ;; generating a pseudo reg before reload.
11372 (define_insn_and_split "*movrt_negc"
11373 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11374 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11375 (clobber (match_scratch:SI 2 "=r"))
11376 (clobber (reg:SI T_REG))]
11377 "TARGET_SH1 && ! TARGET_SH2A"
11379 "&& reload_completed"
11380 [(set (match_dup 2) (const_int -1))
11382 [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
11383 (set (reg:SI T_REG) (const_int 1))
11384 (use (match_dup 2))])])
11386 ;; Store the negated T bit in a reg using r0 and xor. This one doesn't
11387 ;; clobber the T bit, which is useful when storing the T bit and the
11388 ;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
11389 ;; Usually we don't want this insn to be matched, except for cases where the
11390 ;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
11391 (define_insn_and_split "movrt_xor"
11392 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11393 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11394 (use (reg:SI T_REG))]
11395 "TARGET_SH1 && !TARGET_SH2A"
11397 "&& reload_completed"
11398 [(set (match_dup 0) (reg:SI T_REG))
11399 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11401 ;; Store the T bit and the negated T bit in two regs in parallel. There is
11402 ;; no real insn to do that, but specifying this pattern will give combine
11403 ;; some opportunities.
11404 (define_insn_and_split "*movt_movrt"
11405 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11406 (match_operand:SI 1 "negt_reg_operand"))
11407 (set (match_operand:SI 2 "arith_reg_dest")
11408 (match_operand:SI 3 "t_reg_operand"))])]
11414 rtx i = TARGET_SH2A
11415 ? gen_movrt (operands[0], get_t_reg_rtx ())
11416 : gen_movrt_xor (operands[0], get_t_reg_rtx ());
11419 emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
11423 (define_insn_and_split "*movt_movrt"
11424 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11425 (match_operand:SI 1 "t_reg_operand"))
11426 (set (match_operand:SI 2 "arith_reg_dest")
11427 (match_operand:SI 3 "negt_reg_operand"))])]
11431 [(parallel [(set (match_dup 2) (match_dup 3))
11432 (set (match_dup 0) (match_dup 1))])])
11434 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11435 ;; T = 1: 0x80000000 -> reg
11436 ;; T = 0: 0x7FFFFFFF -> reg
11437 ;; This works because 0 - 0x80000000 = 0x80000000.
11439 ;; This insn must not match again after it has been split into the constant
11440 ;; load and negc. This is accomplished by the special negc insn that
11441 ;; has a use on the operand.
11442 (define_insn_and_split "*mov_t_msb_neg"
11443 [(set (match_operand:SI 0 "arith_reg_dest")
11444 (minus:SI (const_int -2147483648) ;; 0x80000000
11445 (match_operand 1 "t_reg_operand")))
11446 (clobber (reg:SI T_REG))]
11449 "&& can_create_pseudo_p ()"
11450 [(set (match_dup 2) (const_int -2147483648))
11451 (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11453 (clobber (reg:SI T_REG))
11454 (use (match_dup 2))])]
11456 operands[2] = gen_reg_rtx (SImode);
11459 (define_insn "*mov_t_msb_neg_negc"
11460 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11461 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
11462 (match_operand:SI 2 "t_reg_operand")))
11463 (clobber (reg:SI T_REG))
11464 (use (match_dup 1))]
11467 [(set_attr "type" "arith")])
11469 ;; These are essentially the same as above, but with the inverted T bit.
11470 ;; Combine recognizes the split patterns, but does not take them sometimes
11471 ;; if the T_REG clobber is specified. Instead it tries to split out the
11472 ;; T bit negation. Since these splits are supposed to be taken only by
11473 ;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
11476 [(set (match_operand:SI 0 "arith_reg_dest")
11477 (plus:SI (match_operand 1 "negt_reg_operand")
11478 (const_int 2147483647)))] ;; 0x7fffffff
11479 "TARGET_SH1 && can_create_pseudo_p ()"
11480 [(parallel [(set (match_dup 0)
11481 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11482 (clobber (reg:SI T_REG))])])
11485 [(set (match_operand:SI 0 "arith_reg_dest")
11486 (if_then_else:SI (match_operand 1 "t_reg_operand")
11487 (const_int 2147483647) ;; 0x7fffffff
11488 (const_int -2147483648)))] ;; 0x80000000
11489 "TARGET_SH1 && can_create_pseudo_p ()"
11490 [(parallel [(set (match_dup 0)
11491 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11492 (clobber (reg:SI T_REG))])])
11494 ;; The *negnegt pattern helps the combine pass to figure out how to fold
11495 ;; an explicit double T bit negation.
11496 (define_insn_and_split "*negnegt"
11497 [(set (reg:SI T_REG)
11498 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11504 ;; Store T bit as all zeros or ones in a reg.
11505 (define_insn "mov_neg_si_t"
11506 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11507 (neg:SI (match_operand 1 "t_reg_operand" "")))]
11510 [(set_attr "type" "arith")])
11512 ;; Store negated T bit as all zeros or ones in a reg.
11513 ;; Use the following sequence:
11514 ;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
11515 ;; not Rn,Rn ! Rn = 0 - Rn
11517 [(set (match_operand:SI 0 "arith_reg_dest" "")
11518 (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11520 [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11521 (set (match_dup 0) (not:SI (match_dup 0)))])
11523 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11524 (define_insn_and_split "*movtt"
11525 [(set (reg:SI T_REG)
11526 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11532 ;; Invert the T bit.
11533 ;; On SH2A we can use the nott insn. On anything else this must be done with
11534 ;; multiple insns like:
11537 ;; This requires an additional pseudo. The SH specific sh_treg_combine RTL
11538 ;; pass will look for this insn. Disallow using it if pseudos can't be
11540 (define_insn_and_split "nott"
11541 [(set (reg:SI T_REG)
11542 (xor:SI (match_operand:SI 0 "t_reg_operand") (const_int 1)))]
11543 "TARGET_SH2A || (TARGET_SH1 && can_create_pseudo_p ())"
11545 gcc_assert (TARGET_SH2A);
11548 "! TARGET_SH2A && can_create_pseudo_p ()"
11549 [(set (match_dup 0) (reg:SI T_REG))
11550 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11552 operands[0] = gen_reg_rtx (SImode);
11555 ;; Store T bit as MSB in a reg.
11556 ;; T = 0: 0x00000000 -> reg
11557 ;; T = 1: 0x80000000 -> reg
11558 (define_insn_and_split "*movt_msb"
11559 [(set (match_operand:SI 0 "arith_reg_dest")
11560 (mult:SI (match_operand:SI 1 "t_reg_operand")
11561 (const_int -2147483648))) ;; 0xffffffff80000000
11562 (clobber (reg:SI T_REG))]
11566 [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11568 ;; Store inverted T bit as MSB in a reg.
11569 ;; T = 0: 0x80000000 -> reg
11570 ;; T = 1: 0x00000000 -> reg
11571 ;; On SH2A we can get away without clobbering the T_REG.
11572 (define_insn_and_split "*negt_msb"
11573 [(set (match_operand:SI 0 "arith_reg_dest")
11574 (match_operand:SI 1 "negt_reg_shl31_operand"))]
11577 "&& can_create_pseudo_p ()"
11580 rtx tmp = gen_reg_rtx (SImode);
11581 emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11582 emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11586 (define_insn_and_split "*negt_msb"
11587 [(set (match_operand:SI 0 "arith_reg_dest")
11588 (match_operand:SI 1 "negt_reg_shl31_operand"))
11589 (clobber (reg:SI T_REG))]
11590 "TARGET_SH1 && !TARGET_SH2A"
11592 "&& can_create_pseudo_p ()"
11595 rtx tmp = gen_reg_rtx (SImode);
11596 emit_move_insn (tmp, get_t_reg_rtx ());
11597 emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11598 emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11602 ;; The *cset_zero patterns convert optimizations such as
11603 ;; "if (test) x = 0;"
11605 ;; "x &= -(test == 0);"
11606 ;; back to conditional branch sequences if zero-displacement branches
11608 ;; FIXME: These patterns can be removed when conditional execution patterns
11609 ;; are implemented, since ifcvt will not perform these optimizations if
11610 ;; conditional execution is supported.
11611 (define_insn "*cset_zero"
11612 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11613 (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11615 (match_operand:SI 2 "arith_reg_operand" "0")))]
11616 "TARGET_SH1 && TARGET_ZDCBRANCH"
11618 return "bf 0f" "\n"
11622 [(set_attr "type" "arith") ;; poor approximation
11623 (set_attr "length" "4")])
11625 (define_insn "*cset_zero"
11626 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11627 (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
11628 (match_operand:SI 2 "arith_reg_operand" "0")
11630 "TARGET_SH1 && TARGET_ZDCBRANCH"
11632 return "bt 0f" "\n"
11636 [(set_attr "type" "arith") ;; poor approximation
11637 (set_attr "length" "4")])
11639 (define_expand "cstoresf4"
11640 [(set (match_operand:SI 0 "register_operand" "=r")
11641 (match_operator:SI 1 "sh_float_comparison_operator"
11642 [(match_operand:SF 2 "arith_operand" "")
11643 (match_operand:SF 3 "arith_operand" "")]))]
11644 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11646 if (TARGET_SHMEDIA)
11648 emit_insn (gen_cstore4_media (operands[0], operands[1],
11649 operands[2], operands[3]));
11653 if (! currently_expanding_to_rtl)
11656 sh_emit_compare_and_set (operands, SFmode);
11660 (define_expand "cstoredf4"
11661 [(set (match_operand:SI 0 "register_operand" "=r")
11662 (match_operator:SI 1 "sh_float_comparison_operator"
11663 [(match_operand:DF 2 "arith_operand" "")
11664 (match_operand:DF 3 "arith_operand" "")]))]
11665 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11667 if (TARGET_SHMEDIA)
11669 emit_insn (gen_cstore4_media (operands[0], operands[1],
11670 operands[2], operands[3]));
11674 if (! currently_expanding_to_rtl)
11677 sh_emit_compare_and_set (operands, DFmode);
11681 ;; -------------------------------------------------------------------------
11682 ;; Instructions to cope with inline literal tables
11683 ;; -------------------------------------------------------------------------
11685 ;; 2 byte integer in line
11686 (define_insn "consttable_2"
11687 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11688 (match_operand 1 "" "")]
11692 if (operands[1] != const0_rtx)
11693 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11696 [(set_attr "length" "2")
11697 (set_attr "in_delay_slot" "no")])
11699 ;; 4 byte integer in line
11700 (define_insn "consttable_4"
11701 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11702 (match_operand 1 "" "")]
11706 if (operands[1] != const0_rtx)
11708 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11709 mark_symbol_refs_as_used (operands[0]);
11713 [(set_attr "length" "4")
11714 (set_attr "in_delay_slot" "no")])
11716 ;; 8 byte integer in line
11717 (define_insn "consttable_8"
11718 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11719 (match_operand 1 "" "")]
11723 if (operands[1] != const0_rtx)
11724 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11727 [(set_attr "length" "8")
11728 (set_attr "in_delay_slot" "no")])
11730 ;; 4 byte floating point
11731 (define_insn "consttable_sf"
11732 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11733 (match_operand 1 "" "")]
11737 if (operands[1] != const0_rtx)
11740 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11741 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11745 [(set_attr "length" "4")
11746 (set_attr "in_delay_slot" "no")])
11748 ;; 8 byte floating point
11749 (define_insn "consttable_df"
11750 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11751 (match_operand 1 "" "")]
11755 if (operands[1] != const0_rtx)
11758 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11759 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11763 [(set_attr "length" "8")
11764 (set_attr "in_delay_slot" "no")])
11766 ;; Alignment is needed for some constant tables; it may also be added for
11767 ;; Instructions at the start of loops, or after unconditional branches.
11768 ;; ??? We would get more accurate lengths if we did instruction
11769 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11770 ;; here is too conservative.
11772 ;; align to a two byte boundary
11773 (define_expand "align_2"
11774 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11778 ;; Align to a four byte boundary.
11779 ;; align_4 and align_log are instructions for the starts of loops, or
11780 ;; after unconditional branches, which may take up extra room.
11781 (define_expand "align_4"
11782 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11786 ;; Align to a cache line boundary.
11787 (define_insn "align_log"
11788 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11791 [(set_attr "length" "0")
11792 (set_attr "in_delay_slot" "no")])
11794 ;; Emitted at the end of the literal table, used to emit the
11795 ;; 32bit branch labels if needed.
11796 (define_insn "consttable_end"
11797 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11800 return output_jump_label_table ();
11802 [(set_attr "in_delay_slot" "no")])
11804 ;; Emitted at the end of the window in the literal table.
11805 (define_insn "consttable_window_end"
11806 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11809 [(set_attr "length" "0")
11810 (set_attr "in_delay_slot" "no")])
11812 ;; -------------------------------------------------------------------------
11813 ;; Minimum / maximum operations.
11814 ;; -------------------------------------------------------------------------
11816 ;; The SH2A clips.b and clips.w insns do a signed min-max function. If smin
11817 ;; and smax standard name patterns are defined, they will be used during
11818 ;; initial expansion and combine will then be able to form the actual min-max
11820 ;; The clips.b and clips.w set the SR.CS bit if the value in the register is
11821 ;; clipped, but there is currently no way of making use of this information.
11822 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
11823 (define_expand "<code>si3"
11824 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11825 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
11826 (match_operand 2 "const_int_operand")))
11827 (clobber (reg:SI T_REG))])]
11830 /* Force the comparison value into a register, because greater-than
11831 comparisons can work only on registers. Combine will be able to pick up
11832 the constant value from the REG_EQUAL note when trying to form a min-max
11834 operands[2] = force_reg (SImode, operands[2]);
11838 ;; smax (smin (...))
11840 ;; smin (smax (...))
11841 (define_insn_and_split "*clips"
11842 [(set (match_operand:SI 0 "arith_reg_dest")
11843 (smax:SI (smin:SI (match_operand:SI 1 "arith_reg_operand")
11844 (match_operand 2 "clips_max_const_int"))
11845 (match_operand 3 "clips_min_const_int")))]
11849 [(set (match_dup 0)
11850 (smin:SI (smax:SI (match_dup 1) (match_dup 3)) (match_dup 2)))])
11852 (define_insn "*clips"
11853 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11854 (smin:SI (smax:SI (match_operand:SI 1 "arith_reg_operand" "0")
11855 (match_operand 2 "clips_min_const_int"))
11856 (match_operand 3 "clips_max_const_int")))]
11859 if (INTVAL (operands[3]) == 127)
11860 return "clips.b %0";
11861 else if (INTVAL (operands[3]) == 32767)
11862 return "clips.w %0";
11864 gcc_unreachable ();
11866 [(set_attr "type" "arith")])
11868 ;; If the expanded smin or smax patterns were not combined, split them into
11869 ;; a compare and branch sequence, because there are no real smin or smax
11871 (define_insn_and_split "*<code>si3"
11872 [(set (match_operand:SI 0 "arith_reg_dest")
11873 (SMIN_SMAX:SI (match_operand:SI 1 "arith_reg_operand")
11874 (match_operand:SI 2 "arith_reg_or_0_or_1_operand")))
11875 (clobber (reg:SI T_REG))]
11876 "TARGET_SH2A && can_create_pseudo_p ()"
11881 rtx skip_label = gen_label_rtx ();
11882 emit_move_insn (operands[0], operands[1]);
11884 rtx cmp_val = operands[2];
11885 if (satisfies_constraint_M (cmp_val))
11886 cmp_val = const0_rtx;
11888 emit_insn (gen_cmpgtsi_t (operands[0], cmp_val));
11889 emit_jump_insn (<CODE> == SMIN
11890 ? gen_branch_false (skip_label)
11891 : gen_branch_true (skip_label));
11893 emit_label_after (skip_label, emit_move_insn (operands[0], operands[2]));
11897 ;; The SH2A clipu.b and clipu.w insns can be used to implement a min function
11898 ;; with a register and a constant.
11899 ;; The clipu.b and clipu.w set the SR.CS bit if the value in the register is
11900 ;; clipped, but there is currently no way of making use of this information.
11901 ;; The only way to read or reset the SR.CS bit is by accessing the SR.
11902 (define_expand "uminsi3"
11903 [(set (match_operand:SI 0 "arith_reg_dest")
11904 (umin:SI (match_operand:SI 1 "arith_reg_operand")
11905 (match_operand 2 "const_int_operand")))]
11908 if (INTVAL (operands[2]) == 1)
11910 emit_insn (gen_clipu_one (operands[0], operands[1]));
11913 else if (! clipu_max_const_int (operands[2], VOIDmode))
11917 (define_insn "*clipu"
11918 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11919 (umin:SI (match_operand:SI 1 "arith_reg_operand" "0")
11920 (match_operand 2 "clipu_max_const_int")))]
11923 if (INTVAL (operands[2]) == 255)
11924 return "clipu.b %0";
11925 else if (INTVAL (operands[2]) == 65535)
11926 return "clipu.w %0";
11928 gcc_unreachable ();
11930 [(set_attr "type" "arith")])
11932 (define_insn_and_split "clipu_one"
11933 [(set (match_operand:SI 0 "arith_reg_dest")
11934 (umin:SI (match_operand:SI 1 "arith_reg_operand") (const_int 1)))
11935 (clobber (reg:SI T_REG))]
11938 "&& can_create_pseudo_p ()"
11941 emit_insn (gen_cmpeqsi_t (operands[1], const0_rtx));
11942 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
11946 ;; -------------------------------------------------------------------------
11948 ;; -------------------------------------------------------------------------
11950 ;; String/block move insn.
11952 (define_expand "movmemsi"
11953 [(parallel [(set (mem:BLK (match_operand:BLK 0))
11954 (mem:BLK (match_operand:BLK 1)))
11955 (use (match_operand:SI 2 "nonmemory_operand"))
11956 (use (match_operand:SI 3 "immediate_operand"))
11957 (clobber (reg:SI PR_REG))
11958 (clobber (reg:SI R4_REG))
11959 (clobber (reg:SI R5_REG))
11960 (clobber (reg:SI R0_REG))])]
11961 "TARGET_SH1 && ! TARGET_SH5"
11963 if (expand_block_move (operands))
11969 (define_insn "block_move_real"
11970 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11971 (mem:BLK (reg:SI R5_REG)))
11972 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11973 (clobber (reg:SI PR_REG))
11974 (clobber (reg:SI R0_REG))])]
11975 "TARGET_SH1 && ! TARGET_HARD_SH4"
11977 [(set_attr "type" "sfunc")
11978 (set_attr "needs_delay_slot" "yes")])
11980 (define_insn "block_lump_real"
11981 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11982 (mem:BLK (reg:SI R5_REG)))
11983 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11984 (use (reg:SI R6_REG))
11985 (clobber (reg:SI PR_REG))
11986 (clobber (reg:SI T_REG))
11987 (clobber (reg:SI R4_REG))
11988 (clobber (reg:SI R5_REG))
11989 (clobber (reg:SI R6_REG))
11990 (clobber (reg:SI R0_REG))])]
11991 "TARGET_SH1 && ! TARGET_HARD_SH4"
11993 [(set_attr "type" "sfunc")
11994 (set_attr "needs_delay_slot" "yes")])
11996 (define_insn "block_move_real_i4"
11997 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11998 (mem:BLK (reg:SI R5_REG)))
11999 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12000 (clobber (reg:SI PR_REG))
12001 (clobber (reg:SI R0_REG))
12002 (clobber (reg:SI R1_REG))
12003 (clobber (reg:SI R2_REG))])]
12006 [(set_attr "type" "sfunc")
12007 (set_attr "needs_delay_slot" "yes")])
12009 (define_insn "block_lump_real_i4"
12010 [(parallel [(set (mem:BLK (reg:SI R4_REG))
12011 (mem:BLK (reg:SI R5_REG)))
12012 (use (match_operand:SI 0 "arith_reg_operand" "r"))
12013 (use (reg:SI R6_REG))
12014 (clobber (reg:SI PR_REG))
12015 (clobber (reg:SI T_REG))
12016 (clobber (reg:SI R4_REG))
12017 (clobber (reg:SI R5_REG))
12018 (clobber (reg:SI R6_REG))
12019 (clobber (reg:SI R0_REG))
12020 (clobber (reg:SI R1_REG))
12021 (clobber (reg:SI R2_REG))
12022 (clobber (reg:SI R3_REG))])]
12025 [(set_attr "type" "sfunc")
12026 (set_attr "needs_delay_slot" "yes")])
12028 ;; byte compare pattern
12030 ;; !((temp & 0xF000) && (temp & 0x0F00) && (temp & 0x00F0) && (temp & 0x000F))
12031 (define_insn "cmpstr_t"
12032 [(set (reg:SI T_REG)
12037 (xor:SI (match_operand:SI 0 "arith_reg_operand" "r")
12038 (match_operand:SI 1 "arith_reg_operand" "r"))
12039 (const_int 8) (const_int 0))
12040 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12041 (const_int 8) (const_int 8)))
12042 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12043 (const_int 8) (const_int 16)))
12044 (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
12045 (const_int 8) (const_int 24)))
12049 [(set_attr "type" "mt_group")])
12051 (define_expand "cmpstrsi"
12052 [(set (match_operand:SI 0 "register_operand")
12053 (compare:SI (match_operand:BLK 1 "memory_operand")
12054 (match_operand:BLK 2 "memory_operand")))
12055 (use (match_operand 3 "immediate_operand"))]
12056 "TARGET_SH1 && optimize"
12058 if (! optimize_insn_for_size_p () && sh_expand_cmpstr (operands))
12064 (define_expand "cmpstrnsi"
12065 [(set (match_operand:SI 0 "register_operand")
12066 (compare:SI (match_operand:BLK 1 "memory_operand")
12067 (match_operand:BLK 2 "memory_operand")))
12068 (use (match_operand:SI 3 "immediate_operand"))
12069 (use (match_operand:SI 4 "immediate_operand"))]
12070 "TARGET_SH1 && optimize"
12072 if (! optimize_insn_for_size_p () && sh_expand_cmpnstr (operands))
12078 (define_expand "strlensi"
12079 [(set (match_operand:SI 0 "register_operand")
12080 (unspec:SI [(match_operand:BLK 1 "memory_operand")
12081 (match_operand:SI 2 "immediate_operand")
12082 (match_operand:SI 3 "immediate_operand")]
12083 UNSPEC_BUILTIN_STRLEN))]
12084 "TARGET_SH1 && optimize"
12086 if (! optimize_insn_for_size_p () && sh_expand_strlen (operands))
12093 ;; -------------------------------------------------------------------------
12094 ;; Floating point instructions.
12095 ;; -------------------------------------------------------------------------
12097 ;; ??? All patterns should have a type attribute.
12099 (define_expand "movpsi"
12100 [(set (match_operand:PSI 0 "register_operand" "")
12101 (match_operand:PSI 1 "general_movsrc_operand" ""))]
12102 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12105 ;; The c / m alternative is a fake to guide reload to load directly into
12106 ;; fpscr, since reload doesn't know how to use post-increment.
12107 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
12108 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
12109 ;; predicate after reload.
12110 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
12111 ;; like a mac -> gpr move.
12112 (define_insn "fpu_switch"
12113 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
12114 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
12116 && (! reload_completed
12117 || true_regnum (operands[0]) != FPSCR_REG
12118 || !MEM_P (operands[1])
12119 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
12121 ! precision stays the same
12130 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
12131 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,
12135 [(set (reg:PSI FPSCR_REG)
12136 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
12137 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
12140 rtx fpscr, mem, new_insn;
12142 fpscr = SET_DEST (PATTERN (curr_insn));
12143 mem = SET_SRC (PATTERN (curr_insn));
12144 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
12146 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
12147 add_reg_note (new_insn, REG_INC, operands[0]);
12152 [(set (reg:PSI FPSCR_REG)
12153 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
12154 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
12155 && (flag_peephole2 ? epilogue_completed : reload_completed)"
12158 rtx fpscr, mem, new_insn;
12160 fpscr = SET_DEST (PATTERN (curr_insn));
12161 mem = SET_SRC (PATTERN (curr_insn));
12162 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
12164 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
12165 add_reg_note (new_insn, REG_INC, operands[0]);
12167 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
12168 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
12172 ;; ??? This uses the fp unit, but has no type indicating that.
12173 ;; If we did that, this would either give a bogus latency or introduce
12174 ;; a bogus FIFO constraint.
12175 ;; Since this insn is currently only used for prologues/epilogues,
12176 ;; it is probably best to claim no function unit, which matches the
12177 ;; current setting.
12178 (define_insn "toggle_sz"
12179 [(set (reg:PSI FPSCR_REG)
12180 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
12181 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12183 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
12185 ;; There's no way we can use it today, since optimize mode switching
12186 ;; doesn't enable us to know from which mode we're switching to the
12187 ;; mode it requests, to tell whether we can use a relative mode switch
12188 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
12190 (define_insn "toggle_pr"
12191 [(set (reg:PSI FPSCR_REG)
12192 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
12193 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
12195 [(set_attr "type" "fpscr_toggle")])
12197 (define_expand "addsf3"
12198 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12199 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand")
12200 (match_operand:SF 2 "fp_arith_reg_operand")))]
12201 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12205 expand_sf_binop (&gen_addsf3_i, operands);
12210 (define_insn "*addsf3_media"
12211 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12212 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12213 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12214 "TARGET_SHMEDIA_FPU"
12215 "fadd.s %1, %2, %0"
12216 [(set_attr "type" "fparith_media")])
12218 (define_insn_and_split "unary_sf_op"
12219 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12224 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
12225 (match_operator:SF 2 "unary_float_operator"
12226 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12227 (parallel [(match_operand 4
12228 "const_int_operand" "n")]))]))
12229 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
12230 "TARGET_SHMEDIA_FPU"
12232 "TARGET_SHMEDIA_FPU && reload_completed"
12233 [(set (match_dup 5) (match_dup 6))]
12235 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12236 rtx op1 = gen_rtx_REG (SFmode,
12237 (true_regnum (operands[1])
12238 + (INTVAL (operands[4]) ^ endian)));
12240 operands[7] = gen_rtx_REG (SFmode,
12241 (true_regnum (operands[0])
12242 + (INTVAL (operands[3]) ^ endian)));
12243 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
12245 [(set_attr "type" "fparith_media")])
12247 (define_insn_and_split "binary_sf_op0"
12248 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12250 (match_operator:SF 3 "binary_float_operator"
12251 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12252 (parallel [(const_int 0)]))
12253 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12254 (parallel [(const_int 0)]))])
12257 (parallel [(const_int 1)]))))]
12258 "TARGET_SHMEDIA_FPU"
12260 "&& reload_completed"
12261 [(set (match_dup 4) (match_dup 5))]
12263 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12264 rtx op1 = gen_rtx_REG (SFmode,
12265 true_regnum (operands[1]) + endian);
12266 rtx op2 = gen_rtx_REG (SFmode,
12267 true_regnum (operands[2]) + endian);
12269 operands[4] = gen_rtx_REG (SFmode,
12270 true_regnum (operands[0]) + endian);
12271 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12273 [(set_attr "type" "fparith_media")])
12275 (define_insn_and_split "binary_sf_op1"
12276 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12280 (parallel [(const_int 0)]))
12281 (match_operator:SF 3 "binary_float_operator"
12282 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
12283 (parallel [(const_int 1)]))
12284 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
12285 (parallel [(const_int 1)]))])))]
12286 "TARGET_SHMEDIA_FPU"
12288 "&& reload_completed"
12289 [(set (match_dup 4) (match_dup 5))]
12291 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
12292 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
12293 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
12295 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
12296 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
12298 [(set_attr "type" "fparith_media")])
12300 (define_insn "addsf3_i"
12301 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12302 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12303 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12304 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12307 [(set_attr "type" "fp")
12308 (set_attr "fp_mode" "single")])
12310 (define_expand "subsf3"
12311 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12312 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12313 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12314 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12318 expand_sf_binop (&gen_subsf3_i, operands);
12323 (define_insn "*subsf3_media"
12324 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12325 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12326 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12327 "TARGET_SHMEDIA_FPU"
12328 "fsub.s %1, %2, %0"
12329 [(set_attr "type" "fparith_media")])
12331 (define_insn "subsf3_i"
12332 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12333 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12334 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12335 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12338 [(set_attr "type" "fp")
12339 (set_attr "fp_mode" "single")])
12341 (define_expand "mulsf3"
12342 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12343 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
12344 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
12345 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12349 emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2],
12350 get_fpscr_rtx ()));
12355 (define_insn "*mulsf3_media"
12356 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12357 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12358 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12359 "TARGET_SHMEDIA_FPU"
12360 "fmul.s %1, %2, %0"
12361 [(set_attr "type" "fparith_media")])
12363 (define_insn "mulsf3_i"
12364 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12365 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
12366 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12367 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12370 [(set_attr "type" "fp")
12371 (set_attr "fp_mode" "single")])
12373 ;; FMA (fused multiply-add) patterns
12374 (define_expand "fmasf4"
12375 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12376 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand")
12377 (match_operand:SF 2 "fp_arith_reg_operand")
12378 (match_operand:SF 3 "fp_arith_reg_operand")))]
12379 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12383 emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
12384 operands[3], get_fpscr_rtx ()));
12389 (define_insn "fmasf4_i"
12390 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12391 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
12392 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12393 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
12394 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
12397 [(set_attr "type" "fp")
12398 (set_attr "fp_mode" "single")])
12400 (define_insn "fmasf4_media"
12401 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12402 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12403 (match_operand:SF 2 "fp_arith_reg_operand" "f")
12404 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12405 "TARGET_SHMEDIA_FPU"
12406 "fmac.s %1, %2, %0"
12407 [(set_attr "type" "fparith_media")])
12409 ;; For some cases such as 'a * b + a' the FMA pattern is not generated by
12410 ;; previous transformations. If FMA is generally allowed, let the combine
12411 ;; pass utilize it.
12412 (define_insn_and_split "*fmasf4"
12413 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12414 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
12415 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12416 (match_operand:SF 3 "arith_reg_operand" "0")))
12417 (use (match_operand:PSI 4 "fpscr_operand"))]
12418 "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF"
12420 "&& can_create_pseudo_p ()"
12421 [(parallel [(set (match_dup 0)
12422 (fma:SF (match_dup 1) (match_dup 2) (match_dup 3)))
12423 (use (match_dup 4))])]
12425 /* Change 'b * a + a' into 'a * b + a'.
12426 This is better for register allocation. */
12427 if (REGNO (operands[2]) == REGNO (operands[3]))
12429 rtx tmp = operands[1];
12430 operands[1] = operands[2];
12434 [(set_attr "type" "fp")
12435 (set_attr "fp_mode" "single")])
12437 (define_insn "*fmasf4_media"
12438 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12439 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
12440 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
12441 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
12442 "TARGET_SHMEDIA_FPU && flag_fp_contract_mode != FP_CONTRACT_OFF"
12443 "fmac.s %1, %2, %0"
12444 [(set_attr "type" "fparith_media")])
12446 (define_expand "divsf3"
12447 [(set (match_operand:SF 0 "fp_arith_reg_operand")
12448 (div:SF (match_operand:SF 1 "fp_arith_reg_operand")
12449 (match_operand:SF 2 "fp_arith_reg_operand")))]
12450 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12454 expand_sf_binop (&gen_divsf3_i, operands);
12459 (define_insn "*divsf3_media"
12460 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12461 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
12462 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12463 "TARGET_SHMEDIA_FPU"
12464 "fdiv.s %1, %2, %0"
12465 [(set_attr "type" "fdiv_media")])
12467 (define_insn "divsf3_i"
12468 [(set (match_operand:SF 0 "fp_arith_reg_dest" "=f")
12469 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
12470 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
12471 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12474 [(set_attr "type" "fdiv")
12475 (set_attr "fp_mode" "single")])
12477 (define_insn "floatdisf2"
12478 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12479 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12480 "TARGET_SHMEDIA_FPU"
12482 [(set_attr "type" "fpconv_media")])
12484 (define_expand "floatsisf2"
12485 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12486 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
12487 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12489 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12491 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1],
12492 get_fpscr_rtx ()));
12497 (define_insn "*floatsisf2_media"
12498 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12499 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12500 "TARGET_SHMEDIA_FPU"
12502 [(set_attr "type" "fpconv_media")])
12504 (define_insn "floatsisf2_i4"
12505 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12506 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
12507 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12508 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12510 [(set_attr "type" "fp")
12511 (set_attr "fp_mode" "single")])
12513 (define_insn "*floatsisf2_ie"
12514 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12515 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
12516 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12518 [(set_attr "type" "fp")])
12520 (define_insn "fix_truncsfdi2"
12521 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12522 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12523 "TARGET_SHMEDIA_FPU"
12525 [(set_attr "type" "fpconv_media")])
12527 (define_expand "fix_truncsfsi2"
12528 [(set (match_operand:SI 0 "fpul_operand" "=y")
12529 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12530 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12532 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
12534 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1],
12535 get_fpscr_rtx ()));
12540 (define_insn "*fix_truncsfsi2_media"
12541 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12542 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12543 "TARGET_SHMEDIA_FPU"
12545 [(set_attr "type" "fpconv_media")])
12547 (define_insn "fix_truncsfsi2_i4"
12548 [(set (match_operand:SI 0 "fpul_operand" "=y")
12549 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12550 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12551 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12553 [(set_attr "type" "ftrc_s")
12554 (set_attr "fp_mode" "single")])
12556 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
12557 ;; fix_truncsfsi2_i4.
12558 ;; (define_insn "fix_truncsfsi2_i4_2"
12559 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12560 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12561 ;; (use (reg:PSI FPSCR_REG))
12562 ;; (clobber (reg:SI FPUL_REG))]
12565 ;; [(set_attr "length" "4")
12566 ;; (set_attr "fp_mode" "single")])
12569 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12570 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12571 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12572 ;; (clobber (reg:SI FPUL_REG))]
12574 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12575 ;; (use (match_dup 2))])
12576 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
12578 (define_insn "*fixsfsi"
12579 [(set (match_operand:SI 0 "fpul_operand" "=y")
12580 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12581 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12583 [(set_attr "type" "fp")])
12585 (define_insn "cmpgtsf_t"
12586 [(set (reg:SI T_REG)
12587 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12588 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12589 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12591 [(set_attr "type" "fp_cmp")
12592 (set_attr "fp_mode" "single")])
12594 (define_insn "cmpeqsf_t"
12595 [(set (reg:SI T_REG)
12596 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12597 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12598 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12600 [(set_attr "type" "fp_cmp")
12601 (set_attr "fp_mode" "single")])
12603 (define_insn "ieee_ccmpeqsf_t"
12604 [(set (reg:SI T_REG)
12605 (ior:SI (reg:SI T_REG)
12606 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12607 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
12608 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12610 return output_ieee_ccmpeq (insn, operands);
12612 [(set_attr "length" "4")])
12615 (define_insn "cmpgtsf_t_i4"
12616 [(set (reg:SI T_REG)
12617 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12618 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12619 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12620 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12622 [(set_attr "type" "fp_cmp")
12623 (set_attr "fp_mode" "single")])
12625 (define_insn "cmpeqsf_t_i4"
12626 [(set (reg:SI T_REG)
12627 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12628 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12629 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12630 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12632 [(set_attr "type" "fp_cmp")
12633 (set_attr "fp_mode" "single")])
12635 (define_insn "*ieee_ccmpeqsf_t_4"
12636 [(set (reg:SI T_REG)
12637 (ior:SI (reg:SI T_REG)
12638 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12639 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12640 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12641 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12643 return output_ieee_ccmpeq (insn, operands);
12645 [(set_attr "length" "4")
12646 (set_attr "fp_mode" "single")])
12648 (define_insn "cmpeqsf_media"
12649 [(set (match_operand:SI 0 "register_operand" "=r")
12650 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12651 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12652 "TARGET_SHMEDIA_FPU"
12653 "fcmpeq.s %1, %2, %0"
12654 [(set_attr "type" "fcmp_media")])
12656 (define_insn "cmpgtsf_media"
12657 [(set (match_operand:SI 0 "register_operand" "=r")
12658 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12659 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12660 "TARGET_SHMEDIA_FPU"
12661 "fcmpgt.s %1, %2, %0"
12662 [(set_attr "type" "fcmp_media")])
12664 (define_insn "cmpgesf_media"
12665 [(set (match_operand:SI 0 "register_operand" "=r")
12666 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12667 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12668 "TARGET_SHMEDIA_FPU"
12669 "fcmpge.s %1, %2, %0"
12670 [(set_attr "type" "fcmp_media")])
12672 (define_insn "cmpunsf_media"
12673 [(set (match_operand:SI 0 "register_operand" "=r")
12674 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12675 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12676 "TARGET_SHMEDIA_FPU"
12677 "fcmpun.s %1, %2, %0"
12678 [(set_attr "type" "fcmp_media")])
12680 (define_expand "cbranchsf4"
12682 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12683 [(match_operand:SF 1 "arith_operand" "")
12684 (match_operand:SF 2 "arith_operand" "")])
12685 (match_operand 3 "" "")
12687 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12689 if (TARGET_SHMEDIA)
12690 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12693 sh_emit_compare_and_branch (operands, SFmode);
12697 (define_expand "negsf2"
12698 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12699 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12700 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12704 expand_sf_unop (&gen_negsf2_i, operands);
12709 (define_insn "*negsf2_media"
12710 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12711 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12712 "TARGET_SHMEDIA_FPU"
12714 [(set_attr "type" "fmove_media")])
12716 (define_insn "negsf2_i"
12717 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12718 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12719 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12722 [(set_attr "type" "fmove")
12723 (set_attr "fp_mode" "single")])
12725 (define_expand "sqrtsf2"
12726 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12727 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12728 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12732 expand_sf_unop (&gen_sqrtsf2_i, operands);
12737 (define_insn "*sqrtsf2_media"
12738 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12739 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12740 "TARGET_SHMEDIA_FPU"
12742 [(set_attr "type" "fdiv_media")])
12744 (define_insn "sqrtsf2_i"
12745 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12746 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12747 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12750 [(set_attr "type" "fdiv")
12751 (set_attr "fp_mode" "single")])
12753 (define_insn "rsqrtsf2"
12754 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12755 (div:SF (match_operand:SF 1 "immediate_operand" "i")
12756 (sqrt:SF (match_operand:SF 2 "fp_arith_reg_operand" "0"))))
12757 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12758 "TARGET_FPU_ANY && TARGET_FSRRA
12759 && operands[1] == CONST1_RTX (SFmode)"
12761 [(set_attr "type" "fsrra")
12762 (set_attr "fp_mode" "single")])
12764 ;; When the sincos pattern is defined, the builtin functions sin and cos
12765 ;; will be expanded to the sincos pattern and one of the output values will
12767 (define_expand "sincossf3"
12768 [(set (match_operand:SF 0 "nonimmediate_operand")
12769 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand")] UNSPEC_FCOSA))
12770 (set (match_operand:SF 1 "nonimmediate_operand")
12771 (unspec:SF [(match_dup 2)] UNSPEC_FSINA))]
12772 "TARGET_FPU_ANY && TARGET_FSCA"
12774 rtx scaled = gen_reg_rtx (SFmode);
12775 rtx truncated = gen_reg_rtx (SImode);
12776 rtx fsca = gen_reg_rtx (V2SFmode);
12777 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12779 emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12780 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
12781 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
12782 get_fpscr_rtx ()));
12784 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
12785 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0));
12789 (define_insn_and_split "fsca"
12790 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12792 (unspec:SF [(mult:SF
12793 (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12794 (match_operand:SF 2 "fsca_scale_factor" "i"))
12796 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12798 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12799 "TARGET_FPU_ANY && TARGET_FSCA"
12801 "&& !fpul_operand (operands[1], SImode)"
12804 /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12805 to a simple reg, otherwise reload will have trouble reloading the
12806 pseudo into fpul. */
12807 rtx x = XEXP (operands[1], 0);
12808 while (x != NULL_RTX && !fpul_operand (x, SImode))
12810 gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12814 gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12815 emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
12818 [(set_attr "type" "fsca")
12819 (set_attr "fp_mode" "single")])
12821 (define_expand "abssf2"
12822 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12823 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12824 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12828 expand_sf_unop (&gen_abssf2_i, operands);
12833 (define_insn "*abssf2_media"
12834 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12835 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12836 "TARGET_SHMEDIA_FPU"
12838 [(set_attr "type" "fmove_media")])
12840 (define_insn "abssf2_i"
12841 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12842 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12843 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12846 [(set_attr "type" "fmove")
12847 (set_attr "fp_mode" "single")])
12849 (define_expand "adddf3"
12850 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12851 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12852 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12853 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12855 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12857 expand_df_binop (&gen_adddf3_i, operands);
12862 (define_insn "*adddf3_media"
12863 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12864 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12865 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12866 "TARGET_SHMEDIA_FPU"
12867 "fadd.d %1, %2, %0"
12868 [(set_attr "type" "dfparith_media")])
12870 (define_insn "adddf3_i"
12871 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12872 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12873 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12874 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12875 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12877 [(set_attr "type" "dfp_arith")
12878 (set_attr "fp_mode" "double")])
12880 (define_expand "subdf3"
12881 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12882 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12883 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12884 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12886 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12888 expand_df_binop (&gen_subdf3_i, operands);
12893 (define_insn "*subdf3_media"
12894 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12895 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12896 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12897 "TARGET_SHMEDIA_FPU"
12898 "fsub.d %1, %2, %0"
12899 [(set_attr "type" "dfparith_media")])
12901 (define_insn "subdf3_i"
12902 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12903 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12904 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12905 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12906 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12908 [(set_attr "type" "dfp_arith")
12909 (set_attr "fp_mode" "double")])
12911 (define_expand "muldf3"
12912 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12913 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12914 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12917 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12919 expand_df_binop (&gen_muldf3_i, operands);
12924 (define_insn "*muldf3_media"
12925 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12926 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12927 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12928 "TARGET_SHMEDIA_FPU"
12929 "fmul.d %1, %2, %0"
12930 [(set_attr "type" "dfmul_media")])
12932 (define_insn "muldf3_i"
12933 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12934 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12935 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12936 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12937 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12939 [(set_attr "type" "dfp_mul")
12940 (set_attr "fp_mode" "double")])
12942 (define_expand "divdf3"
12943 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12944 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12945 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12946 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12948 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12950 expand_df_binop (&gen_divdf3_i, operands);
12955 (define_insn "*divdf3_media"
12956 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12957 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12958 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12959 "TARGET_SHMEDIA_FPU"
12960 "fdiv.d %1, %2, %0"
12961 [(set_attr "type" "dfdiv_media")])
12963 (define_insn "divdf3_i"
12964 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12965 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12966 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12967 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12968 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12970 [(set_attr "type" "dfdiv")
12971 (set_attr "fp_mode" "double")])
12973 (define_insn "floatdidf2"
12974 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12975 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12976 "TARGET_SHMEDIA_FPU"
12978 [(set_attr "type" "dfpconv_media")])
12980 (define_expand "floatsidf2"
12981 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12982 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
12983 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12985 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12987 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
12988 get_fpscr_rtx ()));
12993 (define_insn "*floatsidf2_media"
12994 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12995 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12996 "TARGET_SHMEDIA_FPU"
12998 [(set_attr "type" "dfpconv_media")])
13000 (define_insn "floatsidf2_i"
13001 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13002 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
13003 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13004 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13006 [(set_attr "type" "dfp_conv")
13007 (set_attr "fp_mode" "double")])
13009 (define_insn "fix_truncdfdi2"
13010 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
13011 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13012 "TARGET_SHMEDIA_FPU"
13014 [(set_attr "type" "dfpconv_media")])
13016 (define_expand "fix_truncdfsi2"
13017 [(set (match_operand:SI 0 "fpul_operand" "")
13018 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13019 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13021 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13023 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
13024 get_fpscr_rtx ()));
13029 (define_insn "*fix_truncdfsi2_media"
13030 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
13031 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13032 "TARGET_SHMEDIA_FPU"
13034 [(set_attr "type" "dfpconv_media")])
13036 (define_insn "fix_truncdfsi2_i"
13037 [(set (match_operand:SI 0 "fpul_operand" "=y")
13038 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13039 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13040 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13042 [(set_attr "type" "dfp_conv")
13043 (set_attr "dfp_comp" "no")
13044 (set_attr "fp_mode" "double")])
13046 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
13047 ;; fix_truncdfsi2_i.
13048 ;; (define_insn "fix_truncdfsi2_i4"
13049 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13050 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
13051 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
13052 ;; (clobber (reg:SI FPUL_REG))]
13055 ;; [(set_attr "length" "4")
13056 ;; (set_attr "fp_mode" "double")])
13059 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13060 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
13061 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
13062 ;; (clobber (reg:SI FPUL_REG))]
13064 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
13065 ;; (use (match_dup 2))])
13066 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
13068 (define_insn "cmpgtdf_t"
13069 [(set (reg:SI T_REG)
13070 (gt:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13071 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13072 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13073 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13075 [(set_attr "type" "dfp_cmp")
13076 (set_attr "fp_mode" "double")])
13078 (define_insn "cmpeqdf_t"
13079 [(set (reg:SI T_REG)
13080 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13081 (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13082 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13083 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13085 [(set_attr "type" "dfp_cmp")
13086 (set_attr "fp_mode" "double")])
13088 (define_insn "*ieee_ccmpeqdf_t"
13089 [(set (reg:SI T_REG)
13090 (ior:SI (reg:SI T_REG)
13091 (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f")
13092 (match_operand:DF 1 "fp_arith_reg_operand" "f"))))
13093 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13094 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13096 return output_ieee_ccmpeq (insn, operands);
13098 [(set_attr "length" "4")
13099 (set_attr "fp_mode" "double")])
13101 (define_insn "cmpeqdf_media"
13102 [(set (match_operand:SI 0 "register_operand" "=r")
13103 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13104 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13105 "TARGET_SHMEDIA_FPU"
13106 "fcmpeq.d %1,%2,%0"
13107 [(set_attr "type" "fcmp_media")])
13109 (define_insn "cmpgtdf_media"
13110 [(set (match_operand:SI 0 "register_operand" "=r")
13111 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13112 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13113 "TARGET_SHMEDIA_FPU"
13114 "fcmpgt.d %1,%2,%0"
13115 [(set_attr "type" "fcmp_media")])
13117 (define_insn "cmpgedf_media"
13118 [(set (match_operand:SI 0 "register_operand" "=r")
13119 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13120 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13121 "TARGET_SHMEDIA_FPU"
13122 "fcmpge.d %1,%2,%0"
13123 [(set_attr "type" "fcmp_media")])
13125 (define_insn "cmpundf_media"
13126 [(set (match_operand:SI 0 "register_operand" "=r")
13127 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
13128 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
13129 "TARGET_SHMEDIA_FPU"
13130 "fcmpun.d %1,%2,%0"
13131 [(set_attr "type" "fcmp_media")])
13133 (define_expand "cbranchdf4"
13135 (if_then_else (match_operator 0 "sh_float_comparison_operator"
13136 [(match_operand:DF 1 "arith_operand" "")
13137 (match_operand:DF 2 "arith_operand" "")])
13138 (match_operand 3 "" "")
13140 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13142 if (TARGET_SHMEDIA)
13143 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
13146 sh_emit_compare_and_branch (operands, DFmode);
13150 (define_expand "negdf2"
13151 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13152 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13153 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13155 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13157 expand_df_unop (&gen_negdf2_i, operands);
13162 (define_insn "*negdf2_media"
13163 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13164 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13165 "TARGET_SHMEDIA_FPU"
13167 [(set_attr "type" "fmove_media")])
13169 (define_insn "negdf2_i"
13170 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13171 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
13172 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13173 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13175 [(set_attr "type" "fmove")
13176 (set_attr "fp_mode" "double")])
13178 (define_expand "sqrtdf2"
13179 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13180 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13181 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13183 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13185 expand_df_unop (&gen_sqrtdf2_i, operands);
13190 (define_insn "*sqrtdf2_media"
13191 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13192 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13193 "TARGET_SHMEDIA_FPU"
13195 [(set_attr "type" "dfdiv_media")])
13197 (define_insn "sqrtdf2_i"
13198 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13199 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
13200 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13201 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13203 [(set_attr "type" "dfdiv")
13204 (set_attr "fp_mode" "double")])
13206 (define_expand "absdf2"
13207 [(set (match_operand:DF 0 "fp_arith_reg_operand")
13208 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand")))]
13209 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13211 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13213 expand_df_unop (&gen_absdf2_i, operands);
13218 (define_insn "*absdf2_media"
13219 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13220 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13221 "TARGET_SHMEDIA_FPU"
13223 [(set_attr "type" "fmove_media")])
13225 (define_insn "absdf2_i"
13226 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13227 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
13228 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13229 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13231 [(set_attr "type" "fmove")
13232 (set_attr "fp_mode" "double")])
13234 (define_expand "extendsfdf2"
13235 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
13236 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
13237 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13239 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13241 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
13242 get_fpscr_rtx ()));
13247 (define_insn "*extendsfdf2_media"
13248 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13249 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
13250 "TARGET_SHMEDIA_FPU"
13252 [(set_attr "type" "dfpconv_media")])
13254 (define_insn "extendsfdf2_i4"
13255 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
13256 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
13257 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13258 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13260 [(set_attr "type" "fp")
13261 (set_attr "fp_mode" "double")])
13263 (define_expand "truncdfsf2"
13264 [(set (match_operand:SF 0 "fpul_operand" "")
13265 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
13266 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
13268 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
13270 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
13271 get_fpscr_rtx ()));
13276 (define_insn "*truncdfsf2_media"
13277 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13278 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
13279 "TARGET_SHMEDIA_FPU"
13281 [(set_attr "type" "dfpconv_media")])
13283 (define_insn "truncdfsf2_i4"
13284 [(set (match_operand:SF 0 "fpul_operand" "=y")
13285 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
13286 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
13287 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
13289 [(set_attr "type" "fp")
13290 (set_attr "fp_mode" "double")])
13292 ;; -------------------------------------------------------------------------
13293 ;; Bit field extract patterns.
13294 ;; -------------------------------------------------------------------------
13296 ;; These give better code for packed bitfields, because they allow
13297 ;; auto-increment addresses to be generated.
13299 (define_expand "insv"
13300 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
13301 (match_operand:SI 1 "immediate_operand" "")
13302 (match_operand:SI 2 "immediate_operand" ""))
13303 (match_operand:SI 3 "general_operand" ""))]
13304 "TARGET_SH1 && TARGET_BIG_ENDIAN"
13306 rtx addr_target, orig_address, shift_reg, qi_val;
13307 HOST_WIDE_INT bitsize, size, v = 0;
13308 rtx x = operands[3];
13310 if (TARGET_SH2A && TARGET_BITOPS
13311 && (satisfies_constraint_Sbw (operands[0])
13312 || satisfies_constraint_Sbv (operands[0]))
13313 && satisfies_constraint_M (operands[1])
13314 && satisfies_constraint_K03 (operands[2]))
13316 if (satisfies_constraint_N (operands[3]))
13318 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
13321 else if (satisfies_constraint_M (operands[3]))
13323 emit_insn (gen_bset_m2a (operands[0], operands[2]));
13326 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
13327 && satisfies_constraint_M (operands[1]))
13329 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13332 else if (REG_P (operands[3])
13333 && satisfies_constraint_M (operands[1]))
13335 emit_insn (gen_bld_reg (operands[3], const0_rtx));
13336 emit_insn (gen_bst_m2a (operands[0], operands[2]));
13340 /* ??? expmed doesn't care for non-register predicates. */
13341 if (! memory_operand (operands[0], VOIDmode)
13342 || ! immediate_operand (operands[1], VOIDmode)
13343 || ! immediate_operand (operands[2], VOIDmode)
13344 || ! general_operand (x, VOIDmode))
13346 /* If this isn't a 16 / 24 / 32 bit field, or if
13347 it doesn't start on a byte boundary, then fail. */
13348 bitsize = INTVAL (operands[1]);
13349 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
13350 || (INTVAL (operands[2]) % 8) != 0)
13353 size = bitsize / 8;
13354 orig_address = XEXP (operands[0], 0);
13355 shift_reg = gen_reg_rtx (SImode);
13356 if (CONST_INT_P (x))
13359 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
13363 emit_insn (gen_movsi (shift_reg, operands[3]));
13364 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13366 addr_target = copy_addr_to_reg (plus_constant (Pmode,
13367 orig_address, size - 1));
13369 operands[0] = replace_equiv_address (operands[0], addr_target);
13370 emit_insn (gen_movqi (operands[0], qi_val));
13374 if (CONST_INT_P (x))
13376 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
13379 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
13380 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
13382 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
13383 emit_insn (gen_movqi (operands[0], qi_val));
13389 (define_insn "movua"
13390 [(set (match_operand:SI 0 "register_operand" "=z")
13391 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
13395 [(set_attr "type" "movua")])
13397 ;; We shouldn't need this, but cse replaces increments with references
13398 ;; to other regs before flow has a chance to create post_inc
13399 ;; addressing modes, and only postreload's cse_move2add brings the
13400 ;; increments back to a usable form.
13402 [(set (match_operand:SI 0 "register_operand" "")
13403 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
13404 (const_int 32) (const_int 0)))
13405 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13406 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
13407 [(set (match_operand:SI 0 "register_operand" "")
13408 (sign_extract:SI (mem:SI (post_inc:SI
13409 (match_operand:SI 1 "register_operand" "")))
13410 (const_int 32) (const_int 0)))]
13413 (define_expand "extv"
13414 [(set (match_operand:SI 0 "register_operand" "")
13415 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13416 (match_operand 2 "const_int_operand" "")
13417 (match_operand 3 "const_int_operand" "")))]
13418 "TARGET_SH4A_ARCH || TARGET_SH2A"
13420 if (TARGET_SH2A && TARGET_BITOPS
13421 && (satisfies_constraint_Sbw (operands[1])
13422 || satisfies_constraint_Sbv (operands[1]))
13423 && satisfies_constraint_M (operands[2])
13424 && satisfies_constraint_K03 (operands[3]))
13426 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
13427 if (REGNO (operands[0]) != T_REG)
13428 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13431 if (TARGET_SH4A_ARCH
13432 && INTVAL (operands[2]) == 32
13433 && INTVAL (operands[3]) == 0
13434 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13436 rtx src = adjust_address (operands[1], BLKmode, 0);
13437 set_mem_size (src, 4);
13438 emit_insn (gen_movua (operands[0], src));
13445 (define_expand "extzv"
13446 [(set (match_operand:SI 0 "register_operand" "")
13447 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
13448 (match_operand 2 "const_int_operand" "")
13449 (match_operand 3 "const_int_operand" "")))]
13450 "TARGET_SH4A_ARCH || TARGET_SH2A"
13452 if (TARGET_SH2A && TARGET_BITOPS
13453 && (satisfies_constraint_Sbw (operands[1])
13454 || satisfies_constraint_Sbv (operands[1]))
13455 && satisfies_constraint_M (operands[2])
13456 && satisfies_constraint_K03 (operands[3]))
13458 emit_insn (gen_bld_m2a (operands[1], operands[3]));
13459 if (REGNO (operands[0]) != T_REG)
13460 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
13463 if (TARGET_SH4A_ARCH
13464 && INTVAL (operands[2]) == 32
13465 && INTVAL (operands[3]) == 0
13466 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
13468 rtx src = adjust_address (operands[1], BLKmode, 0);
13469 set_mem_size (src, 4);
13470 emit_insn (gen_movua (operands[0], src));
13477 ;; SH2A instructions for bitwise operations.
13478 ;; FIXME: Convert multiple instruction insns to insn_and_split.
13479 ;; FIXME: Use iterators to fold at least and,xor,or insn variations.
13481 ;; Clear a bit in a memory location.
13482 (define_insn "bclr_m2a"
13483 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13485 (not:QI (ashift:QI (const_int 1)
13486 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13488 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13491 bclr.b %1,@(0,%t0)"
13492 [(set_attr "length" "4,4")])
13494 (define_insn "bclrmem_m2a"
13495 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13496 (and:QI (match_dup 0)
13497 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
13498 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
13501 bclr.b %W1,@(0,%t0)"
13502 [(set_attr "length" "4,4")])
13504 ;; Set a bit in a memory location.
13505 (define_insn "bset_m2a"
13506 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13508 (ashift:QI (const_int 1)
13509 (match_operand:QI 1 "const_int_operand" "K03,K03"))
13511 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13514 bset.b %1,@(0,%t0)"
13515 [(set_attr "length" "4,4")])
13517 (define_insn "bsetmem_m2a"
13518 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
13519 (ior:QI (match_dup 0)
13520 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
13521 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
13524 bset.b %V1,@(0,%t0)"
13525 [(set_attr "length" "4,4")])
13527 ;;; Transfer the contents of the T bit to a specified bit of memory.
13528 (define_insn "bst_m2a"
13529 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
13530 (if_then_else (eq (reg:SI T_REG) (const_int 0))
13532 (not:QI (ashift:QI (const_int 1)
13533 (match_operand:QI 1 "const_int_operand" "K03,K03")))
13536 (ashift:QI (const_int 1) (match_dup 1))
13538 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13542 [(set_attr "length" "4")])
13544 ;; Store a specified bit of memory in the T bit.
13545 (define_insn "bld_m2a"
13546 [(set (reg:SI T_REG)
13548 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13550 (match_operand 1 "const_int_operand" "K03,K03")))]
13551 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13555 [(set_attr "length" "4,4")])
13557 ;; Store a specified bit of memory in the T bit.
13558 (define_insn "bldsign_m2a"
13559 [(set (reg:SI T_REG)
13561 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13563 (match_operand 1 "const_int_operand" "K03,K03")))]
13564 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13568 [(set_attr "length" "4,4")])
13570 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13571 (define_insn "bld_reg"
13572 [(set (reg:SI T_REG)
13573 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13575 (match_operand 1 "const_int_operand" "K03")))]
13576 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13579 (define_insn "*bld_regqi"
13580 [(set (reg:SI T_REG)
13581 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13583 (match_operand 1 "const_int_operand" "K03")))]
13584 "TARGET_SH2A && satisfies_constraint_K03 (operands[1])"
13587 ;; Take logical and of a specified bit of memory with the T bit and
13588 ;; store its result in the T bit.
13589 (define_insn "band_m2a"
13590 [(set (reg:SI T_REG)
13591 (and:SI (reg:SI T_REG)
13593 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13595 (match_operand 1 "const_int_operand" "K03,K03"))))]
13596 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13599 band.b %1,@(0,%t0)"
13600 [(set_attr "length" "4,4")])
13602 (define_insn "bandreg_m2a"
13603 [(set (match_operand:SI 0 "register_operand" "=r,r")
13604 (and:SI (zero_extract:SI
13605 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13607 (match_operand 2 "const_int_operand" "K03,K03"))
13608 (match_operand:SI 3 "register_operand" "r,r")))]
13609 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13611 static const char* alt[] =
13613 "band.b %2,%1" "\n"
13616 "band.b %2,@(0,%t1)" "\n"
13619 return alt[which_alternative];
13621 [(set_attr "length" "6,6")])
13623 ;; Take logical or of a specified bit of memory with the T bit and
13624 ;; store its result in the T bit.
13625 (define_insn "bor_m2a"
13626 [(set (reg:SI T_REG)
13627 (ior:SI (reg:SI T_REG)
13629 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13631 (match_operand 1 "const_int_operand" "K03,K03"))))]
13632 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13636 [(set_attr "length" "4,4")])
13638 (define_insn "borreg_m2a"
13639 [(set (match_operand:SI 0 "register_operand" "=r,r")
13640 (ior:SI (zero_extract:SI
13641 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13643 (match_operand 2 "const_int_operand" "K03,K03"))
13644 (match_operand:SI 3 "register_operand" "=r,r")))]
13645 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13647 static const char* alt[] =
13652 "bor.b %2,@(0,%t1)" "\n"
13655 return alt[which_alternative];
13657 [(set_attr "length" "6,6")])
13659 ;; Take exclusive or of a specified bit of memory with the T bit and
13660 ;; store its result in the T bit.
13661 (define_insn "bxor_m2a"
13662 [(set (reg:SI T_REG)
13663 (xor:SI (reg:SI T_REG)
13665 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13667 (match_operand 1 "const_int_operand" "K03,K03"))))]
13668 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[1])"
13671 bxor.b %1,@(0,%t0)"
13672 [(set_attr "length" "4,4")])
13674 (define_insn "bxorreg_m2a"
13675 [(set (match_operand:SI 0 "register_operand" "=r,r")
13676 (xor:SI (zero_extract:SI
13677 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13679 (match_operand 2 "const_int_operand" "K03,K03"))
13680 (match_operand:SI 3 "register_operand" "=r,r")))]
13681 "TARGET_SH2A && TARGET_BITOPS && satisfies_constraint_K03 (operands[2])"
13683 static const char* alt[] =
13685 "bxor.b %2,%1" "\n"
13688 "bxor.b %2,@(0,%t1)" "\n"
13691 return alt[which_alternative];
13693 [(set_attr "length" "6,6")])
13695 ;; -------------------------------------------------------------------------
13697 ;; -------------------------------------------------------------------------
13698 ;; This matches cases where the bit in a memory location is set.
13700 [(set (match_operand:SI 0 "register_operand")
13701 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
13703 (ior:SI (match_dup 0)
13704 (match_operand:SI 2 "const_int_operand")))
13706 (match_operand 3 "arith_reg_operand"))]
13707 "TARGET_SH2A && TARGET_BITOPS
13708 && satisfies_constraint_Pso (operands[2])
13709 && REGNO (operands[0]) == REGNO (operands[3])"
13710 [(set (match_dup 1)
13711 (ior:QI (match_dup 1) (match_dup 2)))]
13714 ;; This matches cases where the bit in a memory location is cleared.
13716 [(set (match_operand:SI 0 "register_operand")
13717 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
13719 (and:SI (match_dup 0)
13720 (match_operand:SI 2 "const_int_operand")))
13722 (match_operand 3 "arith_reg_operand"))]
13723 "TARGET_SH2A && TARGET_BITOPS
13724 && satisfies_constraint_Psz (operands[2])
13725 && REGNO (operands[0]) == REGNO (operands[3])"
13726 [(set (match_dup 1)
13727 (and:QI (match_dup 1) (match_dup 2)))]
13730 ;; This matches cases where a stack pointer increment at the start of the
13731 ;; epilogue combines with a stack slot read loading the return value.
13733 [(set (match_operand:SI 0 "arith_reg_operand" "")
13734 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13735 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13736 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13739 ;; See the comment on the dt combiner pattern above.
13741 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13742 (plus:SI (match_dup 0)
13744 (set (reg:SI T_REG)
13745 (eq:SI (match_dup 0) (const_int 0)))]
13749 ;; The following peepholes fold load sequences for which reload was not
13750 ;; able to generate a displacement addressing move insn.
13751 ;; This can happen when reload has to transform a move insn
13752 ;; without displacement into one with displacement. Or when reload can't
13753 ;; fit a displacement into the insn's constraints. In the latter case, the
13754 ;; load destination reg remains at r0, which reload compensates by inserting
13755 ;; another mov insn.
13759 ;; mov.{b,w} @(r0,r15),r0
13762 ;; mov.{b,w} @(54,r15),r3
13765 [(set (match_operand:SI 0 "arith_reg_dest" "")
13766 (match_operand:SI 1 "const_int_operand" ""))
13767 (set (match_operand:SI 2 "arith_reg_dest" "")
13769 (mem:QI (plus:SI (match_dup 0)
13770 (match_operand:SI 3 "arith_reg_operand" "")))))
13771 (set (match_operand:QI 4 "arith_reg_dest" "")
13772 (match_operand:QI 5 "arith_reg_operand" ""))]
13774 && sh_legitimate_index_p (QImode, operands[1], true, true)
13775 && REGNO (operands[2]) == REGNO (operands[5])
13776 && peep2_reg_dead_p (3, operands[5])"
13777 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13781 [(set (match_operand:SI 0 "arith_reg_dest" "")
13782 (match_operand:SI 1 "const_int_operand" ""))
13783 (set (match_operand:SI 2 "arith_reg_dest" "")
13785 (mem:HI (plus:SI (match_dup 0)
13786 (match_operand:SI 3 "arith_reg_operand" "")))))
13787 (set (match_operand:HI 4 "arith_reg_dest" "")
13788 (match_operand:HI 5 "arith_reg_operand" ""))]
13790 && sh_legitimate_index_p (HImode, operands[1], true, true)
13791 && REGNO (operands[2]) == REGNO (operands[5])
13792 && peep2_reg_dead_p (3, operands[5])"
13793 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13798 ;; mov.{b,w} @(r0,r15),r1
13800 ;; mov.{b,w} @(54,r15),r1
13803 [(set (match_operand:SI 0 "arith_reg_dest" "")
13804 (match_operand:SI 1 "const_int_operand" ""))
13805 (set (match_operand:SI 2 "arith_reg_dest" "")
13807 (mem:QI (plus:SI (match_dup 0)
13808 (match_operand:SI 3 "arith_reg_operand" "")))))]
13810 && sh_legitimate_index_p (QImode, operands[1], true, true)
13811 && (peep2_reg_dead_p (2, operands[0])
13812 || REGNO (operands[0]) == REGNO (operands[2]))"
13813 [(set (match_dup 2)
13814 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13818 [(set (match_operand:SI 0 "arith_reg_dest" "")
13819 (match_operand:SI 1 "const_int_operand" ""))
13820 (set (match_operand:SI 2 "arith_reg_dest" "")
13822 (mem:HI (plus:SI (match_dup 0)
13823 (match_operand:SI 3 "arith_reg_operand" "")))))]
13825 && sh_legitimate_index_p (HImode, operands[1], true, true)
13826 && (peep2_reg_dead_p (2, operands[0])
13827 || REGNO (operands[0]) == REGNO (operands[2]))"
13828 [(set (match_dup 2)
13829 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13833 ;; mov.{b,w} @(r0,r15),r0
13836 ;; mov.{b,w} @(r0,r15),r3
13838 ;; This can happen when initially a displacement address is picked, where
13839 ;; the destination reg is fixed to r0, and then the address is transformed
13840 ;; into 'r0 + reg'.
13842 [(set (match_operand:SI 0 "arith_reg_dest" "")
13844 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13845 (match_operand:SI 2 "arith_reg_operand" "")))))
13846 (set (match_operand:QI 3 "arith_reg_dest" "")
13847 (match_operand:QI 4 "arith_reg_operand" ""))]
13849 && REGNO (operands[0]) == REGNO (operands[4])
13850 && peep2_reg_dead_p (2, operands[0])"
13851 [(set (match_dup 3)
13852 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13856 [(set (match_operand:SI 0 "arith_reg_dest" "")
13858 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13859 (match_operand:SI 2 "arith_reg_operand" "")))))
13860 (set (match_operand:HI 3 "arith_reg_dest" "")
13861 (match_operand:HI 4 "arith_reg_operand" ""))]
13863 && REGNO (operands[0]) == REGNO (operands[4])
13864 && peep2_reg_dead_p (2, operands[0])"
13865 [(set (match_dup 3)
13866 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13870 [(set (match_operand:SI 0 "register_operand" "=r")
13871 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13872 (set (mem:SF (match_dup 0))
13873 (match_operand:SF 2 "general_movsrc_operand" ""))]
13874 "TARGET_SH1 && REGNO (operands[0]) == 0
13875 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13876 || (GET_CODE (operands[2]) == SUBREG
13877 && REGNO (SUBREG_REG (operands[2])) < 16))
13878 && reg_unused_after (operands[0], insn)"
13879 "mov.l %2,@(%0,%1)")
13882 [(set (match_operand:SI 0 "register_operand" "=r")
13883 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13884 (set (match_operand:SF 2 "general_movdst_operand" "")
13886 (mem:SF (match_dup 0)))]
13887 "TARGET_SH1 && REGNO (operands[0]) == 0
13888 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13889 || (GET_CODE (operands[2]) == SUBREG
13890 && REGNO (SUBREG_REG (operands[2])) < 16))
13891 && reg_unused_after (operands[0], insn)"
13892 "mov.l @(%0,%1),%2")
13895 [(set (match_operand:SI 0 "register_operand" "=r")
13896 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13897 (set (mem:SF (match_dup 0))
13898 (match_operand:SF 2 "general_movsrc_operand" ""))]
13899 "TARGET_SH2E && REGNO (operands[0]) == 0
13900 && ((REG_P (operands[2])
13901 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13902 || (GET_CODE (operands[2]) == SUBREG
13903 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13904 && reg_unused_after (operands[0], insn)"
13905 "fmov{.s|} %2,@(%0,%1)")
13908 [(set (match_operand:SI 0 "register_operand" "=r")
13909 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13910 (set (match_operand:SF 2 "general_movdst_operand" "")
13912 (mem:SF (match_dup 0)))]
13913 "TARGET_SH2E && REGNO (operands[0]) == 0
13914 && ((REG_P (operands[2])
13915 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13916 || (GET_CODE (operands[2]) == SUBREG
13917 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13918 && reg_unused_after (operands[0], insn)"
13919 "fmov{.s|} @(%0,%1),%2")
13921 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13922 (define_insn "sp_switch_1"
13923 [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")]
13924 UNSPECV_SP_SWITCH_B))]
13927 return "mov.l r0,@-r15" "\n"
13928 " mov.l %0,r0" "\n"
13929 " mov.l @r0,r0" "\n"
13930 " mov.l r15,@-r0" "\n"
13933 [(set_attr "length" "10")])
13935 ;; Switch back to the original stack for interrupt functions with the
13936 ;; sp_switch attribute.
13937 (define_insn "sp_switch_2"
13938 [(unspec_volatile [(const_int 0)]
13939 UNSPECV_SP_SWITCH_E)]
13942 return "mov.l @r15,r15" "\n"
13945 [(set_attr "length" "4")])
13947 ;; -------------------------------------------------------------------------
13948 ;; Integer vector moves
13949 ;; -------------------------------------------------------------------------
13951 (define_expand "movv8qi"
13952 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
13953 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
13956 prepare_move_operands (operands, V8QImode);
13959 (define_insn "movv8qi_i"
13960 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
13961 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13963 && (register_operand (operands[0], V8QImode)
13964 || sh_register_operand (operands[1], V8QImode))"
13971 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13972 (set_attr "length" "4,4,16,4,4")])
13975 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
13976 (subreg:V8QI (const_int 0) 0))]
13978 [(set (match_dup 0)
13979 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
13980 (const_int 0) (const_int 0) (const_int 0)
13981 (const_int 0) (const_int 0)]))])
13984 [(set (match_operand 0 "arith_reg_dest" "")
13985 (match_operand 1 "sh_rep_vec" ""))]
13986 "TARGET_SHMEDIA && reload_completed
13987 && GET_MODE (operands[0]) == GET_MODE (operands[1])
13988 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
13989 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
13990 && (XVECEXP (operands[1], 0, 0) != const0_rtx
13991 || XVECEXP (operands[1], 0, 1) != const0_rtx)
13992 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
13993 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
13994 [(set (match_dup 0) (match_dup 1))
13997 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
13998 rtx elt1 = XVECEXP (operands[1], 0, 1);
14001 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
14005 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
14006 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
14008 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
14009 operands[1] = XVECEXP (operands[1], 0, 0);
14012 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
14014 = GEN_INT (TARGET_LITTLE_ENDIAN
14015 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
14016 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
14019 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
14021 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
14027 [(set (match_operand 0 "arith_reg_dest" "")
14028 (match_operand 1 "sh_const_vec" ""))]
14029 "TARGET_SHMEDIA && reload_completed
14030 && GET_MODE (operands[0]) == GET_MODE (operands[1])
14031 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
14032 [(set (match_dup 0) (match_dup 1))]
14034 rtx v = operands[1];
14035 enum machine_mode new_mode
14036 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
14038 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
14040 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
14043 (define_expand "movv2hi"
14044 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
14045 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
14048 prepare_move_operands (operands, V2HImode);
14051 (define_insn "movv2hi_i"
14052 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
14053 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14055 && (register_operand (operands[0], V2HImode)
14056 || sh_register_operand (operands[1], V2HImode))"
14063 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14064 (set_attr "length" "4,4,16,4,4")
14065 (set (attr "highpart")
14066 (cond [(match_test "sh_contains_memref_p (insn)")
14067 (const_string "user")]
14068 (const_string "ignore")))])
14070 (define_expand "movv4hi"
14071 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
14072 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
14075 prepare_move_operands (operands, V4HImode);
14078 (define_insn "movv4hi_i"
14079 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
14080 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14082 && (register_operand (operands[0], V4HImode)
14083 || sh_register_operand (operands[1], V4HImode))"
14090 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14091 (set_attr "length" "4,4,16,4,4")
14092 (set_attr "highpart" "depend")])
14094 (define_expand "movv2si"
14095 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
14096 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
14099 prepare_move_operands (operands, V2SImode);
14102 (define_insn "movv2si_i"
14103 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
14104 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
14106 && (register_operand (operands[0], V2SImode)
14107 || sh_register_operand (operands[1], V2SImode))"
14114 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
14115 (set_attr "length" "4,4,16,4,4")
14116 (set_attr "highpart" "depend")])
14118 ;; -------------------------------------------------------------------------
14119 ;; Multimedia Intrinsics
14120 ;; -------------------------------------------------------------------------
14122 (define_insn "absv2si2"
14123 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14124 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
14127 [(set_attr "type" "mcmp_media")
14128 (set_attr "highpart" "depend")])
14130 (define_insn "absv4hi2"
14131 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14132 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
14135 [(set_attr "type" "mcmp_media")
14136 (set_attr "highpart" "depend")])
14138 (define_insn "addv2si3"
14139 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14140 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
14141 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14143 "madd.l %1, %2, %0"
14144 [(set_attr "type" "arith_media")
14145 (set_attr "highpart" "depend")])
14147 (define_insn "addv4hi3"
14148 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14149 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
14150 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14152 "madd.w %1, %2, %0"
14153 [(set_attr "type" "arith_media")
14154 (set_attr "highpart" "depend")])
14156 (define_insn_and_split "addv2hi3"
14157 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14158 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
14159 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
14165 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14166 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14167 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14168 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14169 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14171 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
14172 emit_insn (gen_truncdisi2 (si_dst, di_dst));
14175 [(set_attr "highpart" "must_split")])
14177 (define_insn "ssaddv2si3"
14178 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14179 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
14180 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14182 "madds.l %1, %2, %0"
14183 [(set_attr "type" "mcmp_media")
14184 (set_attr "highpart" "depend")])
14186 (define_insn "usaddv8qi3"
14187 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14188 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
14189 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14191 "madds.ub %1, %2, %0"
14192 [(set_attr "type" "mcmp_media")
14193 (set_attr "highpart" "depend")])
14195 (define_insn "ssaddv4hi3"
14196 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14197 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
14198 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14200 "madds.w %1, %2, %0"
14201 [(set_attr "type" "mcmp_media")
14202 (set_attr "highpart" "depend")])
14204 (define_insn "negcmpeqv8qi"
14205 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14207 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
14208 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
14210 "mcmpeq.b %N1, %N2, %0"
14211 [(set_attr "type" "mcmp_media")
14212 (set_attr "highpart" "depend")])
14214 (define_insn "negcmpeqv2si"
14215 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14217 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
14218 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14220 "mcmpeq.l %N1, %N2, %0"
14221 [(set_attr "type" "mcmp_media")
14222 (set_attr "highpart" "depend")])
14224 (define_insn "negcmpeqv4hi"
14225 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14227 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
14228 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14230 "mcmpeq.w %N1, %N2, %0"
14231 [(set_attr "type" "mcmp_media")
14232 (set_attr "highpart" "depend")])
14234 (define_insn "negcmpgtuv8qi"
14235 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14236 (neg:V8QI (gtu:V8QI
14237 (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
14238 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
14240 "mcmpgt.ub %N1, %N2, %0"
14241 [(set_attr "type" "mcmp_media")
14242 (set_attr "highpart" "depend")])
14244 (define_insn "negcmpgtv2si"
14245 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14247 (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
14248 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14250 "mcmpgt.l %N1, %N2, %0"
14251 [(set_attr "type" "mcmp_media")
14252 (set_attr "highpart" "depend")])
14254 (define_insn "negcmpgtv4hi"
14255 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14257 (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
14258 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14260 "mcmpgt.w %N1, %N2, %0"
14261 [(set_attr "type" "mcmp_media")
14262 (set_attr "highpart" "depend")])
14264 (define_insn "mcmv"
14265 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14266 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14267 (match_operand:DI 2 "arith_reg_operand" "r"))
14268 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
14269 (not:DI (match_dup 2)))))]
14272 [(set_attr "type" "arith_media")
14273 (set_attr "highpart" "depend")])
14275 (define_insn "mcnvs_lw"
14276 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14278 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
14280 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
14282 "mcnvs.lw %N1, %N2, %0"
14283 [(set_attr "type" "mcmp_media")])
14285 (define_insn "mcnvs_wb"
14286 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14288 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14290 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14292 "mcnvs.wb %N1, %N2, %0"
14293 [(set_attr "type" "mcmp_media")])
14295 (define_insn "mcnvs_wub"
14296 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14298 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
14300 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
14302 "mcnvs.wub %N1, %N2, %0"
14303 [(set_attr "type" "mcmp_media")])
14305 (define_insn "mextr_rl"
14306 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14307 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14308 (match_operand:HI 3 "mextr_bit_offset" "i"))
14309 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14310 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14311 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14313 static char templ[21];
14314 sprintf (templ, "mextr%d %%N1, %%N2, %%0",
14315 (int) INTVAL (operands[3]) >> 3);
14318 [(set_attr "type" "arith_media")])
14320 (define_insn "*mextr_lr"
14321 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14322 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14323 (match_operand:HI 3 "mextr_bit_offset" "i"))
14324 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14325 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
14326 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
14328 static char templ[21];
14329 sprintf (templ, "mextr%d %%N2, %%N1, %%0",
14330 (int) INTVAL (operands[4]) >> 3);
14333 [(set_attr "type" "arith_media")])
14335 ; mextrN can be modelled with vec_select / vec_concat, but the selection
14336 ; vector then varies depending on endianness.
14337 (define_expand "mextr1"
14338 [(match_operand:DI 0 "arith_reg_dest" "")
14339 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14340 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14343 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14344 GEN_INT (1 * 8), GEN_INT (7 * 8)));
14348 (define_expand "mextr2"
14349 [(match_operand:DI 0 "arith_reg_dest" "")
14350 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14351 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14354 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14355 GEN_INT (2 * 8), GEN_INT (6 * 8)));
14359 (define_expand "mextr3"
14360 [(match_operand:DI 0 "arith_reg_dest" "")
14361 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14362 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14365 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14366 GEN_INT (3 * 8), GEN_INT (5 * 8)));
14370 (define_expand "mextr4"
14371 [(match_operand:DI 0 "arith_reg_dest" "")
14372 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14373 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14376 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14377 GEN_INT (4 * 8), GEN_INT (4 * 8)));
14381 (define_expand "mextr5"
14382 [(match_operand:DI 0 "arith_reg_dest" "")
14383 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14384 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14387 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14388 GEN_INT (5 * 8), GEN_INT (3 * 8)));
14392 (define_expand "mextr6"
14393 [(match_operand:DI 0 "arith_reg_dest" "")
14394 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14395 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14398 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14399 GEN_INT (6 * 8), GEN_INT (2 * 8)));
14403 (define_expand "mextr7"
14404 [(match_operand:DI 0 "arith_reg_dest" "")
14405 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14406 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
14409 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
14410 GEN_INT (7 * 8), GEN_INT (1 * 8)));
14414 (define_expand "mmacfx_wl"
14415 [(match_operand:V2SI 0 "arith_reg_dest" "")
14416 (match_operand:V2HI 1 "extend_reg_operand" "")
14417 (match_operand:V2HI 2 "extend_reg_operand" "")
14418 (match_operand:V2SI 3 "arith_reg_operand" "")]
14421 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
14422 operands[1], operands[2]));
14426 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
14428 (define_insn "mmacfx_wl_i"
14429 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14431 (match_operand:V2SI 1 "arith_reg_operand" "0")
14436 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14437 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14440 "mmacfx.wl %2, %3, %0"
14441 [(set_attr "type" "mac_media")
14442 (set_attr "highpart" "depend")])
14444 (define_expand "mmacnfx_wl"
14445 [(match_operand:V2SI 0 "arith_reg_dest" "")
14446 (match_operand:V2HI 1 "extend_reg_operand" "")
14447 (match_operand:V2HI 2 "extend_reg_operand" "")
14448 (match_operand:V2SI 3 "arith_reg_operand" "")]
14451 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
14452 operands[1], operands[2]));
14456 (define_insn "mmacnfx_wl_i"
14457 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14459 (match_operand:V2SI 1 "arith_reg_operand" "0")
14464 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
14465 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
14468 "mmacnfx.wl %2, %3, %0"
14469 [(set_attr "type" "mac_media")
14470 (set_attr "highpart" "depend")])
14472 (define_insn "mulv2si3"
14473 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14474 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14475 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14477 "mmul.l %1, %2, %0"
14478 [(set_attr "type" "d2mpy_media")
14479 (set_attr "highpart" "depend")])
14481 (define_insn "mulv4hi3"
14482 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14483 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14484 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14486 "mmul.w %1, %2, %0"
14487 [(set_attr "type" "dmpy_media")
14488 (set_attr "highpart" "depend")])
14490 (define_insn "mmulfx_l"
14491 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14495 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14496 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
14499 "mmulfx.l %1, %2, %0"
14500 [(set_attr "type" "d2mpy_media")
14501 (set_attr "highpart" "depend")])
14503 (define_insn "mmulfx_w"
14504 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14508 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14509 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14512 "mmulfx.w %1, %2, %0"
14513 [(set_attr "type" "dmpy_media")
14514 (set_attr "highpart" "depend")])
14516 (define_insn "mmulfxrp_w"
14517 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14522 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14523 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14527 "mmulfxrp.w %1, %2, %0"
14528 [(set_attr "type" "dmpy_media")
14529 (set_attr "highpart" "depend")])
14532 (define_expand "mmulhi_wl"
14533 [(match_operand:V2SI 0 "arith_reg_dest" "")
14534 (match_operand:V4HI 1 "arith_reg_operand" "")
14535 (match_operand:V4HI 2 "arith_reg_operand" "")]
14538 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
14539 (operands[0], operands[1], operands[2]));
14543 (define_expand "mmullo_wl"
14544 [(match_operand:V2SI 0 "arith_reg_dest" "")
14545 (match_operand:V4HI 1 "arith_reg_operand" "")
14546 (match_operand:V4HI 2 "arith_reg_operand" "")]
14549 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14550 (operands[0], operands[1], operands[2]));
14554 (define_insn "mmul23_wl"
14555 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14558 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14559 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14560 (parallel [(const_int 2) (const_int 3)])))]
14563 return (TARGET_LITTLE_ENDIAN
14564 ? "mmulhi.wl %1, %2, %0"
14565 : "mmullo.wl %1, %2, %0");
14567 [(set_attr "type" "dmpy_media")
14568 (set (attr "highpart")
14569 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14570 (const_string "user")))])
14572 (define_insn "mmul01_wl"
14573 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14576 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14577 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14578 (parallel [(const_int 0) (const_int 1)])))]
14581 return (TARGET_LITTLE_ENDIAN
14582 ? "mmullo.wl %1, %2, %0"
14583 : "mmulhi.wl %1, %2, %0");
14585 [(set_attr "type" "dmpy_media")
14586 (set (attr "highpart")
14587 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14588 (const_string "user")))])
14591 (define_expand "mmulsum_wq"
14592 [(match_operand:DI 0 "arith_reg_dest" "")
14593 (match_operand:V4HI 1 "arith_reg_operand" "")
14594 (match_operand:V4HI 2 "arith_reg_operand" "")
14595 (match_operand:DI 3 "arith_reg_operand" "")]
14598 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14599 operands[1], operands[2]));
14603 (define_insn "mmulsum_wq_i"
14604 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14605 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14610 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14611 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14612 (parallel [(const_int 0)]))
14613 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14614 (sign_extend:V4DI (match_dup 3)))
14615 (parallel [(const_int 1)])))
14617 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14618 (sign_extend:V4DI (match_dup 3)))
14619 (parallel [(const_int 2)]))
14620 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14621 (sign_extend:V4DI (match_dup 3)))
14622 (parallel [(const_int 3)]))))))]
14624 "mmulsum.wq %2, %3, %0"
14625 [(set_attr "type" "mac_media")])
14627 (define_expand "mperm_w"
14628 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14629 (match_operand:V4HI 1 "arith_reg_operand" "r")
14630 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14633 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14634 (operands[0], operands[1], operands[2]));
14638 ; This use of vec_select isn't exactly correct according to rtl.texi
14639 ; (because not constant), but it seems a straightforward extension.
14640 (define_insn "mperm_w_little"
14641 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14643 (match_operand:V4HI 1 "arith_reg_operand" "r")
14645 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14646 (const_int 2) (const_int 0))
14647 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14648 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14649 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14650 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14651 "mperm.w %1, %N2, %0"
14652 [(set_attr "type" "arith_media")])
14654 (define_insn "mperm_w_big"
14655 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14657 (match_operand:V4HI 1 "arith_reg_operand" "r")
14659 [(zero_extract:QI (not:QI (match_operand:QI 2
14660 "extend_reg_or_0_operand" "rZ"))
14661 (const_int 2) (const_int 0))
14662 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14663 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14664 (zero_extract:QI (not:QI (match_dup 2))
14665 (const_int 2) (const_int 6))])))]
14666 "TARGET_SHMEDIA && TARGET_BIG_ENDIAN"
14667 "mperm.w %1, %N2, %0"
14668 [(set_attr "type" "arith_media")])
14670 (define_insn "mperm_w0"
14671 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14672 (vec_duplicate:V4HI (truncate:HI (match_operand 1
14673 "trunc_hi_operand" "r"))))]
14675 "mperm.w %1, r63, %0"
14676 [(set_attr "type" "arith_media")
14677 (set_attr "highpart" "ignore")])
14679 (define_expand "msad_ubq"
14680 [(match_operand:DI 0 "arith_reg_dest" "")
14681 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14682 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14683 (match_operand:DI 3 "arith_reg_operand" "")]
14686 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14687 operands[1], operands[2]));
14691 (define_insn "msad_ubq_i"
14692 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14697 (match_operand:DI 1 "arith_reg_operand" "0")
14698 (abs:DI (vec_select:DI
14701 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14703 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14704 (parallel [(const_int 0)]))))
14705 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14706 (zero_extend:V8DI (match_dup 3)))
14707 (parallel [(const_int 1)]))))
14709 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14710 (zero_extend:V8DI (match_dup 3)))
14711 (parallel [(const_int 2)])))
14712 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14713 (zero_extend:V8DI (match_dup 3)))
14714 (parallel [(const_int 3)])))))
14717 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14718 (zero_extend:V8DI (match_dup 3)))
14719 (parallel [(const_int 4)])))
14720 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14721 (zero_extend:V8DI (match_dup 3)))
14722 (parallel [(const_int 5)]))))
14724 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14725 (zero_extend:V8DI (match_dup 3)))
14726 (parallel [(const_int 6)])))
14727 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14728 (zero_extend:V8DI (match_dup 3)))
14729 (parallel [(const_int 7)])))))))]
14731 "msad.ubq %N2, %N3, %0"
14732 [(set_attr "type" "mac_media")])
14734 (define_insn "mshalds_l"
14735 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14738 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14739 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14740 (const_int 31)))))]
14742 "mshalds.l %1, %2, %0"
14743 [(set_attr "type" "mcmp_media")
14744 (set_attr "highpart" "depend")])
14746 (define_insn "mshalds_w"
14747 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14750 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14751 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14752 (const_int 15)))))]
14754 "mshalds.w %1, %2, %0"
14755 [(set_attr "type" "mcmp_media")
14756 (set_attr "highpart" "depend")])
14758 (define_insn "ashrv2si3"
14759 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14760 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14761 (match_operand:DI 2 "arith_reg_operand" "r")))]
14763 "mshard.l %1, %2, %0"
14764 [(set_attr "type" "arith_media")
14765 (set_attr "highpart" "depend")])
14767 (define_insn "ashrv4hi3"
14768 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14769 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14770 (match_operand:DI 2 "arith_reg_operand" "r")))]
14772 "mshard.w %1, %2, %0"
14773 [(set_attr "type" "arith_media")
14774 (set_attr "highpart" "depend")])
14776 (define_insn "mshards_q"
14777 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14779 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14780 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14782 "mshards.q %1, %N2, %0"
14783 [(set_attr "type" "mcmp_media")])
14785 (define_expand "mshfhi_b"
14786 [(match_operand:V8QI 0 "arith_reg_dest" "")
14787 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14788 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14791 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14792 (operands[0], operands[1], operands[2]));
14796 (define_expand "mshflo_b"
14797 [(match_operand:V8QI 0 "arith_reg_dest" "")
14798 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14799 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14802 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14803 (operands[0], operands[1], operands[2]));
14807 (define_insn "mshf4_b"
14809 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14811 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14812 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14813 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14814 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14817 return (TARGET_LITTLE_ENDIAN
14818 ? "mshfhi.b %N1, %N2, %0"
14819 : "mshflo.b %N1, %N2, %0");
14821 [(set_attr "type" "arith_media")
14822 (set (attr "highpart")
14823 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14824 (const_string "user")))])
14826 (define_insn "mshf0_b"
14828 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14830 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14831 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14832 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14833 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14836 return (TARGET_LITTLE_ENDIAN
14837 ? "mshflo.b %N1, %N2, %0"
14838 : "mshfhi.b %N1, %N2, %0");
14840 [(set_attr "type" "arith_media")
14841 (set (attr "highpart")
14842 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14843 (const_string "user")))])
14845 (define_expand "mshfhi_l"
14846 [(match_operand:V2SI 0 "arith_reg_dest" "")
14847 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14848 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14851 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14852 (operands[0], operands[1], operands[2]));
14856 (define_expand "mshflo_l"
14857 [(match_operand:V2SI 0 "arith_reg_dest" "")
14858 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14859 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14862 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14863 (operands[0], operands[1], operands[2]));
14867 (define_insn "mshf4_l"
14868 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14870 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14871 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14872 (parallel [(const_int 1) (const_int 3)])))]
14875 return (TARGET_LITTLE_ENDIAN
14876 ? "mshfhi.l %N1, %N2, %0"
14877 : "mshflo.l %N1, %N2, %0");
14879 [(set_attr "type" "arith_media")
14880 (set (attr "highpart")
14881 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14882 (const_string "user")))])
14884 (define_insn "mshf0_l"
14885 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14887 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14888 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14889 (parallel [(const_int 0) (const_int 2)])))]
14892 return (TARGET_LITTLE_ENDIAN
14893 ? "mshflo.l %N1, %N2, %0"
14894 : "mshfhi.l %N1, %N2, %0");
14896 [(set_attr "type" "arith_media")
14897 (set (attr "highpart")
14898 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14899 (const_string "user")))])
14901 (define_expand "mshfhi_w"
14902 [(match_operand:V4HI 0 "arith_reg_dest" "")
14903 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14904 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14907 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14908 (operands[0], operands[1], operands[2]));
14912 (define_expand "mshflo_w"
14913 [(match_operand:V4HI 0 "arith_reg_dest" "")
14914 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14915 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14918 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14919 (operands[0], operands[1], operands[2]));
14923 (define_insn "mshf4_w"
14924 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14926 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14927 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14928 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
14931 return (TARGET_LITTLE_ENDIAN
14932 ? "mshfhi.w %N1, %N2, %0"
14933 : "mshflo.w %N1, %N2, %0");
14935 [(set_attr "type" "arith_media")
14936 (set (attr "highpart")
14937 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14938 (const_string "user")))])
14940 (define_insn "mshf0_w"
14941 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14943 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14944 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14945 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
14948 return (TARGET_LITTLE_ENDIAN
14949 ? "mshflo.w %N1, %N2, %0"
14950 : "mshfhi.w %N1, %N2, %0");
14952 [(set_attr "type" "arith_media")
14953 (set (attr "highpart")
14954 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14955 (const_string "user")))])
14957 (define_insn "mshflo_w_x"
14958 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14960 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
14961 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
14962 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
14964 "mshflo.w %N1, %N2, %0"
14965 [(set_attr "type" "arith_media")
14966 (set_attr "highpart" "ignore")])
14968 ;; These are useful to expand ANDs and as combiner patterns.
14969 (define_insn_and_split "mshfhi_l_di"
14970 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
14971 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
14973 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
14974 (const_int -4294967296))))]
14977 mshfhi.l %N1, %N2, %0
14979 "TARGET_SHMEDIA && reload_completed
14980 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14981 [(set (match_dup 3) (match_dup 4))
14982 (set (match_dup 5) (match_dup 6))]
14984 operands[3] = gen_lowpart (SImode, operands[0]);
14985 operands[4] = gen_highpart (SImode, operands[1]);
14986 operands[5] = gen_highpart (SImode, operands[0]);
14987 operands[6] = gen_highpart (SImode, operands[2]);
14989 [(set_attr "type" "arith_media")])
14991 (define_insn "*mshfhi_l_di_rev"
14992 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14993 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14994 (const_int -4294967296))
14995 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14998 "mshfhi.l %N2, %N1, %0"
14999 [(set_attr "type" "arith_media")])
15002 [(set (match_operand:DI 0 "arith_reg_dest" "")
15003 (ior:DI (zero_extend:DI (match_operand:SI 1
15004 "extend_reg_or_0_operand" ""))
15005 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
15006 (const_int -4294967296))))
15007 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
15011 emit_insn (gen_ashldi3_media (operands[3],
15012 simplify_gen_subreg (DImode, operands[1],
15015 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
15019 (define_insn "mshflo_l_di"
15020 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15021 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15022 (const_int 4294967295))
15023 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15027 "mshflo.l %N1, %N2, %0"
15028 [(set_attr "type" "arith_media")
15029 (set_attr "highpart" "ignore")])
15031 (define_insn "*mshflo_l_di_rev"
15032 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15033 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15035 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15036 (const_int 4294967295))))]
15039 "mshflo.l %N2, %N1, %0"
15040 [(set_attr "type" "arith_media")
15041 (set_attr "highpart" "ignore")])
15043 ;; Combiner pattern for trampoline initialization.
15044 (define_insn_and_split "*double_shori"
15045 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15046 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
15048 (match_operand:DI 2 "const_int_operand" "n")))]
15050 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
15052 "rtx_equal_p (operands[0], operands[1])"
15055 HOST_WIDE_INT v = INTVAL (operands[2]);
15057 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
15058 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
15061 [(set_attr "highpart" "ignore")])
15063 (define_insn "*mshflo_l_di_x"
15064 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15065 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
15067 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
15070 "mshflo.l %N1, %N2, %0"
15071 [(set_attr "type" "arith_media")
15072 (set_attr "highpart" "ignore")])
15074 (define_insn_and_split "concat_v2sf"
15075 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
15076 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
15077 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
15078 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
15081 mshflo.l %N1, %N2, %0
15084 "TARGET_SHMEDIA && reload_completed
15085 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
15086 [(set (match_dup 3) (match_dup 1))
15087 (set (match_dup 4) (match_dup 2))]
15089 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
15090 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
15092 [(set_attr "type" "arith_media")
15093 (set_attr "highpart" "ignore")])
15095 (define_insn "*mshflo_l_di_x_rev"
15096 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15097 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
15100 (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
15102 "mshflo.l %N2, %N1, %0"
15103 [(set_attr "type" "arith_media")
15104 (set_attr "highpart" "ignore")])
15106 (define_insn "ashlv2si3"
15107 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15108 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15109 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15111 "mshlld.l %1, %2, %0"
15112 [(set_attr "type" "arith_media")
15113 (set_attr "highpart" "depend")])
15116 [(set (match_operand 0 "any_register_operand" "")
15117 (match_operator 3 "shift_operator"
15118 [(match_operand 1 "any_register_operand" "")
15119 (match_operand 2 "shift_count_reg_operand" "")]))]
15120 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
15121 [(set (match_dup 0) (match_dup 3))]
15123 rtx count = operands[2];
15124 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
15126 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
15127 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
15128 || GET_CODE (count) == TRUNCATE)
15129 count = XEXP (count, 0);
15130 inner_mode = GET_MODE (count);
15131 count = simplify_gen_subreg (outer_mode, count, inner_mode,
15132 subreg_lowpart_offset (outer_mode, inner_mode));
15133 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
15134 operands[1], count);
15137 (define_insn "ashlv4hi3"
15138 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15139 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15140 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15142 "mshlld.w %1, %2, %0"
15143 [(set_attr "type" "arith_media")
15144 (set_attr "highpart" "depend")])
15146 (define_insn "lshrv2si3"
15147 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15148 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
15149 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15151 "mshlrd.l %1, %2, %0"
15152 [(set_attr "type" "arith_media")
15153 (set_attr "highpart" "depend")])
15155 (define_insn "lshrv4hi3"
15156 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15157 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
15158 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
15160 "mshlrd.w %1, %2, %0"
15161 [(set_attr "type" "arith_media")
15162 (set_attr "highpart" "depend")])
15164 (define_insn "subv2si3"
15165 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15166 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15167 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15169 "msub.l %N1, %2, %0"
15170 [(set_attr "type" "arith_media")
15171 (set_attr "highpart" "depend")])
15173 (define_insn "subv4hi3"
15174 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15175 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15176 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15178 "msub.w %N1, %2, %0"
15179 [(set_attr "type" "arith_media")
15180 (set_attr "highpart" "depend")])
15182 (define_insn_and_split "subv2hi3"
15183 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
15184 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
15185 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
15191 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
15192 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
15193 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
15194 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
15195 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
15197 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
15198 emit_insn (gen_truncdisi2 (si_dst, di_dst));
15201 [(set_attr "highpart" "must_split")])
15203 (define_insn "sssubv2si3"
15204 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
15205 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
15206 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
15208 "msubs.l %N1, %2, %0"
15209 [(set_attr "type" "mcmp_media")
15210 (set_attr "highpart" "depend")])
15212 (define_insn "ussubv8qi3"
15213 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15214 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
15215 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
15217 "msubs.ub %N1, %2, %0"
15218 [(set_attr "type" "mcmp_media")
15219 (set_attr "highpart" "depend")])
15221 (define_insn "sssubv4hi3"
15222 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
15223 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
15224 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
15226 "msubs.w %N1, %2, %0"
15227 [(set_attr "type" "mcmp_media")
15228 (set_attr "highpart" "depend")])
15230 ;; -------------------------------------------------------------------------
15231 ;; Floating Point Intrinsics
15232 ;; -------------------------------------------------------------------------
15234 (define_insn "fcosa_s"
15235 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15236 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
15240 [(set_attr "type" "atrans_media")])
15242 (define_insn "fsina_s"
15243 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15244 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
15248 [(set_attr "type" "atrans_media")])
15250 (define_insn "fipr"
15251 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15252 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
15253 "fp_arith_reg_operand" "f")
15254 (match_operand:V4SF 2
15255 "fp_arith_reg_operand" "f"))
15256 (parallel [(const_int 0)]))
15257 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15258 (parallel [(const_int 1)])))
15259 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15260 (parallel [(const_int 2)]))
15261 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
15262 (parallel [(const_int 3)])))))]
15264 "fipr.s %1, %2, %0"
15265 [(set_attr "type" "fparith_media")])
15267 (define_insn "fsrra_s"
15268 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
15269 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
15273 [(set_attr "type" "atrans_media")])
15275 (define_insn "ftrv"
15276 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
15280 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
15281 (parallel [(const_int 0) (const_int 5)
15282 (const_int 10) (const_int 15)]))
15283 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
15285 (vec_select:V4SF (match_dup 1)
15286 (parallel [(const_int 4) (const_int 9)
15287 (const_int 14) (const_int 3)]))
15288 (vec_select:V4SF (match_dup 2)
15289 (parallel [(const_int 1) (const_int 2)
15290 (const_int 3) (const_int 0)]))))
15293 (vec_select:V4SF (match_dup 1)
15294 (parallel [(const_int 8) (const_int 13)
15295 (const_int 2) (const_int 7)]))
15296 (vec_select:V4SF (match_dup 2)
15297 (parallel [(const_int 2) (const_int 3)
15298 (const_int 0) (const_int 1)])))
15300 (vec_select:V4SF (match_dup 1)
15301 (parallel [(const_int 12) (const_int 1)
15302 (const_int 6) (const_int 11)]))
15303 (vec_select:V4SF (match_dup 2)
15304 (parallel [(const_int 3) (const_int 0)
15305 (const_int 1) (const_int 2)]))))))]
15307 "ftrv.s %1, %2, %0"
15308 [(set_attr "type" "fparith_media")])
15310 (define_insn "ldhi_l"
15311 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15313 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15316 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
15320 [(set_attr "type" "load_media")])
15322 (define_insn "ldhi_q"
15323 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15325 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
15328 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
15332 [(set_attr "type" "load_media")])
15334 (define_insn_and_split "*ldhi_q_comb0"
15335 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15337 (mem:DI (plus:SI (ior:SI (plus:SI
15338 (match_operand:SI 1 "register_operand" "r")
15339 (match_operand:SI 2 "ua_offset" "I06"))
15342 (plus:SI (and:SI (match_dup 1) (const_int 7))
15345 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15350 emit_insn (gen_ldhi_q (operands[0],
15351 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15355 (define_insn_and_split "*ldhi_q_comb1"
15356 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15358 (mem:DI (plus:SI (ior:SI (plus:SI
15359 (match_operand:SI 1 "register_operand" "r")
15360 (match_operand:SI 2 "ua_offset" "I06"))
15363 (plus:SI (and:SI (plus:SI (match_dup 1)
15364 (match_operand:SI 3 "ua_offset" "I06"))
15368 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15369 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15374 emit_insn (gen_ldhi_q (operands[0],
15375 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15379 (define_insn "ldlo_l"
15380 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15382 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15384 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
15385 (and:SI (match_dup 1) (const_int 3))))]
15388 [(set_attr "type" "load_media")])
15390 (define_insn "ldlo_q"
15391 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15393 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
15395 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15396 (and:SI (match_dup 1) (const_int 7))))]
15399 [(set_attr "type" "load_media")])
15401 (define_insn_and_split "*ldlo_q_comb0"
15402 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15404 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15405 (match_operand:SI 2 "ua_offset" "I06"))
15407 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
15408 (and:SI (match_dup 1) (const_int 7))))]
15409 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
15414 emit_insn (gen_ldlo_q (operands[0],
15415 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15419 (define_insn_and_split "*ldlo_q_comb1"
15420 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15422 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
15423 (match_operand:SI 2 "ua_offset" "I06"))
15425 (minus:SI (const_int 8)
15426 (and:SI (plus:SI (match_dup 1)
15427 (match_operand:SI 3 "ua_offset" "I06"))
15429 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
15430 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
15431 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
15436 emit_insn (gen_ldlo_q (operands[0],
15437 gen_rtx_PLUS (SImode, operands[1], operands[2])));
15441 (define_insn "sthi_l"
15442 [(set (zero_extract:SI
15443 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15446 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
15448 (match_operand:SI 1 "arith_reg_operand" "r"))]
15451 [(set_attr "type" "ustore_media")])
15453 ;; All unaligned stores are considered to be 'narrow' because they typically
15454 ;; operate on less that a quadword, and when they operate on a full quadword,
15455 ;; the vanilla store high / store low sequence will cause a stall if not
15456 ;; scheduled apart.
15457 (define_insn "sthi_q"
15458 [(set (zero_extract:DI
15459 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
15462 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15464 (match_operand:DI 1 "arith_reg_operand" "r"))]
15467 [(set_attr "type" "ustore_media")])
15469 (define_insn_and_split "*sthi_q_comb0"
15470 [(set (zero_extract:DI
15471 (mem:DI (plus:SI (ior:SI (plus:SI
15472 (match_operand:SI 0 "register_operand" "r")
15473 (match_operand:SI 1 "ua_offset" "I06"))
15476 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
15478 (match_operand:DI 2 "arith_reg_operand" "r"))]
15479 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15484 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15489 (define_insn_and_split "*sthi_q_comb1"
15490 [(set (zero_extract:DI
15491 (mem:DI (plus:SI (ior:SI (plus:SI
15492 (match_operand:SI 0 "register_operand" "r")
15493 (match_operand:SI 1 "ua_offset" "I06"))
15496 (plus:SI (and:SI (plus:SI (match_dup 0)
15497 (match_operand:SI 2 "ua_offset" "I06"))
15501 (match_operand:DI 3 "arith_reg_operand" "r"))]
15502 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
15503 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15508 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15513 ;; This is highpart user because the address is used as full 64 bit.
15514 (define_insn "stlo_l"
15515 [(set (zero_extract:SI
15516 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15518 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
15519 (and:SI (match_dup 0) (const_int 3)))
15520 (match_operand:SI 1 "arith_reg_operand" "r"))]
15523 [(set_attr "type" "ustore_media")])
15525 (define_insn "stlo_q"
15526 [(set (zero_extract:DI
15527 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
15529 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15530 (and:SI (match_dup 0) (const_int 7)))
15531 (match_operand:DI 1 "arith_reg_operand" "r"))]
15534 [(set_attr "type" "ustore_media")])
15536 (define_insn_and_split "*stlo_q_comb0"
15537 [(set (zero_extract:DI
15538 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15539 (match_operand:SI 1 "ua_offset" "I06"))
15541 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
15542 (and:SI (match_dup 0) (const_int 7)))
15543 (match_operand:DI 2 "arith_reg_operand" "r"))]
15544 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15549 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15554 (define_insn_and_split "*stlo_q_comb1"
15555 [(set (zero_extract:DI
15556 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15557 (match_operand:SI 1 "ua_offset" "I06"))
15559 (minus:SI (const_int 8)
15560 (and:SI (plus:SI (match_dup 0)
15561 (match_operand:SI 2 "ua_offset" "I06"))
15563 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15564 (match_operand:DI 3 "arith_reg_operand" "r"))]
15565 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15570 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15575 (define_insn "ldhi_l64"
15576 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15578 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15581 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15585 [(set_attr "type" "load_media")])
15587 (define_insn "ldhi_q64"
15588 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15590 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15593 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15597 [(set_attr "type" "load_media")])
15599 (define_insn "ldlo_l64"
15600 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15602 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15604 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15605 (and:DI (match_dup 1) (const_int 3))))]
15608 [(set_attr "type" "load_media")])
15610 (define_insn "ldlo_q64"
15611 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15613 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15615 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15616 (and:DI (match_dup 1) (const_int 7))))]
15619 [(set_attr "type" "load_media")])
15621 (define_insn "sthi_l64"
15622 [(set (zero_extract:SI
15623 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15626 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15628 (match_operand:SI 1 "arith_reg_operand" "r"))]
15631 [(set_attr "type" "ustore_media")])
15633 (define_insn "sthi_q64"
15634 [(set (zero_extract:DI
15635 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15638 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15640 (match_operand:DI 1 "arith_reg_operand" "r"))]
15643 [(set_attr "type" "ustore_media")])
15645 (define_insn "stlo_l64"
15646 [(set (zero_extract:SI
15647 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15649 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15650 (and:DI (match_dup 0) (const_int 3)))
15651 (match_operand:SI 1 "arith_reg_operand" "r"))]
15654 [(set_attr "type" "ustore_media")])
15656 (define_insn "stlo_q64"
15657 [(set (zero_extract:DI
15658 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15660 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15661 (and:DI (match_dup 0) (const_int 7)))
15662 (match_operand:DI 1 "arith_reg_operand" "r"))]
15665 [(set_attr "type" "ustore_media")])
15668 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15669 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15673 [(set_attr "type" "arith_media")])
15675 (define_insn "nsbsi"
15676 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15678 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15682 [(set_attr "type" "arith_media")])
15684 (define_insn "nsbdi"
15685 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15687 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15691 [(set_attr "type" "arith_media")])
15693 (define_expand "ffsdi2"
15694 [(set (match_operand:DI 0 "arith_reg_dest" "")
15695 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15698 rtx scratch = gen_reg_rtx (DImode);
15701 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15702 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15703 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15704 emit_insn (gen_nsbdi (scratch, scratch));
15705 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15706 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15707 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15708 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15713 (define_expand "ffssi2"
15714 [(set (match_operand:SI 0 "arith_reg_dest" "")
15715 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15718 rtx scratch = gen_reg_rtx (SImode);
15719 rtx discratch = gen_reg_rtx (DImode);
15722 emit_insn (gen_adddi3 (discratch,
15723 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15725 emit_insn (gen_andcdi3 (discratch,
15726 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15728 emit_insn (gen_nsbsi (scratch, discratch));
15729 last = emit_insn (gen_subsi3 (operands[0],
15730 force_reg (SImode, GEN_INT (63)), scratch));
15731 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15736 (define_insn "byterev"
15737 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15738 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15739 (parallel [(const_int 7) (const_int 6) (const_int 5)
15740 (const_int 4) (const_int 3) (const_int 2)
15741 (const_int 1) (const_int 0)])))]
15744 [(set_attr "type" "arith_media")])
15746 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15747 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
15748 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15749 (define_expand "prefetch"
15750 [(prefetch (match_operand 0 "address_operand" "")
15751 (match_operand:SI 1 "const_int_operand" "")
15752 (match_operand:SI 2 "const_int_operand" ""))]
15753 "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15754 && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15756 (define_insn "*prefetch"
15757 [(prefetch (match_operand:SI 0 "register_operand" "r")
15758 (match_operand:SI 1 "const_int_operand" "n")
15759 (match_operand:SI 2 "const_int_operand" "n"))]
15760 "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15762 [(set_attr "type" "other")])
15764 (define_insn "*prefetch_media"
15765 [(prefetch (match_operand:QI 0 "address_operand" "p")
15766 (match_operand:SI 1 "const_int_operand" "n")
15767 (match_operand:SI 2 "const_int_operand" "n"))]
15770 operands[0] = gen_rtx_MEM (QImode, operands[0]);
15771 output_asm_insn ("ld%M0.b %m0,r63", operands);
15774 [(set_attr "type" "other")])
15776 (define_insn "alloco_i"
15777 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15778 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15783 if (GET_CODE (operands[0]) == PLUS)
15785 xops[0] = XEXP (operands[0], 0);
15786 xops[1] = XEXP (operands[0], 1);
15790 xops[0] = operands[0];
15791 xops[1] = const0_rtx;
15793 output_asm_insn ("alloco %0, %1", xops);
15796 [(set_attr "type" "other")])
15799 [(set (match_operand 0 "any_register_operand" "")
15800 (match_operand 1 "" ""))]
15801 "TARGET_SHMEDIA && reload_completed"
15802 [(set (match_dup 0) (match_dup 1))]
15806 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
15811 ;; -------------------------------------------------------------------------
15812 ;; Stack Protector Patterns
15813 ;; -------------------------------------------------------------------------
15815 (define_expand "stack_protect_set"
15816 [(set (match_operand 0 "memory_operand" "")
15817 (match_operand 1 "memory_operand" ""))]
15820 if (TARGET_SHMEDIA)
15822 if (TARGET_SHMEDIA64)
15823 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15825 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15828 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15833 (define_insn "stack_protect_set_si"
15834 [(set (match_operand:SI 0 "memory_operand" "=m")
15835 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15836 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15839 return "mov.l %1,%2" "\n"
15840 " mov.l %2,%0" "\n"
15843 [(set_attr "type" "other")
15844 (set_attr "length" "6")])
15846 (define_insn "stack_protect_set_si_media"
15847 [(set (match_operand:SI 0 "memory_operand" "=m")
15848 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15849 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15852 return "ld%M1.l %m1,%2" "\n"
15853 " st%M0.l %m0,%2" "\n"
15856 [(set_attr "type" "other")
15857 (set_attr "length" "12")])
15859 (define_insn "stack_protect_set_di_media"
15860 [(set (match_operand:DI 0 "memory_operand" "=m")
15861 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15862 (set (match_scratch:DI 2 "=&r") (const_int 0))]
15865 return "ld%M1.q %m1,%2" "\n"
15866 " st%M0.q %m0,%2" "\n"
15869 [(set_attr "type" "other")
15870 (set_attr "length" "12")])
15872 (define_expand "stack_protect_test"
15873 [(match_operand 0 "memory_operand" "")
15874 (match_operand 1 "memory_operand" "")
15875 (match_operand 2 "" "")]
15878 if (TARGET_SHMEDIA)
15880 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15883 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15884 if (TARGET_SHMEDIA64)
15886 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15888 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15892 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15894 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15899 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15900 emit_jump_insn (gen_branch_true (operands[2]));
15906 (define_insn "stack_protect_test_si"
15907 [(set (reg:SI T_REG)
15908 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15909 (match_operand:SI 1 "memory_operand" "m")]
15911 (set (match_scratch:SI 2 "=&r") (const_int 0))
15912 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15915 return "mov.l %0,%2" "\n"
15916 " mov.l %1,%3" "\n"
15917 " cmp/eq %2,%3" "\n"
15921 [(set_attr "type" "other")
15922 (set_attr "length" "10")])
15924 (define_insn "stack_protect_test_si_media"
15925 [(set (match_operand:SI 0 "register_operand" "=&r")
15926 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15927 (match_operand:SI 2 "memory_operand" "m")]
15929 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15932 return "ld%M1.l %m1,%0" "\n"
15933 " ld%M2.l %m2,%3" "\n"
15934 " cmpeq %0,%3,%0" "\n"
15937 [(set_attr "type" "other")
15938 (set_attr "length" "16")])
15940 (define_insn "stack_protect_test_di_media"
15941 [(set (match_operand:DI 0 "register_operand" "=&r")
15942 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
15943 (match_operand:DI 2 "memory_operand" "m")]
15945 (set (match_scratch:DI 3 "=&r") (const_int 0))]
15948 return "ld%M1.q %m1,%0" "\n"
15949 " ld%M2.q %m2,%3" "\n"
15950 " cmpeq %0,%3,%0" "\n"
15953 [(set_attr "type" "other")
15954 (set_attr "length" "16")])
15956 ;; -------------------------------------------------------------------------
15957 ;; Atomic operations
15958 ;; -------------------------------------------------------------------------
15960 (include "sync.md")