1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;; Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
145 (UNSPEC_DIV_INV_M0 30)
146 (UNSPEC_DIV_INV_M1 31)
147 (UNSPEC_DIV_INV_M2 32)
148 (UNSPEC_DIV_INV_M3 33)
149 (UNSPEC_DIV_INV20 34)
150 (UNSPEC_DIV_INV_TABLE 37)
158 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160 (UNSPEC_EXTRACT_S16 43)
161 (UNSPEC_EXTRACT_U16 44)
163 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
166 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167 (UNSPEC_PCREL_SYMOFF 46)
169 ;; These are used with unspec_volatile.
175 (UNSPECV_WINDOW_END 10)
176 (UNSPECV_CONST_END 11)
177 (UNSPECV_EH_RETURN 12)
181 ;; -------------------------------------------------------------------------
183 ;; -------------------------------------------------------------------------
188 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
189 (const (symbol_ref "sh_cpu_attr")))
191 (define_attr "endian" "big,little"
192 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
193 (const_string "little") (const_string "big"))))
195 ;; Indicate if the default fpu mode is single precision.
196 (define_attr "fpu_single" "yes,no"
197 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
198 (const_string "yes") (const_string "no"))))
200 (define_attr "fmovd" "yes,no"
201 (const (if_then_else (symbol_ref "TARGET_FMOVD")
202 (const_string "yes") (const_string "no"))))
204 (define_attr "pipe_model" "sh1,sh4,sh5media"
206 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
207 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
208 (const_string "sh1"))))
210 ;; cbranch conditional branch instructions
211 ;; jump unconditional jumps
212 ;; arith ordinary arithmetic
213 ;; arith3 a compound insn that behaves similarly to a sequence of
214 ;; three insns of type arith
215 ;; arith3b like above, but might end with a redirected branch
217 ;; load_si Likewise, SImode variant for general register.
218 ;; fload Likewise, but load to fp register.
220 ;; fstore floating point register to memory
221 ;; move general purpose register to register
222 ;; movi8 8-bit immediate to general purpose register
223 ;; mt_group other sh4 mt instructions
224 ;; fmove register to register, floating point
225 ;; smpy word precision integer multiply
226 ;; dmpy longword or doublelongword precision integer multiply
228 ;; pload load of pr reg, which can't be put into delay slot of rts
229 ;; prset copy register to pr reg, ditto
230 ;; pstore store of pr reg, which can't be put into delay slot of jsr
231 ;; prget copy pr to register, ditto
232 ;; pcload pc relative load of constant value
233 ;; pcfload Likewise, but load to fp register.
234 ;; pcload_si Likewise, SImode variant for general register.
235 ;; rte return from exception
236 ;; sfunc special function call with known used registers
237 ;; call function call
239 ;; fpscr_toggle toggle a bit in the fpscr
240 ;; fdiv floating point divide (or square root)
241 ;; gp_fpul move from general purpose register to fpul
242 ;; fpul_gp move from fpul to general purpose register
243 ;; mac_gp move from mac[lh] to general purpose register
244 ;; gp_mac move from general purpose register to mac[lh]
245 ;; mac_mem move from mac[lh] to memory
246 ;; mem_mac move from memory to mac[lh]
247 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
248 ;; ftrc_s fix_truncsfsi2_i4
249 ;; dfdiv double precision floating point divide (or square root)
250 ;; cwb ic_invalidate_line_i
251 ;; movua SH4a unaligned load
252 ;; fsrra square root reciprocal approximate
253 ;; fsca sine and cosine approximate
254 ;; tls_load load TLS related address
255 ;; arith_media SHmedia arithmetic, logical, and shift instructions
256 ;; cbranch_media SHmedia conditional branch instructions
257 ;; cmp_media SHmedia compare instructions
258 ;; dfdiv_media SHmedia double precision divide and square root
259 ;; dfmul_media SHmedia double precision multiply instruction
260 ;; dfparith_media SHmedia double precision floating point arithmetic
261 ;; dfpconv_media SHmedia double precision floating point conversions
262 ;; dmpy_media SHmedia longword multiply
263 ;; fcmp_media SHmedia floating point compare instructions
264 ;; fdiv_media SHmedia single precision divide and square root
265 ;; fload_media SHmedia floating point register load instructions
266 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
267 ;; fparith_media SHmedia single precision floating point arithmetic
268 ;; fpconv_media SHmedia single precision floating point conversions
269 ;; fstore_media SHmedia floating point register store instructions
270 ;; gettr_media SHmedia gettr instruction
271 ;; invalidate_line_media SHmedia invalidate_line sequence
272 ;; jump_media SHmedia unconditional branch instructions
273 ;; load_media SHmedia general register load instructions
274 ;; pt_media SHmedia pt instruction (expanded by assembler)
275 ;; ptabs_media SHmedia ptabs instruction
276 ;; store_media SHmedia general register store instructions
277 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
278 ;; mac_media SHmedia mac-style fixed point operations
279 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
280 ;; atrans_media SHmedia approximate transcendental functions
281 ;; ustore_media SHmedia unaligned stores
282 ;; nil no-op move, will be deleted.
285 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
286 (const_string "other"))
288 ;; We define a new attribute namely "insn_class".We use
289 ;; this for the DFA based pipeline description.
291 ;; mt_group SH4 "mt" group instructions.
293 ;; ex_group SH4 "ex" group instructions.
295 ;; ls_group SH4 "ls" group instructions.
298 (define_attr "insn_class"
299 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
300 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
301 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
302 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
303 (eq_attr "type" "cbranch,jump") (const_string "br_group")
304 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
305 (const_string "fe_group")
306 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
307 (const_string "none")))
308 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
309 ;; so these do not belong in an insn group, although they are modeled
310 ;; with their own define_insn_reservations.
312 ;; Indicate what precision must be selected in fpscr for this insn, if any.
314 (define_attr "fp_mode" "single,double,none" (const_string "none"))
316 ;; Indicate if the fpu mode is set by this instruction
317 ;; "unknown" must have the value as "none" in fp_mode, and means
318 ;; that the instruction/abi has left the processor in an unknown
320 ;; "none" means that nothing has changed and no mode is set.
321 ;; This attribute is only used for the Renesas ABI.
322 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
324 ; If a conditional branch destination is within -252..258 bytes away
325 ; from the instruction it can be 2 bytes long. Something in the
326 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
327 ; branches are initially assumed to be 16 bytes long.
328 ; In machine_dependent_reorg, we split all branches that are longer than
331 ;; The maximum range used for SImode constant pool entries is 1018. A final
332 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
333 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
334 ;; instruction around the pool table, 2 bytes of alignment before the table,
335 ;; and 30 bytes of alignment after the table. That gives a maximum total
336 ;; pool size of 1058 bytes.
337 ;; Worst case code/pool content size ratio is 1:2 (using asms).
338 ;; Thus, in the worst case, there is one instruction in front of a maximum
339 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
340 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
341 ;; If we have a forward branch, the initial table will be put after the
342 ;; unconditional branch.
344 ;; ??? We could do much better by keeping track of the actual pcloads within
345 ;; the branch range and in the pcload range in front of the branch range.
347 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
349 (define_attr "short_cbranch_p" "no,yes"
350 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
354 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
358 ] (const_string "no")))
360 (define_attr "med_branch_p" "no,yes"
361 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
364 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
366 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
369 ] (const_string "no")))
371 (define_attr "med_cbranch_p" "no,yes"
372 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
375 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
380 ] (const_string "no")))
382 (define_attr "braf_branch_p" "no,yes"
383 (cond [(match_test "! TARGET_SH2")
385 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
388 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
390 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
393 ] (const_string "no")))
395 (define_attr "braf_cbranch_p" "no,yes"
396 (cond [(match_test "! TARGET_SH2")
398 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
401 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
403 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
406 ] (const_string "no")))
408 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
409 ; For wider ranges, we need a combination of a code and a data part.
410 ; If we can get a scratch register for a long range jump, the code
411 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
412 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
413 ; long; otherwise, it must be 6 bytes long.
415 ; All other instructions are two bytes long by default.
417 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
418 ;; but getattrtab doesn't understand this.
419 (define_attr "length" ""
420 (cond [(eq_attr "type" "cbranch")
421 (cond [(eq_attr "short_cbranch_p" "yes")
423 (eq_attr "med_cbranch_p" "yes")
425 (eq_attr "braf_cbranch_p" "yes")
427 ;; ??? using pc is not computed transitively.
428 (ne (match_dup 0) (match_dup 0))
430 (match_test "flag_pic")
433 (eq_attr "type" "jump")
434 (cond [(eq_attr "med_branch_p" "yes")
436 (and (match_test "prev_nonnote_insn (insn)")
437 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))") (symbol_ref "INSN"))
438 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))") (symbol_ref "code_for_indirect_jump_scratch"))))
439 (cond [(eq_attr "braf_branch_p" "yes")
441 (not (match_test "flag_pic"))
443 (match_test "TARGET_SH2")
444 (const_int 10)] (const_int 18))
445 (eq_attr "braf_branch_p" "yes")
447 ;; ??? using pc is not computed transitively.
448 (ne (match_dup 0) (match_dup 0))
450 (match_test "flag_pic")
453 (eq_attr "type" "pt_media")
454 (if_then_else (match_test "TARGET_SHMEDIA64")
455 (const_int 20) (const_int 12))
456 (and (eq_attr "type" "jump_media")
457 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
459 ] (if_then_else (match_test "TARGET_SHMEDIA")
463 ;; DFA descriptions for the pipelines
466 (include "shmedia.md")
469 (include "iterators.md")
470 (include "predicates.md")
471 (include "constraints.md")
473 ;; Definitions for filling delay slots
475 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
477 (define_attr "banked" "yes,no"
478 (cond [(match_test "sh_loads_bankedreg_p (insn)")
479 (const_string "yes")]
480 (const_string "no")))
482 ;; ??? This should be (nil) instead of (const_int 0)
483 (define_attr "hit_stack" "yes,no"
484 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
486 (const_string "yes")))
488 (define_attr "interrupt_function" "no,yes"
489 (const (symbol_ref "current_function_interrupt")))
491 (define_attr "in_delay_slot" "yes,no"
492 (cond [(eq_attr "type" "cbranch") (const_string "no")
493 (eq_attr "type" "pcload,pcload_si") (const_string "no")
494 (eq_attr "needs_delay_slot" "yes") (const_string "no")
495 (eq_attr "length" "2") (const_string "yes")
496 ] (const_string "no")))
498 (define_attr "cond_delay_slot" "yes,no"
499 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
500 ] (const_string "no")))
502 (define_attr "is_sfunc" ""
503 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
505 (define_attr "is_mac_media" ""
506 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
508 (define_attr "branch_zero" "yes,no"
509 (cond [(eq_attr "type" "!cbranch") (const_string "no")
510 (ne (symbol_ref "(next_active_insn (insn)\
511 == (prev_active_insn\
512 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
513 && get_attr_length (next_active_insn (insn)) == 2")
515 (const_string "yes")]
516 (const_string "no")))
518 ;; SH4 Double-precision computation with double-precision result -
519 ;; the two halves are ready at different times.
520 (define_attr "dfp_comp" "yes,no"
521 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
522 (const_string "no")))
524 ;; Insns for which the latency of a preceding fp insn is decreased by one.
525 (define_attr "late_fp_use" "yes,no" (const_string "no"))
526 ;; And feeding insns for which this relevant.
527 (define_attr "any_fp_comp" "yes,no"
528 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
529 (const_string "yes")]
530 (const_string "no")))
532 (define_attr "any_int_load" "yes,no"
533 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
534 (const_string "yes")]
535 (const_string "no")))
537 (define_attr "highpart" "user, ignore, extend, depend, must_split"
538 (const_string "user"))
541 (eq_attr "needs_delay_slot" "yes")
542 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
544 ;; Since a normal return (rts) implicitly uses the PR register,
545 ;; we can't allow PR register loads in an rts delay slot.
546 ;; On the SH1* and SH2*, the rte instruction reads the return pc from the
547 ;; stack, and thus we can't put a pop instruction in its delay slot.
548 ;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
549 ;; pop instruction can go in the delay slot, unless it references a banked
550 ;; register (the register bank is switched by rte).
552 (eq_attr "type" "return")
553 [(and (eq_attr "in_delay_slot" "yes")
554 (ior (and (eq_attr "interrupt_function" "no")
555 (eq_attr "type" "!pload,prset"))
556 (and (eq_attr "interrupt_function" "yes")
557 (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
558 (eq_attr "banked" "no"))))
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
565 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566 [(and (eq_attr "in_delay_slot" "yes")
567 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
577 (and (eq_attr "type" "cbranch")
578 (match_test "TARGET_SH2"))
579 ;; SH2e has a hardware bug that pretty much prohibits the use of
580 ;; annulled delay slots.
581 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582 (not (eq_attr "cpu" "sh2e"))) (nil)])
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
588 ;; Various patterns to generate the TST #imm, R0 instruction.
589 ;; Although this adds some pressure on the R0 register, it can potentially
590 ;; result in faster code, even if the operand has to be moved to R0 first.
591 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group
592 ;; instructions and thus will be executed in parallel. On SH4A TST #imm, R0
593 ;; is an EX group instruction but still can be executed in parallel with the
594 ;; MT group MOV Rm, Rn instruction.
596 ;; Usual TST #imm, R0 patterns for SI, HI and QI
597 ;; This is usually used for bit patterns other than contiguous bits
600 (define_insn "tstsi_t"
602 (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603 (match_operand:SI 1 "logical_operand" "K08,r"))
607 [(set_attr "type" "mt_group")])
609 (define_insn "tsthi_t"
611 (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612 (match_operand 1 "const_int_operand")) 0)
615 && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
617 [(set_attr "type" "mt_group")])
619 (define_insn "tstqi_t"
621 (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622 (match_operand 1 "const_int_operand")) 0)
625 && (CONST_OK_FOR_K08 (INTVAL (operands[1]))
626 || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
628 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
631 [(set_attr "type" "mt_group")])
633 ;; Test low QI subreg against zero.
634 ;; This avoids unnecessary zero extension before the test.
636 (define_insn "tstqi_t_zero"
638 (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
641 [(set_attr "type" "mt_group")])
643 ;; Extract LSB, negate and store in T bit.
645 (define_insn "tstsi_t_and_not"
647 (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
651 [(set_attr "type" "mt_group")])
653 ;; Extract contiguous bits and compare them against zero.
655 (define_insn "tstsi_t_zero_extract_eq"
657 (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
658 (match_operand:SI 1 "const_int_operand")
659 (match_operand:SI 2 "const_int_operand"))
662 && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
664 operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
667 [(set_attr "type" "mt_group")])
669 ;; This split is required when testing bits in a QI subreg.
673 (eq:SI (if_then_else:SI (zero_extract:SI
674 (match_operand 0 "logical_operand" "")
675 (match_operand 1 "const_int_operand")
676 (match_operand 2 "const_int_operand"))
677 (match_operand 3 "const_int_operand")
681 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
682 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
683 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
686 if (GET_MODE (operands[0]) == QImode)
687 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
690 ;; Extract single bit, negate and store it in the T bit.
691 ;; Not used for SH4A.
693 (define_insn "tstsi_t_zero_extract_xor"
695 (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
696 (match_operand:SI 3 "const_int_operand"))
697 (match_operand:SI 1 "const_int_operand")
698 (match_operand:SI 2 "const_int_operand")))]
700 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
701 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
703 [(set_attr "type" "mt_group")])
705 ;; Extract single bit, negate and store it in the T bit.
706 ;; Used for SH4A little endian.
708 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
711 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
712 (match_operand:SI 3 "const_int_operand")) 0)
713 (match_operand:SI 1 "const_int_operand")
714 (match_operand:SI 2 "const_int_operand")))]
715 "TARGET_SH1 && TARGET_LITTLE_ENDIAN
716 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
717 == (INTVAL (operands[3]) & 255)
718 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
720 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
723 [(set_attr "type" "mt_group")])
725 ;; Extract single bit, negate and store it in the T bit.
726 ;; Used for SH4A big endian.
728 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
731 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
732 (match_operand:SI 3 "const_int_operand")) 3)
733 (match_operand:SI 1 "const_int_operand")
734 (match_operand:SI 2 "const_int_operand")))]
735 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
736 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
737 == (INTVAL (operands[3]) & 255)
738 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
740 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
743 [(set_attr "type" "mt_group")])
745 (define_insn "cmpeqsi_t"
747 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
748 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
754 [(set_attr "type" "mt_group")])
756 ;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
757 ;; pattern by itself. What this actually does is:
758 ;; x == 0: (1 >> 0-0) & 1 = 1
759 ;; x != 0: (1 >> 0-x) & 1 = 0
760 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
761 (define_insn_and_split "*cmpeqsi_t"
765 (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
770 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
772 (define_insn "cmpgtsi_t"
774 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
775 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
780 [(set_attr "type" "mt_group")])
782 (define_insn "cmpgesi_t"
784 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
785 (match_operand:SI 1 "arith_reg_or_0_operand" "N,r")))]
790 [(set_attr "type" "mt_group")])
792 ;; FIXME: This is actually wrong. There is no way to literally move a
793 ;; general reg to t reg. Luckily, it seems that this pattern will be only
794 ;; used when the general reg is known be either '0' or '1' during combine.
795 ;; What we actually need is reg != 0 -> T, but we have only reg == 0 -> T.
796 ;; Due to interactions with other patterns, combine fails to pick the latter
797 ;; and invert the dependent logic.
798 (define_insn "*negtstsi"
799 [(set (reg:SI T_REG) (match_operand:SI 0 "arith_reg_operand" "r"))]
802 [(set_attr "type" "mt_group")])
804 ;; Some integer sign comparison patterns can be realized with the div0s insn.
805 ;; div0s Rm,Rn T = (Rm >> 31) ^ (Rn >> 31)
806 (define_insn "cmp_div0s_0"
808 (lshiftrt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
809 (match_operand:SI 1 "arith_reg_operand" "r"))
813 [(set_attr "type" "arith")])
815 (define_insn "cmp_div0s_1"
817 (lt:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "%r")
818 (match_operand:SI 1 "arith_reg_operand" "r"))
822 [(set_attr "type" "arith")])
824 (define_insn_and_split "*cmp_div0s_0"
825 [(set (match_operand:SI 0 "arith_reg_dest" "")
826 (lshiftrt:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
827 (match_operand:SI 2 "arith_reg_operand" ""))
829 (clobber (reg:SI T_REG))]
834 (lshiftrt:SI (xor:SI (match_dup 1) (match_dup 2)) (const_int 31)))
835 (set (match_dup 0) (reg:SI T_REG))])
837 (define_insn_and_split "*cmp_div0s_1"
838 [(set (match_operand:SI 0 "arith_reg_dest" "")
839 (ge:SI (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
840 (match_operand:SI 2 "arith_reg_operand" ""))
842 (clobber (reg:SI T_REG))]
845 "&& can_create_pseudo_p ()"
847 ;; We have to go through the movnegt expander here which will handle the
848 ;; SH2A vs non-SH2A cases.
850 emit_insn (gen_cmp_div0s_1 (operands[1], operands[2]));
851 emit_insn (gen_movnegt (operands[0], get_t_reg_rtx ()));
855 (define_insn_and_split "*cmp_div0s_1"
857 (ge:SI (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
858 (match_operand:SI 1 "arith_reg_operand" ""))
862 "&& can_create_pseudo_p ()"
863 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 0) (match_dup 1))
865 (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
868 ;; -------------------------------------------------------------------------
869 ;; SImode compare and branch
870 ;; -------------------------------------------------------------------------
872 (define_expand "cbranchsi4"
874 (if_then_else (match_operator 0 "comparison_operator"
875 [(match_operand:SI 1 "arith_operand" "")
876 (match_operand:SI 2 "arith_operand" "")])
877 (label_ref (match_operand 3 "" ""))
879 (clobber (reg:SI T_REG))]
883 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
884 operands[2], operands[3]));
886 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
891 ;; Combine patterns to invert compare and branch operations for which we
892 ;; don't have actual comparison insns. These patterns are used in cases
893 ;; which appear after the initial cbranchsi expansion, which also does
894 ;; some condition inversion.
898 (if_then_else (ne (match_operand:SI 0 "arith_reg_operand" "")
899 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
900 (label_ref (match_operand 2))
902 (clobber (reg:SI T_REG))]
904 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (match_dup 1)))
905 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
906 (label_ref (match_dup 2))
909 ;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
910 ;; and SH2A combine fails to simplify this pattern by itself.
911 ;; What this actually does is:
912 ;; x == 0: (1 >> 0-0) & 1 = 1
913 ;; x != 0: (1 >> 0-x) & 1 = 0
914 ;; Without this the test pr51244-8.c fails on SH2A and SH4A.
918 (eq (and:SI (lshiftrt:SI
920 (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
923 (label_ref (match_operand 2))
925 (clobber (reg:SI T_REG))]
927 [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
928 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
929 (label_ref (match_dup 2))
932 ;; FIXME: These could probably use code iterators for the compare op.
935 (if_then_else (le (match_operand:SI 0 "arith_reg_operand" "")
936 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
937 (label_ref (match_operand 2))
939 (clobber (reg:SI T_REG))]
941 [(set (reg:SI T_REG) (gt:SI (match_dup 0) (match_dup 1)))
942 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
943 (label_ref (match_dup 2))
948 (if_then_else (lt (match_operand:SI 0 "arith_reg_operand" "")
949 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
950 (label_ref (match_operand 2))
952 (clobber (reg:SI T_REG))]
954 [(set (reg:SI T_REG) (ge:SI (match_dup 0) (match_dup 1)))
955 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
956 (label_ref (match_dup 2))
961 (if_then_else (leu (match_operand:SI 0 "arith_reg_operand" "")
962 (match_operand:SI 1 "arith_reg_operand" ""))
963 (label_ref (match_operand 2))
965 (clobber (reg:SI T_REG))]
967 [(set (reg:SI T_REG) (gtu:SI (match_dup 0) (match_dup 1)))
968 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
969 (label_ref (match_dup 2))
974 (if_then_else (ltu (match_operand:SI 0 "arith_reg_operand" "")
975 (match_operand:SI 1 "arith_reg_operand" ""))
976 (label_ref (match_operand 2))
978 (clobber (reg:SI T_REG))]
980 [(set (reg:SI T_REG) (geu:SI (match_dup 0) (match_dup 1)))
981 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
982 (label_ref (match_dup 2))
985 ;; Compare and branch combine patterns for div0s comparisons.
986 (define_insn_and_split "*cbranch_div0s"
988 (if_then_else (lt (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
989 (match_operand:SI 1 "arith_reg_operand" ""))
991 (label_ref (match_operand 2))
993 (clobber (reg:SI T_REG))]
998 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1000 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1001 (label_ref (match_dup 2))
1004 (define_insn_and_split "*cbranch_div0s"
1006 (if_then_else (ge (xor:SI (match_operand:SI 0 "arith_reg_operand" "")
1007 (match_operand:SI 1 "arith_reg_operand" ""))
1009 (label_ref (match_operand 2))
1011 (clobber (reg:SI T_REG))]
1015 [(set (reg:SI T_REG)
1016 (lt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 0)))
1018 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1019 (label_ref (match_dup 2))
1022 ;; Conditional move combine pattern for div0s comparisons.
1023 ;; This is used when TARGET_PRETEND_CMOVE is in effect.
1024 (define_insn_and_split "*movsicc_div0s"
1025 [(set (match_operand:SI 0 "arith_reg_dest" "")
1026 (if_then_else:SI (ge (xor:SI (match_operand:SI 1 "arith_reg_operand" "")
1027 (match_operand:SI 2 "arith_reg_operand" ""))
1029 (match_operand:SI 3 "arith_reg_operand" "")
1030 (match_operand:SI 4 "general_movsrc_operand" "")))
1031 (clobber (reg:SI T_REG))]
1032 "TARGET_PRETEND_CMOVE"
1035 [(set (reg:SI T_REG) (lt:SI (xor:SI (match_dup 1) (match_dup 2))
1038 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1042 ;; -------------------------------------------------------------------------
1043 ;; SImode unsigned integer comparisons
1044 ;; -------------------------------------------------------------------------
1046 ;; Usually comparisons of 'unsigned int >= 0' are optimized away completely.
1047 ;; However, especially when optimizations are off (e.g. -O0) such comparisons
1048 ;; might remain and we have to handle them. If the '>= 0' case wasn't
1049 ;; handled here, something else would just load a '0' into the second operand
1050 ;; and do the comparison. We can do slightly better by just setting the
1052 (define_insn_and_split "cmpgeusi_t"
1053 [(set (reg:SI T_REG)
1054 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1055 (match_operand:SI 1 "arith_reg_or_0_operand" "r")))]
1058 "&& satisfies_constraint_Z (operands[1])"
1059 [(set (reg:SI T_REG) (const_int 1))]
1061 [(set_attr "type" "mt_group")])
1063 (define_insn "cmpgtusi_t"
1064 [(set (reg:SI T_REG)
1065 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1066 (match_operand:SI 1 "arith_reg_operand" "r")))]
1069 [(set_attr "type" "mt_group")])
1072 ;; -------------------------------------------------------------------------
1073 ;; DImode compare and branch
1074 ;; -------------------------------------------------------------------------
1077 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
1078 ;; Therefore, we aim to have a set of three branches that go straight to the
1079 ;; destination, i.e. only one of them is taken at any one time.
1080 ;; This mechanism should also be slightly better for the sh4-200.
1082 (define_expand "cbranchdi4"
1084 (if_then_else (match_operator 0 "comparison_operator"
1085 [(match_operand:DI 1 "arith_operand" "")
1086 (match_operand:DI 2 "arith_operand" "")])
1087 (label_ref (match_operand 3 "" ""))
1089 (clobber (match_dup 4))
1090 (clobber (reg:SI T_REG))]
1091 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
1093 enum rtx_code comparison;
1097 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
1098 operands[2], operands[3]));
1102 else if (!TARGET_CBRANCHDI4)
1104 sh_emit_compare_and_branch (operands, DImode);
1110 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
1113 comparison = prepare_cbranch_operands (operands, DImode,
1114 LAST_AND_UNUSED_RTX_CODE);
1115 if (comparison != GET_CODE (operands[0]))
1117 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
1118 operands[4] = gen_rtx_SCRATCH (SImode);
1122 (define_insn_and_split "cbranchdi4_i"
1124 (if_then_else (match_operator 0 "comparison_operator"
1125 [(match_operand:DI 1 "arith_operand" "r,r")
1126 (match_operand:DI 2 "arith_operand" "rN,I08")])
1127 (label_ref (match_operand 3 "" ""))
1129 (clobber (match_scratch:SI 4 "=X,&r"))
1130 (clobber (reg:SI T_REG))]
1133 "&& reload_completed"
1136 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
1141 ;; -------------------------------------------------------------------------
1142 ;; DImode signed integer comparisons
1143 ;; -------------------------------------------------------------------------
1146 [(set (reg:SI T_REG)
1147 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
1148 (match_operand:DI 1 "arith_operand" "r"))
1152 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
1155 [(set_attr "length" "6")
1156 (set_attr "type" "arith3b")])
1158 (define_insn "cmpeqdi_t"
1159 [(set (reg:SI T_REG)
1160 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1161 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
1164 static const char* alt[] =
1171 "cmp/eq %S1,%S0" "\n"
1173 " cmp/eq %R1,%R0" "\n"
1176 return alt[which_alternative];
1178 [(set_attr "length" "6")
1179 (set_attr "type" "arith3b")])
1182 [(set (reg:SI T_REG)
1183 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
1184 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
1185 ;; If we applied this split when not optimizing, it would only be
1186 ;; applied during the machine-dependent reorg, when no new basic blocks
1188 "TARGET_SH1 && reload_completed && optimize"
1189 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
1190 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
1191 (label_ref (match_dup 6))
1193 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
1196 operands[2] = gen_highpart (SImode, operands[0]);
1197 operands[3] = operands[1] == const0_rtx
1199 : gen_highpart (SImode, operands[1]);
1200 operands[4] = gen_lowpart (SImode, operands[0]);
1201 operands[5] = gen_lowpart (SImode, operands[1]);
1202 operands[6] = gen_label_rtx ();
1205 (define_insn "cmpgtdi_t"
1206 [(set (reg:SI T_REG)
1207 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1208 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1211 static const char* alt[] =
1213 "cmp/eq %S1,%S0" "\n"
1215 " cmp/gt %S1,%S0" "\n"
1216 " cmp/hi %R1,%R0" "\n"
1222 " cmp/hi %S0,%R0" "\n"
1225 return alt[which_alternative];
1227 [(set_attr "length" "8")
1228 (set_attr "type" "arith3")])
1230 (define_insn "cmpgedi_t"
1231 [(set (reg:SI T_REG)
1232 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
1233 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1236 static const char* alt[] =
1238 "cmp/eq %S1,%S0" "\n"
1240 " cmp/ge %S1,%S0" "\n"
1241 " cmp/hs %R1,%R0" "\n"
1246 return alt[which_alternative];
1248 [(set_attr "length" "8,2")
1249 (set_attr "type" "arith3,mt_group")])
1251 ;; -------------------------------------------------------------------------
1252 ;; DImode unsigned integer comparisons
1253 ;; -------------------------------------------------------------------------
1255 (define_insn "cmpgeudi_t"
1256 [(set (reg:SI T_REG)
1257 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1258 (match_operand:DI 1 "arith_reg_operand" "r")))]
1261 return "cmp/eq %S1,%S0" "\n"
1263 " cmp/hs %S1,%S0" "\n"
1264 " cmp/hs %R1,%R0" "\n"
1267 [(set_attr "length" "8")
1268 (set_attr "type" "arith3")])
1270 (define_insn "cmpgtudi_t"
1271 [(set (reg:SI T_REG)
1272 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
1273 (match_operand:DI 1 "arith_reg_operand" "r")))]
1276 return "cmp/eq %S1,%S0" "\n"
1278 " cmp/hi %S1,%S0" "\n"
1279 " cmp/hi %R1,%R0" "\n"
1282 [(set_attr "length" "8")
1283 (set_attr "type" "arith3")])
1285 (define_insn "cmpeqsi_media"
1286 [(set (match_operand:SI 0 "register_operand" "=r")
1287 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1288 (match_operand:SI 2 "cmp_operand" "Nr")))]
1291 [(set_attr "type" "cmp_media")])
1293 (define_insn "cmpeqdi_media"
1294 [(set (match_operand:SI 0 "register_operand" "=r")
1295 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1296 (match_operand:DI 2 "cmp_operand" "Nr")))]
1299 [(set_attr "type" "cmp_media")])
1301 (define_insn "cmpgtsi_media"
1302 [(set (match_operand:SI 0 "register_operand" "=r")
1303 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1304 (match_operand:SI 2 "cmp_operand" "rN")))]
1306 "cmpgt %N1, %N2, %0"
1307 [(set_attr "type" "cmp_media")])
1309 (define_insn "cmpgtdi_media"
1310 [(set (match_operand:SI 0 "register_operand" "=r")
1311 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1312 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1314 "cmpgt %N1, %N2, %0"
1315 [(set_attr "type" "cmp_media")])
1317 (define_insn "cmpgtusi_media"
1318 [(set (match_operand:SI 0 "register_operand" "=r")
1319 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1320 (match_operand:SI 2 "cmp_operand" "rN")))]
1322 "cmpgtu %N1, %N2, %0"
1323 [(set_attr "type" "cmp_media")])
1325 (define_insn "cmpgtudi_media"
1326 [(set (match_operand:SI 0 "register_operand" "=r")
1327 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1328 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1330 "cmpgtu %N1, %N2, %0"
1331 [(set_attr "type" "cmp_media")])
1333 ; This pattern is for combine.
1334 (define_insn "*cmpne0sisi_media"
1335 [(set (match_operand:SI 0 "register_operand" "=r")
1336 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1339 [(set_attr "type" "cmp_media")])
1341 ;; -------------------------------------------------------------------------
1342 ;; Conditional move instructions
1343 ;; -------------------------------------------------------------------------
1345 ;; The insn names may seem reversed, but note that cmveq performs the move
1346 ;; if op1 == 0, and cmvne does it if op1 != 0.
1348 (define_insn "movdicc_false"
1349 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1350 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1352 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1353 (match_operand:DI 3 "arith_reg_operand" "0")))]
1356 [(set_attr "type" "arith_media")])
1358 (define_insn "movdicc_true"
1359 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1360 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1362 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1363 (match_operand:DI 3 "arith_reg_operand" "0")))]
1366 [(set_attr "type" "arith_media")])
1369 [(set (match_operand:DI 0 "arith_reg_dest" "")
1370 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1371 [(match_operand:DI 1 "arith_reg_operand" "")
1373 (match_operand:DI 2 "arith_reg_dest" "")
1375 (set (match_dup 2) (match_dup 0))]
1376 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1378 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1380 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1381 VOIDmode, operands[1], CONST0_RTX (DImode));
1385 [(set (match_operand:DI 0 "general_movdst_operand" "")
1386 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1387 (set (match_operand:DI 2 "arith_reg_dest" "")
1388 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1389 [(match_operand:DI 3 "arith_reg_operand" "")
1393 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1395 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1398 (define_expand "movdicc"
1399 [(set (match_operand:DI 0 "register_operand" "")
1400 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1401 (match_operand:DI 2 "register_operand" "")
1402 (match_operand:DI 3 "register_operand" "")))]
1405 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1406 && GET_MODE (XEXP (operands[1], 0)) == DImode
1407 && XEXP (operands[1], 1) == const0_rtx)
1411 if (!can_create_pseudo_p ())
1414 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1415 GET_CODE (operands[1]),
1416 XEXP (operands[1], 0),
1417 XEXP (operands[1], 1));
1423 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1424 ;; SImode to DImode.
1425 (define_insn "movsicc_false"
1426 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1427 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1429 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1430 (match_operand:SI 3 "arith_reg_operand" "0")))]
1433 [(set_attr "type" "arith_media")])
1435 (define_insn "movsicc_true"
1436 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1439 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1440 (match_operand:SI 3 "arith_reg_operand" "0")))]
1443 [(set_attr "type" "arith_media")])
1446 [(set (match_operand:SI 0 "arith_reg_dest" "")
1447 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1448 [(match_operand:SI 1 "arith_reg_operand" "")
1450 (match_operand:SI 2 "arith_reg_dest" "")
1452 (set (match_dup 2) (match_dup 0))]
1453 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1455 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1457 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1458 VOIDmode, operands[1], CONST0_RTX (SImode));
1462 [(set (match_operand:SI 0 "general_movdst_operand" "")
1463 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1464 (set (match_operand:SI 2 "arith_reg_dest" "")
1465 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1466 [(match_operand:SI 3 "arith_reg_operand" "")
1470 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1471 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1473 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1475 replace_rtx (operands[4], operands[0], operands[1]);
1479 [(set (match_operand 0 "any_register_operand" "")
1480 (match_operand 1 "any_register_operand" ""))
1481 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1482 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1483 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1484 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1485 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1486 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1487 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1488 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1489 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1490 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1491 && (REGNO_REG_CLASS (REGNO (operands[0]))
1492 == REGNO_REG_CLASS (REGNO (operands[2])))
1493 && (REGNO_REG_CLASS (REGNO (operands[1]))
1494 == REGNO_REG_CLASS (REGNO (operands[0])))"
1495 [(set (match_dup 0) (match_dup 3))
1496 (set (match_dup 4) (match_dup 5))]
1498 rtx set1, set2, insn2;
1499 rtx replacements[4];
1501 /* We want to replace occurrences of operands[0] with operands[1] and
1502 operands[2] with operands[0] in operands[4]/operands[5].
1503 Doing just two replace_rtx calls naively would result in the second
1504 replacement undoing all that the first did if operands[1] and operands[2]
1505 are identical, so we must do this simultaneously. */
1506 replacements[0] = operands[0];
1507 replacements[1] = operands[1];
1508 replacements[2] = operands[2];
1509 replacements[3] = operands[0];
1510 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1511 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1512 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1515 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1516 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1517 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1518 /* The operands array is aliased to recog_data.operand, which gets
1519 clobbered by extract_insn, so finish with it now. */
1520 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1521 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1522 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1523 always uses emit_insn. */
1524 /* Check that we don't violate matching constraints or earlyclobbers. */
1525 extract_insn (emit_insn (set1));
1526 if (! constrain_operands (1))
1528 insn2 = emit (set2);
1529 if (GET_CODE (insn2) == BARRIER)
1531 extract_insn (insn2);
1532 if (! constrain_operands (1))
1536 tmp = replacements[0];
1537 replacements[0] = replacements[1];
1538 replacements[1] = tmp;
1539 tmp = replacements[2];
1540 replacements[2] = replacements[3];
1541 replacements[3] = tmp;
1542 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1543 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1544 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1550 ;; The register allocator is rather clumsy in handling multi-way conditional
1551 ;; moves, so allow the combiner to make them, and we split them up after
1553 (define_insn_and_split "*movsicc_umin"
1554 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1555 (umin:SI (if_then_else:SI
1556 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1558 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1559 (match_operand:SI 3 "register_operand" "0"))
1560 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1561 (clobber (match_scratch:SI 5 "=&r"))]
1562 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1564 "TARGET_SHMEDIA && reload_completed"
1567 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1569 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1570 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1575 (define_insn "*movsicc_t_false"
1576 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1577 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1578 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1579 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1580 "TARGET_PRETEND_CMOVE
1581 && (arith_reg_operand (operands[1], SImode)
1582 || (immediate_operand (operands[1], SImode)
1583 && satisfies_constraint_I08 (operands[1])))"
1589 [(set_attr "type" "mt_group,arith") ;; poor approximation
1590 (set_attr "length" "4")])
1592 (define_insn "*movsicc_t_true"
1593 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1594 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1595 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1596 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1597 "TARGET_PRETEND_CMOVE
1598 && (arith_reg_operand (operands[1], SImode)
1599 || (immediate_operand (operands[1], SImode)
1600 && satisfies_constraint_I08 (operands[1])))"
1606 [(set_attr "type" "mt_group,arith") ;; poor approximation
1607 (set_attr "length" "4")])
1609 (define_expand "movsicc"
1610 [(set (match_operand:SI 0 "arith_reg_dest" "")
1611 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1612 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1613 (match_operand:SI 3 "arith_reg_operand" "")))]
1614 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1616 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1617 && GET_MODE (XEXP (operands[1], 0)) == SImode
1619 || (REG_P (XEXP (operands[1], 0))
1620 && REGNO (XEXP (operands[1], 0)) == T_REG))
1621 && XEXP (operands[1], 1) == const0_rtx)
1624 else if (TARGET_PRETEND_CMOVE)
1626 enum rtx_code code = GET_CODE (operands[1]);
1627 enum rtx_code new_code = code;
1628 rtx op0 = XEXP (operands[1], 0);
1629 rtx op1 = XEXP (operands[1], 1);
1631 if (! currently_expanding_to_rtl)
1635 case LT: case LE: case LEU: case LTU:
1636 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1639 new_code = reverse_condition (code);
1641 case EQ: case GT: case GE: case GEU: case GTU:
1646 sh_emit_scc_to_t (new_code, op0, op1);
1647 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1648 gen_rtx_REG (SImode, T_REG), const0_rtx);
1652 if (!can_create_pseudo_p ())
1655 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1656 GET_CODE (operands[1]),
1657 XEXP (operands[1], 0),
1658 XEXP (operands[1], 1));
1664 (define_expand "movqicc"
1665 [(set (match_operand:QI 0 "register_operand" "")
1666 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1667 (match_operand:QI 2 "register_operand" "")
1668 (match_operand:QI 3 "register_operand" "")))]
1671 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1672 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1673 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1674 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1678 ;; -------------------------------------------------------------------------
1679 ;; Addition instructions
1680 ;; -------------------------------------------------------------------------
1682 (define_expand "adddi3"
1683 [(set (match_operand:DI 0 "arith_reg_operand" "")
1684 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1685 (match_operand:DI 2 "arith_operand" "")))]
1690 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1692 operands[2] = force_reg (DImode, operands[2]);
1693 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1698 (define_insn "*adddi3_media"
1699 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1700 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1701 (match_operand:DI 2 "arith_operand" "r,I10")))]
1706 [(set_attr "type" "arith_media")])
1708 (define_insn "*adddisi3_media"
1709 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1710 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1711 (match_operand:DI 2 "arith_operand" "r,I10")))]
1716 [(set_attr "type" "arith_media")
1717 (set_attr "highpart" "ignore")])
1719 (define_insn "adddi3z_media"
1720 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1722 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1723 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1725 "addz.l %1, %N2, %0"
1726 [(set_attr "type" "arith_media")
1727 (set_attr "highpart" "ignore")])
1729 (define_insn_and_split "adddi3_compact"
1730 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1731 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1732 (match_operand:DI 2 "arith_reg_operand" "r")))
1733 (clobber (reg:SI T_REG))]
1736 "&& reload_completed"
1739 rtx high0 = gen_highpart (SImode, operands[0]);
1740 rtx high2 = gen_highpart (SImode, operands[2]);
1741 rtx low0 = gen_lowpart (SImode, operands[0]);
1743 emit_insn (gen_clrt ());
1744 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1745 emit_insn (gen_addc (high0, high0, high2));
1750 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1751 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1752 (match_operand:SI 2 "arith_reg_operand" "r"))
1755 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1758 [(set_attr "type" "arith")])
1760 ;; A simplified version of the addc insn, where the exact value of the
1761 ;; T bit doesn't matter. This is easier for combine to pick up.
1762 ;; We allow a reg or 0 for one of the operands in order to be able to
1763 ;; do 'reg + T' sequences. Reload will load the constant 0 into the reg
1765 (define_insn "*addc"
1766 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1767 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
1768 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1769 (match_operand:SI 3 "t_reg_operand" "")))
1770 (clobber (reg:SI T_REG))]
1773 [(set_attr "type" "arith")])
1775 ;; Split 'reg + reg + 1' into a sett addc sequence, as it can be scheduled
1776 ;; better, if the sett insn can be done early.
1777 (define_insn_and_split "*addc"
1778 [(set (match_operand:SI 0 "arith_reg_dest" "")
1779 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
1780 (match_operand:SI 2 "arith_reg_operand" ""))
1782 (clobber (reg:SI T_REG))]
1786 [(set (reg:SI T_REG) (const_int 1))
1787 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
1789 (clobber (reg:SI T_REG))])])
1791 ;; Left shifts by one are usually done with an add insn to avoid T_REG
1792 ;; clobbers. Thus addc can also be used to do something like '(x << 1) + 1'.
1793 (define_insn_and_split "*addc"
1794 [(set (match_operand:SI 0 "arith_reg_dest")
1795 (plus:SI (mult:SI (match_operand:SI 1 "arith_reg_operand")
1798 (clobber (reg:SI T_REG))]
1802 [(set (reg:SI T_REG) (const_int 1))
1803 (parallel [(set (match_dup 0) (plus:SI (plus:SI (match_dup 1) (match_dup 1))
1805 (clobber (reg:SI T_REG))])])
1807 ;; Sometimes combine will try to do 'reg + (0-reg) + 1' if the *addc pattern
1808 ;; matched. Split this up into a simple sub add sequence, as this will save
1809 ;; us one sett insn.
1810 (define_insn_and_split "*minus_plus_one"
1811 [(set (match_operand:SI 0 "arith_reg_dest" "")
1812 (plus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
1813 (match_operand:SI 2 "arith_reg_operand" ""))
1818 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1819 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))])
1821 ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn.
1822 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1823 ;; operation, as opposed to sequences such as
1827 ;; Even if the constant is not CSE-ed, a sequence such as
1830 ;; can be scheduled much better since the load of the constant can be
1831 ;; done earlier, before any comparison insns that store the result in
1833 (define_insn_and_split "*addc"
1834 [(set (match_operand:SI 0 "arith_reg_dest" "")
1835 (plus:SI (match_operand:SI 1 "t_reg_operand" "")
1836 (match_operand:SI 2 "arith_reg_operand" "")))
1837 (clobber (reg:SI T_REG))]
1841 [(parallel [(set (match_dup 0)
1842 (plus:SI (plus:SI (match_dup 2) (const_int 0))
1844 (clobber (reg:SI T_REG))])])
1846 (define_expand "addsi3"
1847 [(set (match_operand:SI 0 "arith_reg_operand" "")
1848 (plus:SI (match_operand:SI 1 "arith_operand" "")
1849 (match_operand:SI 2 "arith_operand" "")))]
1853 operands[1] = force_reg (SImode, operands[1]);
1856 (define_insn "addsi3_media"
1857 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1858 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1859 (match_operand:SI 2 "arith_operand" "r,I10")))]
1864 [(set_attr "type" "arith_media")
1865 (set_attr "highpart" "ignore")])
1867 (define_insn "addsidi3_media"
1868 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1869 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1871 (match_operand:SI 2 "arith_operand"
1877 [(set_attr "type" "arith_media")
1878 (set_attr "highpart" "ignore")])
1880 (define_insn "*addsi3_compact"
1881 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1882 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1883 (match_operand:SI 2 "arith_operand" "rI08")))]
1886 [(set_attr "type" "arith")])
1888 ;; -------------------------------------------------------------------------
1889 ;; Subtraction instructions
1890 ;; -------------------------------------------------------------------------
1892 (define_expand "subdi3"
1893 [(set (match_operand:DI 0 "arith_reg_operand" "")
1894 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1895 (match_operand:DI 2 "arith_reg_operand" "")))]
1900 operands[1] = force_reg (DImode, operands[1]);
1901 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1906 (define_insn "*subdi3_media"
1907 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1908 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1909 (match_operand:DI 2 "arith_reg_operand" "r")))]
1912 [(set_attr "type" "arith_media")])
1914 (define_insn "subdisi3_media"
1915 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1916 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1917 (match_operand:DI 2 "arith_reg_operand" "r")))]
1920 [(set_attr "type" "arith_media")
1921 (set_attr "highpart" "ignore")])
1923 (define_insn_and_split "subdi3_compact"
1924 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1925 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1926 (match_operand:DI 2 "arith_reg_operand" "r")))
1927 (clobber (reg:SI T_REG))]
1930 "&& reload_completed"
1933 rtx high0 = gen_highpart (SImode, operands[0]);
1934 rtx high2 = gen_highpart (SImode, operands[2]);
1935 rtx low0 = gen_lowpart (SImode, operands[0]);
1937 emit_insn (gen_clrt ());
1938 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1939 emit_insn (gen_subc (high0, high0, high2));
1944 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1945 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1946 (match_operand:SI 2 "arith_reg_operand" "r"))
1949 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1954 [(set_attr "type" "arith")])
1956 ;; A simplified version of the subc insn, where the exact value of the
1957 ;; T bit doesn't matter. This is easier for combine to pick up.
1958 ;; We allow a reg or 0 for one of the operands in order to be able to
1959 ;; do 'reg - T' sequences. Reload will load the constant 0 into the reg
1961 (define_insn "*subc"
1962 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1963 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1964 (match_operand:SI 2 "arith_reg_or_0_operand" "r"))
1965 (match_operand:SI 3 "t_reg_operand" "")))
1966 (clobber (reg:SI T_REG))]
1969 [(set_attr "type" "arith")])
1971 ;; Split reg - reg - 1 into a sett subc sequence, as it can be scheduled
1972 ;; better, if the sett insn can be done early.
1973 ;; Notice that combine turns 'a - b - 1' into 'a + (~b)'.
1974 (define_insn_and_split "*subc"
1975 [(set (match_operand:SI 0 "arith_reg_dest" "")
1976 (plus:SI (not:SI (match_operand:SI 1 "arith_reg_operand" ""))
1977 (match_operand:SI 2 "arith_reg_operand" "")))
1978 (clobber (reg:SI T_REG))]
1982 [(set (reg:SI T_REG) (const_int 1))
1983 (parallel [(set (match_dup 0)
1984 (minus:SI (minus:SI (match_dup 2) (match_dup 1))
1986 (clobber (reg:SI T_REG))])])
1988 ;; Split 'reg - T' into 'reg - 0 - T' to utilize the subc insn.
1989 ;; If the 0 constant can be CSE-ed, this becomes a one instruction
1990 ;; operation, as opposed to sequences such as
1994 ;; Even if the constant is not CSE-ed, a sequence such as
1997 ;; can be scheduled much better since the load of the constant can be
1998 ;; done earlier, before any comparison insns that store the result in
2000 (define_insn_and_split "*subc"
2001 [(set (match_operand:SI 0 "arith_reg_dest" "")
2002 (minus:SI (match_operand:SI 1 "arith_reg_operand" "")
2003 (match_operand:SI 2 "t_reg_operand" "")))
2004 (clobber (reg:SI T_REG))]
2008 [(parallel [(set (match_dup 0)
2009 (minus:SI (minus:SI (match_dup 1) (const_int 0))
2011 (clobber (reg:SI T_REG))])])
2013 (define_insn "*subsi3_internal"
2014 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2015 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
2016 (match_operand:SI 2 "arith_reg_operand" "r")))]
2019 [(set_attr "type" "arith")])
2021 (define_insn_and_split "*subsi3_media"
2022 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2023 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
2024 (match_operand:SI 2 "extend_reg_operand" "r")))]
2026 && (operands[1] != constm1_rtx
2027 || (GET_CODE (operands[2]) != TRUNCATE
2028 && GET_CODE (operands[2]) != SUBREG))"
2030 "operands[1] == constm1_rtx"
2031 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
2033 [(set_attr "type" "arith_media")
2034 (set_attr "highpart" "ignore")])
2037 [(set (match_operand:SI 0 "arith_reg_dest" "")
2038 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2039 "general_extend_operand"
2041 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
2042 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2043 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2047 [(set (match_operand:SI 0 "arith_reg_dest" "")
2048 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
2049 "general_extend_operand"
2051 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
2052 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
2053 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
2055 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
2056 ;; will sometimes save one instruction. Otherwise we might get
2057 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
2060 (define_expand "subsi3"
2061 [(set (match_operand:SI 0 "arith_reg_operand" "")
2062 (minus:SI (match_operand:SI 1 "arith_operand" "")
2063 (match_operand:SI 2 "arith_reg_operand" "")))]
2066 if (TARGET_SH1 && CONST_INT_P (operands[1]))
2068 emit_insn (gen_negsi2 (operands[0], operands[2]));
2069 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
2074 if (!can_create_pseudo_p ()
2075 && ! arith_reg_or_0_operand (operands[1], SImode))
2077 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
2078 operands[1] = force_reg (SImode, operands[1]);
2082 ;; -------------------------------------------------------------------------
2083 ;; Division instructions
2084 ;; -------------------------------------------------------------------------
2086 ;; We take advantage of the library routines which don't clobber as many
2087 ;; registers as a normal function call would.
2089 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
2090 ;; also has an effect on the register that holds the address of the sfunc.
2091 ;; To make this work, we have an extra dummy insn that shows the use
2092 ;; of this register for reorg.
2094 (define_insn "use_sfunc_addr"
2095 [(set (reg:SI PR_REG)
2096 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
2097 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
2099 [(set_attr "length" "0")])
2101 (define_insn "udivsi3_sh2a"
2102 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2103 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
2104 (match_operand:SI 2 "arith_reg_operand" "z")))]
2107 [(set_attr "type" "arith")
2108 (set_attr "in_delay_slot" "no")])
2110 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
2111 ;; hard register 0. If we used hard register 0, then the next instruction
2112 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
2113 ;; gets allocated to a stack slot that needs its address reloaded, then
2114 ;; there is nothing to prevent reload from using r0 to reload the address.
2115 ;; This reload would clobber the value in r0 we are trying to store.
2116 ;; If we let reload allocate r0, then this problem can never happen.
2118 (define_insn "udivsi3_i1"
2119 [(set (match_operand:SI 0 "register_operand" "=z")
2120 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2121 (clobber (reg:SI T_REG))
2122 (clobber (reg:SI PR_REG))
2123 (clobber (reg:SI R4_REG))
2124 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2125 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
2127 [(set_attr "type" "sfunc")
2128 (set_attr "needs_delay_slot" "yes")])
2130 ; Since shmedia-nofpu code could be linked against shcompact code, and
2131 ; the udivsi3 libcall has the same name, we must consider all registers
2132 ; clobbered that are in the union of the registers clobbered by the
2133 ; shmedia and the shcompact implementation. Note, if the shcompact
2134 ; implementation actually used shcompact code, we'd need to clobber
2135 ; also r23 and fr23.
2136 (define_insn "udivsi3_i1_media"
2137 [(set (match_operand:SI 0 "register_operand" "=z")
2138 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2139 (clobber (reg:SI T_MEDIA_REG))
2140 (clobber (reg:SI PR_MEDIA_REG))
2141 (clobber (reg:SI R20_REG))
2142 (clobber (reg:SI R21_REG))
2143 (clobber (reg:SI R22_REG))
2144 (clobber (reg:DI TR0_REG))
2145 (clobber (reg:DI TR1_REG))
2146 (clobber (reg:DI TR2_REG))
2147 (use (match_operand 1 "target_reg_operand" "b"))]
2148 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2150 [(set_attr "type" "sfunc")
2151 (set_attr "needs_delay_slot" "yes")])
2153 (define_expand "udivsi3_i4_media"
2155 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2157 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2158 (set (match_dup 5) (float:DF (match_dup 3)))
2159 (set (match_dup 6) (float:DF (match_dup 4)))
2160 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
2161 (set (match_dup 8) (fix:DI (match_dup 7)))
2162 (set (match_operand:SI 0 "register_operand" "")
2163 (truncate:SI (match_dup 8)))]
2164 "TARGET_SHMEDIA_FPU"
2166 operands[3] = gen_reg_rtx (DImode);
2167 operands[4] = gen_reg_rtx (DImode);
2168 operands[5] = gen_reg_rtx (DFmode);
2169 operands[6] = gen_reg_rtx (DFmode);
2170 operands[7] = gen_reg_rtx (DFmode);
2171 operands[8] = gen_reg_rtx (DImode);
2174 (define_insn "udivsi3_i4"
2175 [(set (match_operand:SI 0 "register_operand" "=y")
2176 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2177 (clobber (reg:SI T_REG))
2178 (clobber (reg:SI PR_REG))
2179 (clobber (reg:DF DR0_REG))
2180 (clobber (reg:DF DR2_REG))
2181 (clobber (reg:DF DR4_REG))
2182 (clobber (reg:SI R0_REG))
2183 (clobber (reg:SI R1_REG))
2184 (clobber (reg:SI R4_REG))
2185 (clobber (reg:SI R5_REG))
2186 (use (reg:PSI FPSCR_REG))
2187 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2188 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2190 [(set_attr "type" "sfunc")
2191 (set_attr "fp_mode" "double")
2192 (set_attr "needs_delay_slot" "yes")])
2194 (define_insn "udivsi3_i4_single"
2195 [(set (match_operand:SI 0 "register_operand" "=y")
2196 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2197 (clobber (reg:SI T_REG))
2198 (clobber (reg:SI PR_REG))
2199 (clobber (reg:DF DR0_REG))
2200 (clobber (reg:DF DR2_REG))
2201 (clobber (reg:DF DR4_REG))
2202 (clobber (reg:SI R0_REG))
2203 (clobber (reg:SI R1_REG))
2204 (clobber (reg:SI R4_REG))
2205 (clobber (reg:SI R5_REG))
2206 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2207 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2209 [(set_attr "type" "sfunc")
2210 (set_attr "needs_delay_slot" "yes")])
2212 (define_insn "udivsi3_i4_int"
2213 [(set (match_operand:SI 0 "register_operand" "=z")
2214 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2215 (clobber (reg:SI T_REG))
2216 (clobber (reg:SI R1_REG))
2217 (clobber (reg:SI PR_REG))
2218 (clobber (reg:SI MACH_REG))
2219 (clobber (reg:SI MACL_REG))
2220 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2223 [(set_attr "type" "sfunc")
2224 (set_attr "needs_delay_slot" "yes")])
2227 (define_expand "udivsi3"
2228 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
2229 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2230 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2231 (parallel [(set (match_operand:SI 0 "register_operand" "")
2232 (udiv:SI (reg:SI R4_REG)
2234 (clobber (reg:SI T_REG))
2235 (clobber (reg:SI PR_REG))
2236 (clobber (reg:SI R4_REG))
2237 (use (match_dup 3))])]
2242 operands[3] = gen_reg_rtx (Pmode);
2243 /* Emit the move of the address to a pseudo outside of the libcall. */
2244 if (TARGET_DIVIDE_CALL_TABLE)
2246 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
2247 that causes problems when the divide code is supposed to come from a
2248 separate library. Division by zero is undefined, so dividing 1 can be
2249 implemented by comparing with the divisor. */
2250 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
2252 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
2253 emit_insn (gen_cstoresi4 (operands[0], test,
2254 operands[1], operands[2]));
2257 else if (operands[2] == const0_rtx)
2259 emit_move_insn (operands[0], operands[2]);
2262 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
2263 last = gen_udivsi3_i4_int (operands[0], operands[3]);
2265 else if (TARGET_DIVIDE_CALL_FP)
2267 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
2268 if (TARGET_FPU_SINGLE)
2269 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2271 last = gen_udivsi3_i4 (operands[0], operands[3]);
2273 else if (TARGET_SHMEDIA_FPU)
2275 operands[1] = force_reg (SImode, operands[1]);
2276 operands[2] = force_reg (SImode, operands[2]);
2277 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
2280 else if (TARGET_SH2A)
2282 operands[1] = force_reg (SImode, operands[1]);
2283 operands[2] = force_reg (SImode, operands[2]);
2284 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
2287 else if (TARGET_SH5)
2289 function_symbol (operands[3],
2290 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
2294 last = gen_udivsi3_i1_media (operands[0], operands[3]);
2295 else if (TARGET_FPU_ANY)
2296 last = gen_udivsi3_i4_single (operands[0], operands[3]);
2298 last = gen_udivsi3_i1 (operands[0], operands[3]);
2302 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
2303 last = gen_udivsi3_i1 (operands[0], operands[3]);
2305 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2306 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2311 (define_insn "divsi3_sh2a"
2312 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2313 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
2314 (match_operand:SI 2 "arith_reg_operand" "z")))]
2317 [(set_attr "type" "arith")
2318 (set_attr "in_delay_slot" "no")])
2320 (define_insn "divsi3_i1"
2321 [(set (match_operand:SI 0 "register_operand" "=z")
2322 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2323 (clobber (reg:SI T_REG))
2324 (clobber (reg:SI PR_REG))
2325 (clobber (reg:SI R1_REG))
2326 (clobber (reg:SI R2_REG))
2327 (clobber (reg:SI R3_REG))
2328 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2329 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
2331 [(set_attr "type" "sfunc")
2332 (set_attr "needs_delay_slot" "yes")])
2334 (define_insn "divsi3_i1_media"
2335 [(set (match_operand:SI 0 "register_operand" "=z")
2336 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2337 (clobber (reg:SI T_MEDIA_REG))
2338 (clobber (reg:SI PR_MEDIA_REG))
2339 (clobber (reg:SI R1_REG))
2340 (clobber (reg:SI R20_REG))
2341 (clobber (reg:SI R21_REG))
2342 (clobber (reg:SI TR0_REG))
2343 (use (match_operand 1 "target_reg_operand" "b"))]
2344 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2346 [(set_attr "type" "sfunc")])
2348 (define_insn "divsi3_media_2"
2349 [(set (match_operand:SI 0 "register_operand" "=z")
2350 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2351 (clobber (reg:SI T_MEDIA_REG))
2352 (clobber (reg:SI PR_MEDIA_REG))
2353 (clobber (reg:SI R1_REG))
2354 (clobber (reg:SI R21_REG))
2355 (clobber (reg:SI TR0_REG))
2356 (use (reg:SI R20_REG))
2357 (use (match_operand 1 "target_reg_operand" "b"))]
2358 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2360 [(set_attr "type" "sfunc")])
2362 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
2363 ;; hard reg clobbers and data dependencies that we need when we want
2364 ;; to rematerialize the division into a call.
2365 (define_insn_and_split "divsi_inv_call"
2366 [(set (match_operand:SI 0 "register_operand" "=r")
2367 (div:SI (match_operand:SI 1 "register_operand" "r")
2368 (match_operand:SI 2 "register_operand" "r")))
2369 (clobber (reg:SI R4_REG))
2370 (clobber (reg:SI R5_REG))
2371 (clobber (reg:SI T_MEDIA_REG))
2372 (clobber (reg:SI PR_MEDIA_REG))
2373 (clobber (reg:SI R1_REG))
2374 (clobber (reg:SI R21_REG))
2375 (clobber (reg:SI TR0_REG))
2376 (clobber (reg:SI R20_REG))
2377 (use (match_operand:SI 3 "register_operand" "r"))]
2380 "&& (reload_in_progress || reload_completed)"
2381 [(set (match_dup 0) (match_dup 3))]
2383 [(set_attr "highpart" "must_split")])
2385 ;; This is the combiner pattern for -mdiv=inv:call .
2386 (define_insn_and_split "*divsi_inv_call_combine"
2387 [(set (match_operand:SI 0 "register_operand" "=z")
2388 (div:SI (match_operand:SI 1 "register_operand" "r")
2389 (match_operand:SI 2 "register_operand" "r")))
2390 (clobber (reg:SI R4_REG))
2391 (clobber (reg:SI R5_REG))
2392 (clobber (reg:SI T_MEDIA_REG))
2393 (clobber (reg:SI PR_MEDIA_REG))
2394 (clobber (reg:SI R1_REG))
2395 (clobber (reg:SI R21_REG))
2396 (clobber (reg:SI TR0_REG))
2397 (clobber (reg:SI R20_REG))
2398 (use (unspec:SI [(match_dup 1)
2399 (match_operand:SI 3 "" "")
2400 (unspec:SI [(match_operand:SI 4 "" "")
2402 (match_operand:DI 5 "" "")]
2404 (match_operand:DI 6 "" "")
2407 UNSPEC_DIV_INV_M3))]
2410 "&& (reload_in_progress || reload_completed)"
2413 const char *name = sh_divsi3_libfunc;
2414 enum sh_function_kind kind = SFUNC_GOT;
2417 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2418 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2419 while (TARGET_DIVIDE_INV_CALL2)
2421 rtx x = operands[3];
2423 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2425 x = XVECEXP (x, 0, 0);
2426 name = "__sdivsi3_2";
2427 kind = SFUNC_STATIC;
2428 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2431 sym = function_symbol (NULL, name, kind);
2432 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2435 [(set_attr "highpart" "must_split")])
2437 (define_expand "divsi3_i4_media"
2438 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2439 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2440 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2441 (set (match_operand:SI 0 "register_operand" "=r")
2442 (fix:SI (match_dup 5)))]
2443 "TARGET_SHMEDIA_FPU"
2445 operands[3] = gen_reg_rtx (DFmode);
2446 operands[4] = gen_reg_rtx (DFmode);
2447 operands[5] = gen_reg_rtx (DFmode);
2450 (define_insn "divsi3_i4"
2451 [(set (match_operand:SI 0 "register_operand" "=y")
2452 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2453 (clobber (reg:SI PR_REG))
2454 (clobber (reg:DF DR0_REG))
2455 (clobber (reg:DF DR2_REG))
2456 (use (reg:PSI FPSCR_REG))
2457 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2458 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2460 [(set_attr "type" "sfunc")
2461 (set_attr "fp_mode" "double")
2462 (set_attr "needs_delay_slot" "yes")])
2464 (define_insn "divsi3_i4_single"
2465 [(set (match_operand:SI 0 "register_operand" "=y")
2466 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2467 (clobber (reg:SI PR_REG))
2468 (clobber (reg:DF DR0_REG))
2469 (clobber (reg:DF DR2_REG))
2470 (clobber (reg:SI R2_REG))
2471 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2472 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2474 [(set_attr "type" "sfunc")
2475 (set_attr "needs_delay_slot" "yes")])
2477 (define_insn "divsi3_i4_int"
2478 [(set (match_operand:SI 0 "register_operand" "=z")
2479 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2480 (clobber (reg:SI T_REG))
2481 (clobber (reg:SI PR_REG))
2482 (clobber (reg:SI R1_REG))
2483 (clobber (reg:SI MACH_REG))
2484 (clobber (reg:SI MACL_REG))
2485 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2488 [(set_attr "type" "sfunc")
2489 (set_attr "needs_delay_slot" "yes")])
2491 (define_expand "divsi3"
2492 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2493 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2494 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2495 (parallel [(set (match_operand:SI 0 "register_operand" "")
2496 (div:SI (reg:SI R4_REG)
2498 (clobber (reg:SI T_REG))
2499 (clobber (reg:SI PR_REG))
2500 (clobber (reg:SI R1_REG))
2501 (clobber (reg:SI R2_REG))
2502 (clobber (reg:SI R3_REG))
2503 (use (match_dup 3))])]
2508 operands[3] = gen_reg_rtx (Pmode);
2509 /* Emit the move of the address to a pseudo outside of the libcall. */
2510 if (TARGET_DIVIDE_CALL_TABLE)
2512 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2513 last = gen_divsi3_i4_int (operands[0], operands[3]);
2515 else if (TARGET_DIVIDE_CALL_FP)
2517 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2518 if (TARGET_FPU_SINGLE)
2519 last = gen_divsi3_i4_single (operands[0], operands[3]);
2521 last = gen_divsi3_i4 (operands[0], operands[3]);
2523 else if (TARGET_SH2A)
2525 operands[1] = force_reg (SImode, operands[1]);
2526 operands[2] = force_reg (SImode, operands[2]);
2527 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2530 else if (TARGET_DIVIDE_INV)
2532 rtx dividend = operands[1];
2533 rtx divisor = operands[2];
2535 rtx nsb_res = gen_reg_rtx (DImode);
2536 rtx norm64 = gen_reg_rtx (DImode);
2537 rtx tab_ix = gen_reg_rtx (DImode);
2538 rtx norm32 = gen_reg_rtx (SImode);
2539 rtx i92 = force_reg (DImode, GEN_INT (92));
2540 rtx scratch0a = gen_reg_rtx (DImode);
2541 rtx scratch0b = gen_reg_rtx (DImode);
2542 rtx inv0 = gen_reg_rtx (SImode);
2543 rtx scratch1a = gen_reg_rtx (DImode);
2544 rtx scratch1b = gen_reg_rtx (DImode);
2545 rtx shift = gen_reg_rtx (DImode);
2547 rtx inv1 = gen_reg_rtx (SImode);
2548 rtx scratch2a = gen_reg_rtx (DImode);
2549 rtx scratch2b = gen_reg_rtx (SImode);
2550 rtx inv2 = gen_reg_rtx (SImode);
2551 rtx scratch3a = gen_reg_rtx (DImode);
2552 rtx scratch3b = gen_reg_rtx (DImode);
2553 rtx scratch3c = gen_reg_rtx (DImode);
2554 rtx scratch3d = gen_reg_rtx (SImode);
2555 rtx scratch3e = gen_reg_rtx (DImode);
2556 rtx result = gen_reg_rtx (SImode);
2558 if (! arith_reg_or_0_operand (dividend, SImode))
2559 dividend = force_reg (SImode, dividend);
2560 if (! arith_reg_operand (divisor, SImode))
2561 divisor = force_reg (SImode, divisor);
2562 if (flag_pic && Pmode != DImode)
2564 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2565 tab_base = gen_datalabel_ref (tab_base);
2566 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2570 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2571 tab_base = gen_datalabel_ref (tab_base);
2572 tab_base = force_reg (DImode, tab_base);
2574 if (TARGET_DIVIDE_INV20U)
2575 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2577 i2p27 = GEN_INT (0);
2578 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2579 i43 = force_reg (DImode, GEN_INT (43));
2582 emit_insn (gen_nsbdi (nsb_res,
2583 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2584 emit_insn (gen_ashldi3_media (norm64,
2585 gen_rtx_SUBREG (DImode, divisor, 0),
2587 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2588 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2589 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2590 inv0, scratch0a, scratch0b,
2591 scratch1a, scratch1b));
2592 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2593 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2595 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2597 scratch3a, scratch3b, scratch3c,
2598 scratch2a, scratch2b, scratch3d, scratch3e));
2599 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2600 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2601 else if (TARGET_DIVIDE_INV_FP)
2602 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2603 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2604 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2605 gen_reg_rtx (DFmode)));
2607 emit_move_insn (operands[0], result);
2610 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2612 operands[1] = force_reg (SImode, operands[1]);
2613 operands[2] = force_reg (SImode, operands[2]);
2614 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2617 else if (TARGET_SH5)
2619 if (TARGET_DIVIDE_CALL2)
2621 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2622 tab_base = gen_datalabel_ref (tab_base);
2623 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2625 if (TARGET_FPU_ANY && TARGET_SH1)
2626 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2627 else if (TARGET_DIVIDE_CALL2)
2628 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2630 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2633 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2634 (operands[0], operands[3]));
2635 else if (TARGET_FPU_ANY)
2636 last = gen_divsi3_i4_single (operands[0], operands[3]);
2638 last = gen_divsi3_i1 (operands[0], operands[3]);
2642 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2643 last = gen_divsi3_i1 (operands[0], operands[3]);
2645 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2646 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2651 ;; operands: scratch, tab_base, tab_ix
2652 ;; These are unspecs because we could generate an indexed addressing mode
2653 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2654 ;; confuse reload. See PR27117.
2656 (define_insn "divsi_inv_qitable"
2657 [(set (match_operand:DI 0 "register_operand" "=r")
2658 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2659 (match_operand:DI 2 "register_operand" "r")]
2660 UNSPEC_DIV_INV_TABLE)))]
2663 [(set_attr "type" "load_media")
2664 (set_attr "highpart" "user")])
2666 ;; operands: scratch, tab_base, tab_ix
2667 (define_insn "divsi_inv_hitable"
2668 [(set (match_operand:DI 0 "register_operand" "=r")
2669 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2670 (match_operand:DI 2 "register_operand" "r")]
2671 UNSPEC_DIV_INV_TABLE)))]
2674 [(set_attr "type" "load_media")
2675 (set_attr "highpart" "user")])
2677 ;; operands: inv0, tab_base, tab_ix, norm32
2678 ;; scratch equiv in sdivsi3_2: r19, r21
2679 (define_expand "divsi_inv_m0"
2680 [(set (match_operand:SI 0 "register_operand" "=r")
2681 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2682 (match_operand:DI 2 "register_operand" "r")
2683 (match_operand:SI 3 "register_operand" "r")]
2685 (clobber (match_operand:DI 4 "register_operand" "=r"))
2686 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2693 ldx.ub r20, r21, r19 // u0.8
2695 muls.l r25, r19, r19 // s2.38
2696 ldx.w r20, r21, r21 // s2.14
2697 shari r19, 24, r19 // truncate to s2.14
2698 sub r21, r19, r19 // some 11 bit inverse in s1.14
2701 rtx inv0 = operands[0];
2702 rtx tab_base = operands[1];
2703 rtx tab_ix = operands[2];
2704 rtx norm32 = operands[3];
2705 rtx scratch0 = operands[4];
2706 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2707 rtx scratch1 = operands[5];
2709 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2710 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2711 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2712 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2713 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2714 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2718 ;; operands: inv1, tab_base, tab_ix, norm32
2719 (define_insn_and_split "divsi_inv_m1"
2720 [(set (match_operand:SI 0 "register_operand" "=r")
2721 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2722 (match_operand:DI 2 "register_operand" "r")
2723 (match_operand:SI 3 "register_operand" "r")]
2725 (clobber (match_operand:SI 4 "register_operand" "=r"))
2726 (clobber (match_operand:DI 5 "register_operand" "=r"))
2727 (clobber (match_operand:DI 6 "register_operand" "=r"))
2728 (clobber (match_operand:DI 7 "register_operand" "=r"))
2729 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2732 "&& !can_create_pseudo_p ()"
2736 muls.l r19, r19, r18 // u0.28
2737 muls.l r25, r18, r18 // s2.58
2738 shlli r19, 45, r0 // multiply by two and convert to s2.58
2740 shari r18, 28, r18 // some 18 bit inverse in s1.30
2743 rtx inv1 = operands[0];
2744 rtx tab_base = operands[1];
2745 rtx tab_ix = operands[2];
2746 rtx norm32 = operands[3];
2747 rtx inv0 = operands[4];
2748 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2749 rtx scratch0a = operands[5];
2750 rtx scratch0b = operands[6];
2751 rtx scratch0 = operands[7];
2752 rtx scratch1 = operands[8];
2753 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2755 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2756 scratch0a, scratch0b));
2757 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2758 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2759 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2760 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2761 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2765 ;; operands: inv2, norm32, inv1, i92
2766 (define_insn_and_split "divsi_inv_m2"
2767 [(set (match_operand:SI 0 "register_operand" "=r")
2768 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2769 (match_operand:SI 2 "register_operand" "r")
2770 (match_operand:DI 3 "register_operand" "r")]
2772 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2775 "&& !can_create_pseudo_p ()"
2779 muls.l r18, r25, r0 // s2.60
2780 shari r0, 16, r0 // s-16.44
2782 muls.l r0, r18, r19 // s-16.74
2783 shari r19, 30, r19 // s-16.44
2785 rtx inv2 = operands[0];
2786 rtx norm32 = operands[1];
2787 rtx inv1 = operands[2];
2788 rtx i92 = operands[3];
2789 rtx scratch0 = operands[4];
2790 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2792 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2793 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2794 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2795 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2796 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2800 (define_insn_and_split "divsi_inv_m3"
2801 [(set (match_operand:SI 0 "register_operand" "=r")
2802 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2803 (match_operand:SI 2 "register_operand" "r")
2804 (match_operand:SI 3 "register_operand" "r")
2805 (match_operand:DI 4 "register_operand" "r")
2806 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2807 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2809 (clobber (match_operand:DI 7 "register_operand" "=r"))
2810 (clobber (match_operand:DI 8 "register_operand" "=r"))
2811 (clobber (match_operand:DI 9 "register_operand" "=r"))
2812 (clobber (match_operand:DI 10 "register_operand" "=r"))
2813 (clobber (match_operand:SI 11 "register_operand" "=r"))
2814 (clobber (match_operand:SI 12 "register_operand" "=r"))
2815 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2818 "&& !can_create_pseudo_p ()"
2822 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2823 r0: scratch0 r19: scratch1 r21: scratch2
2825 muls.l r18, r4, r25 // s32.30
2826 muls.l r19, r4, r19 // s15.30
2828 shari r19, 14, r19 // s18.-14
2834 rtx result = operands[0];
2835 rtx dividend = operands[1];
2836 rtx inv1 = operands[2];
2837 rtx inv2 = operands[3];
2838 rtx shift = operands[4];
2839 rtx scratch0 = operands[7];
2840 rtx scratch1 = operands[8];
2841 rtx scratch2 = operands[9];
2843 if (satisfies_constraint_N (dividend))
2845 emit_move_insn (result, dividend);
2849 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2850 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2851 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2852 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2853 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2854 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2855 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2859 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2860 ;; inv1: tab_base, tab_ix, norm32
2861 ;; inv2: norm32, inv1, i92
2862 (define_insn_and_split "divsi_inv_m1_3"
2863 [(set (match_operand:SI 0 "register_operand" "=r")
2864 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2865 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2866 (match_operand:DI 3 "register_operand" "r")
2867 (match_operand:SI 4 "register_operand" "r")]
2869 (unspec:SI [(match_dup 4)
2870 (unspec:SI [(match_dup 2)
2872 (match_dup 4)] UNSPEC_DIV_INV_M1)
2873 (match_operand:SI 5 "" "")]
2875 (match_operand:DI 6 "register_operand" "r")
2876 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2877 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2879 (clobber (match_operand:DI 9 "register_operand" "=r"))
2880 (clobber (match_operand:DI 10 "register_operand" "=r"))
2881 (clobber (match_operand:DI 11 "register_operand" "=r"))
2882 (clobber (match_operand:DI 12 "register_operand" "=r"))
2883 (clobber (match_operand:SI 13 "register_operand" "=r"))
2884 (clobber (match_operand:SI 14 "register_operand" "=r"))
2885 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2887 && (TARGET_DIVIDE_INV_MINLAT
2888 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2890 "&& !can_create_pseudo_p ()"
2893 rtx result = operands[0];
2894 rtx dividend = operands[1];
2895 rtx tab_base = operands[2];
2896 rtx tab_ix = operands[3];
2897 rtx norm32 = operands[4];
2898 /* rtx i92 = operands[5]; */
2899 rtx shift = operands[6];
2900 rtx i2p27 = operands[7];
2901 rtx i43 = operands[8];
2902 rtx scratch0 = operands[9];
2903 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2904 rtx scratch1 = operands[10];
2905 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2906 rtx scratch2 = operands[11];
2907 rtx scratch3 = operands[12];
2908 rtx scratch4 = operands[13];
2909 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2910 rtx scratch5 = operands[14];
2911 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2912 rtx scratch6 = operands[15];
2914 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2915 scratch0, scratch1));
2916 /* inv0 == scratch4 */
2917 if (! TARGET_DIVIDE_INV20U)
2919 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2921 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2925 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2926 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2928 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2929 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2930 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2931 /* inv1 == scratch4 */
2933 if (TARGET_DIVIDE_INV_MINLAT)
2935 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2936 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2937 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2938 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2939 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2940 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2941 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2942 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2943 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2944 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2945 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2949 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2950 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2951 emit_insn (gen_nsbdi (scratch6,
2952 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2953 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2954 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2955 emit_insn (gen_divsi_inv20 (scratch2,
2956 norm32, scratch4, dividend,
2957 scratch6, scratch3, i43,
2958 /* scratch0 may be shared with i2p27. */
2959 scratch0, scratch1, scratch5,
2960 label, label, i2p27));
2962 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2963 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2967 (define_insn "divsi_inv20"
2968 [(set (match_operand:DI 0 "register_operand" "=&r")
2969 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2970 (match_operand:SI 2 "register_operand" "r")
2971 (match_operand:SI 3 "register_operand" "r")
2972 (match_operand:DI 4 "register_operand" "r")
2973 (match_operand:DI 5 "register_operand" "r")
2974 (match_operand:DI 6 "register_operand" "r")
2975 (match_operand:DI 12 "register_operand" "r")
2976 (match_operand 10 "target_operand" "b")
2977 (match_operand 11 "immediate_operand" "i")]
2979 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2980 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2981 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2983 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2985 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2986 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2987 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2988 %10 label (tr), %11 label (imm)
2990 muls.l inv1, norm32, scratch0 // s2.60
2991 muls.l inv1, dividend, result // s32.30
2992 xor i2p27, result_sign, round_scratch
2993 bge/u dividend_nsb, i43, tr.. (label)
2994 shari scratch0, 16, scratch0 // s-16.44
2995 muls.l sratch0_si, inv1, scratch0 // s-16.74
2996 sub result, round_scratch, result
2997 shari dividend, 14, scratch1 // s19.-14
2998 shari scratch0, 30, scratch0 // s-16.44
2999 muls.l scratch0, scratch1, round_scratch // s15.30
3001 sub result, round_scratch, result */
3003 const bool likely = TARGET_DIVIDE_INV20L;
3006 "muls.l %2, %3, %0" "\n"
3007 " xor %12, %5, %7" "\n"
3008 " bge/l %4, %6, %10" "\n"
3009 " muls.l %2, %1, %8" "\n"
3010 " shari %8, 16, %8" "\n"
3011 " muls.l %8, %2, %8" "\n"
3012 " shari %3, 14, %9" "\n"
3013 " shari %8, 30, %8" "\n"
3014 " muls.l %8, %9, %8" "\n"
3015 " sub %0, %8, %0" "\n"
3016 "%11: add %0, %7, %0";
3019 "muls.l %2, %1, %8" "\n"
3020 " muls.l %2, %3, %0" "\n"
3021 " xor %12, %5, %7" "\n"
3022 " bge/u %4, %6, %10" "\n"
3023 " shari %8, 16, %8" "\n"
3024 " muls.l %8, %2, %8" "\n"
3025 " sub %0, %7, %0" "\n"
3026 " shari %3, 14, %9" "\n"
3027 " shari %8, 30, %8" "\n"
3028 " muls.l %8, %9, %7" "\n"
3029 "%11: sub %0, %7, %0";
3032 (define_insn_and_split "divsi_inv_fp"
3033 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
3034 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
3035 (match_operand:SI 2 "register_operand" "rf")))
3036 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
3037 (clobber (match_operand:SI 4 "register_operand" "=r"))
3038 (clobber (match_operand:SI 5 "register_operand" "=r"))
3039 (clobber (match_operand:DF 6 "register_operand" "=r"))
3040 (clobber (match_operand:DF 7 "register_operand" "=r"))
3041 (clobber (match_operand:DF 8 "register_operand" "=r"))]
3042 "TARGET_SHMEDIA_FPU"
3044 "&& (reload_in_progress || reload_completed)"
3045 [(set (match_dup 0) (match_dup 3))]
3047 [(set_attr "highpart" "must_split")])
3049 ;; If a matching group of divide-by-inverse instructions is in the same
3050 ;; basic block after gcse & loop optimizations, we want to transform them
3051 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
3052 (define_insn_and_split "*divsi_inv_fp_combine"
3053 [(set (match_operand:SI 0 "register_operand" "=f")
3054 (div:SI (match_operand:SI 1 "register_operand" "f")
3055 (match_operand:SI 2 "register_operand" "f")))
3056 (use (unspec:SI [(match_dup 1)
3057 (match_operand:SI 3 "" "")
3058 (unspec:SI [(match_operand:SI 4 "" "")
3060 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
3061 (match_operand:DI 6 "" "")
3063 (const_int 0)] UNSPEC_DIV_INV_M3))
3064 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
3065 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
3066 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
3067 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
3068 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
3069 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
3072 [(set (match_dup 9) (float:DF (match_dup 1)))
3073 (set (match_dup 10) (float:DF (match_dup 2)))
3074 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
3076 (fix:SI (match_dup 11)))
3077 (set (match_dup 0) (match_dup 8))]
3079 if (! fp_arith_reg_operand (operands[1], SImode))
3081 emit_move_insn (operands[7], operands[1]);
3082 operands[1] = operands[7];
3084 if (! fp_arith_reg_operand (operands[2], SImode))
3086 emit_move_insn (operands[8], operands[2]);
3087 operands[2] = operands[8];
3090 [(set_attr "highpart" "must_split")])
3092 ;; -------------------------------------------------------------------------
3093 ;; Multiplication instructions
3094 ;; -------------------------------------------------------------------------
3096 (define_insn "umulhisi3_i"
3097 [(set (reg:SI MACL_REG)
3098 (mult:SI (zero_extend:SI
3099 (match_operand:HI 0 "arith_reg_operand" "r"))
3101 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3104 [(set_attr "type" "smpy")])
3106 (define_insn "mulhisi3_i"
3107 [(set (reg:SI MACL_REG)
3108 (mult:SI (sign_extend:SI
3109 (match_operand:HI 0 "arith_reg_operand" "r"))
3111 (match_operand:HI 1 "arith_reg_operand" "r"))))]
3114 [(set_attr "type" "smpy")])
3116 (define_expand "mulhisi3"
3117 [(set (reg:SI MACL_REG)
3118 (mult:SI (sign_extend:SI
3119 (match_operand:HI 1 "arith_reg_operand" ""))
3121 (match_operand:HI 2 "arith_reg_operand" ""))))
3122 (set (match_operand:SI 0 "arith_reg_operand" "")
3128 macl = gen_rtx_REG (SImode, MACL_REG);
3130 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
3131 insn = get_insns ();
3133 /* expand_binop can't find a suitable code in umul_widen_optab to
3134 make a REG_EQUAL note from, so make one here.
3135 See also smulsi3_highpart.
3136 ??? Alternatively, we could put this at the calling site of expand_binop,
3137 i.e. expand_expr. */
3138 /* Use emit_libcall_block for loop invariant code motion and to make
3139 a REG_EQUAL note. */
3140 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3145 (define_expand "umulhisi3"
3146 [(set (reg:SI MACL_REG)
3147 (mult:SI (zero_extend:SI
3148 (match_operand:HI 1 "arith_reg_operand" ""))
3150 (match_operand:HI 2 "arith_reg_operand" ""))))
3151 (set (match_operand:SI 0 "arith_reg_operand" "")
3157 macl = gen_rtx_REG (SImode, MACL_REG);
3159 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
3160 insn = get_insns ();
3162 /* expand_binop can't find a suitable code in umul_widen_optab to
3163 make a REG_EQUAL note from, so make one here.
3164 See also smulsi3_highpart.
3165 ??? Alternatively, we could put this at the calling site of expand_binop,
3166 i.e. expand_expr. */
3167 /* Use emit_libcall_block for loop invariant code motion and to make
3168 a REG_EQUAL note. */
3169 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
3174 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
3175 ;; a call to a routine which clobbers known registers.
3178 [(set (match_operand:SI 1 "register_operand" "=z")
3179 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
3180 (clobber (reg:SI MACL_REG))
3181 (clobber (reg:SI T_REG))
3182 (clobber (reg:SI PR_REG))
3183 (clobber (reg:SI R3_REG))
3184 (clobber (reg:SI R2_REG))
3185 (clobber (reg:SI R1_REG))
3186 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
3189 [(set_attr "type" "sfunc")
3190 (set_attr "needs_delay_slot" "yes")])
3192 (define_expand "mulsi3_call"
3193 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
3194 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
3195 (parallel[(set (match_operand:SI 0 "register_operand" "")
3196 (mult:SI (reg:SI R4_REG)
3198 (clobber (reg:SI MACL_REG))
3199 (clobber (reg:SI T_REG))
3200 (clobber (reg:SI PR_REG))
3201 (clobber (reg:SI R3_REG))
3202 (clobber (reg:SI R2_REG))
3203 (clobber (reg:SI R1_REG))
3204 (use (match_operand:SI 3 "register_operand" ""))])]
3208 (define_insn "mul_r"
3209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
3211 (match_operand:SI 2 "arith_reg_operand" "z")))]
3214 [(set_attr "type" "dmpy")])
3216 (define_insn "mul_l"
3217 [(set (reg:SI MACL_REG)
3218 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
3219 (match_operand:SI 1 "arith_reg_operand" "r")))]
3222 [(set_attr "type" "dmpy")])
3224 (define_expand "mulsi3"
3225 [(set (reg:SI MACL_REG)
3226 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
3227 (match_operand:SI 2 "arith_reg_operand" "")))
3228 (set (match_operand:SI 0 "arith_reg_operand" "")
3234 /* The address must be set outside the libcall,
3235 since it goes into a pseudo. */
3236 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
3237 rtx addr = force_reg (SImode, sym);
3238 rtx insns = gen_mulsi3_call (operands[0], operands[1],
3244 rtx macl = gen_rtx_REG (SImode, MACL_REG);
3246 emit_insn (gen_mul_l (operands[1], operands[2]));
3247 /* consec_sets_giv can only recognize the first insn that sets a
3248 giv as the giv insn. So we must tag this also with a REG_EQUAL
3250 emit_insn (gen_movsi_i ((operands[0]), macl));
3255 (define_insn "mulsidi3_i"
3256 [(set (reg:SI MACH_REG)
3260 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3261 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3263 (set (reg:SI MACL_REG)
3264 (mult:SI (match_dup 0)
3268 [(set_attr "type" "dmpy")])
3270 (define_expand "mulsidi3"
3271 [(set (match_operand:DI 0 "arith_reg_dest" "")
3272 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3273 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3274 "TARGET_SH2 || TARGET_SHMEDIA"
3278 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
3283 (define_insn "mulsidi3_media"
3284 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3285 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3286 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3289 [(set_attr "type" "dmpy_media")
3290 (set_attr "highpart" "ignore")])
3292 (define_insn_and_split "mulsidi3_compact"
3293 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3295 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3296 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3297 (clobber (reg:SI MACH_REG))
3298 (clobber (reg:SI MACL_REG))]
3304 rtx low_dst = gen_lowpart (SImode, operands[0]);
3305 rtx high_dst = gen_highpart (SImode, operands[0]);
3307 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
3309 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3310 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3311 /* We need something to tag the possible REG_EQUAL notes on to. */
3312 emit_move_insn (operands[0], operands[0]);
3316 (define_insn "umulsidi3_i"
3317 [(set (reg:SI MACH_REG)
3321 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3322 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3324 (set (reg:SI MACL_REG)
3325 (mult:SI (match_dup 0)
3329 [(set_attr "type" "dmpy")])
3331 (define_expand "umulsidi3"
3332 [(set (match_operand:DI 0 "arith_reg_dest" "")
3333 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3334 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
3335 "TARGET_SH2 || TARGET_SHMEDIA"
3339 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
3344 (define_insn "umulsidi3_media"
3345 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3346 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
3347 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
3350 [(set_attr "type" "dmpy_media")
3351 (set_attr "highpart" "ignore")])
3353 (define_insn_and_split "umulsidi3_compact"
3354 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3356 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3357 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3358 (clobber (reg:SI MACH_REG))
3359 (clobber (reg:SI MACL_REG))]
3365 rtx low_dst = gen_lowpart (SImode, operands[0]);
3366 rtx high_dst = gen_highpart (SImode, operands[0]);
3368 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3370 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3371 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3372 /* We need something to tag the possible REG_EQUAL notes on to. */
3373 emit_move_insn (operands[0], operands[0]);
3377 (define_insn "smulsi3_highpart_i"
3378 [(set (reg:SI MACH_REG)
3382 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3383 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3385 (clobber (reg:SI MACL_REG))]
3388 [(set_attr "type" "dmpy")])
3390 (define_expand "smulsi3_highpart"
3392 [(set (reg:SI MACH_REG)
3396 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3397 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3399 (clobber (reg:SI MACL_REG))])
3400 (set (match_operand:SI 0 "arith_reg_operand" "")
3406 mach = gen_rtx_REG (SImode, MACH_REG);
3408 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3409 insn = get_insns ();
3411 /* expand_binop can't find a suitable code in mul_highpart_optab to
3412 make a REG_EQUAL note from, so make one here.
3413 See also {,u}mulhisi.
3414 ??? Alternatively, we could put this at the calling site of expand_binop,
3415 i.e. expand_mult_highpart. */
3416 /* Use emit_libcall_block for loop invariant code motion and to make
3417 a REG_EQUAL note. */
3418 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3423 (define_insn "umulsi3_highpart_i"
3424 [(set (reg:SI MACH_REG)
3428 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3429 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3431 (clobber (reg:SI MACL_REG))]
3434 [(set_attr "type" "dmpy")])
3436 (define_expand "umulsi3_highpart"
3438 [(set (reg:SI MACH_REG)
3442 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3443 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3445 (clobber (reg:SI MACL_REG))])
3446 (set (match_operand:SI 0 "arith_reg_operand" "")
3452 mach = gen_rtx_REG (SImode, MACH_REG);
3454 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3455 insn = get_insns ();
3457 /* Use emit_libcall_block for loop invariant code motion and to make
3458 a REG_EQUAL note. */
3459 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3464 (define_insn_and_split "muldi3"
3465 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3466 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3467 (match_operand:DI 2 "arith_reg_operand" "r")))
3468 (clobber (match_scratch:DI 3 "=&r"))
3469 (clobber (match_scratch:DI 4 "=r"))]
3475 rtx op3_v2si, op2_v2si;
3477 op3_v2si = operands[3];
3478 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3480 op3_v2si = XEXP (op3_v2si, 0);
3481 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3483 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3484 op2_v2si = operands[2];
3485 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3487 op2_v2si = XEXP (op2_v2si, 0);
3488 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3490 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3491 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3492 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3493 emit_insn (gen_umulsidi3_media (operands[4],
3494 sh_gen_truncate (SImode, operands[1], 0),
3495 sh_gen_truncate (SImode, operands[2], 0)));
3496 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3497 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3498 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3499 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3504 ;; -------------------------------------------------------------------------
3505 ;; Logical operations
3506 ;; -------------------------------------------------------------------------
3508 (define_expand "andsi3"
3509 [(set (match_operand:SI 0 "arith_reg_operand" "")
3510 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3511 (match_operand:SI 2 "logical_and_operand" "")))]
3514 /* If it is possible to turn the and insn into a zero extension
3515 already, redundant zero extensions will be folded, which results
3517 Ideally the splitter of *andsi_compact would be enough, if reundant
3518 zero extensions were detected after the combine pass, which does not
3519 happen at the moment. */
3522 if (satisfies_constraint_Jmb (operands[2]))
3524 emit_insn (gen_zero_extendqisi2 (operands[0],
3525 gen_lowpart (QImode, operands[1])));
3528 else if (satisfies_constraint_Jmw (operands[2]))
3530 emit_insn (gen_zero_extendhisi2 (operands[0],
3531 gen_lowpart (HImode, operands[1])));
3537 (define_insn_and_split "*andsi_compact"
3538 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3539 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3540 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3548 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3550 if (satisfies_constraint_Jmb (operands[2]))
3551 operands[1] = gen_lowpart (QImode, operands[1]);
3552 else if (satisfies_constraint_Jmw (operands[2]))
3553 operands[1] = gen_lowpart (HImode, operands[1]);
3557 [(set_attr "type" "arith")])
3559 (define_insn "*andsi3_media"
3560 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3561 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3562 (match_operand:SI 2 "logical_operand" "r,I10")))]
3567 [(set_attr "type" "arith_media")])
3569 (define_insn "*andsi3_bclr"
3570 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3571 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3572 (match_operand:SI 2 "const_int_operand" "Psz")))]
3573 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3575 [(set_attr "type" "arith")])
3577 (define_insn_and_split "anddi3"
3578 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3579 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3580 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3587 && ! logical_operand (operands[2], DImode)"
3590 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3591 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3593 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3596 [(set_attr "type" "arith_media")])
3598 (define_insn "andcsi3"
3599 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3600 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3601 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3604 [(set_attr "type" "arith_media")])
3606 (define_insn "andcdi3"
3607 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3608 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3609 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3612 [(set_attr "type" "arith_media")])
3614 (define_expand "iorsi3"
3615 [(set (match_operand:SI 0 "arith_reg_operand" "")
3616 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3617 (match_operand:SI 2 "logical_operand" "")))]
3621 (define_insn "*iorsi3_compact"
3622 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3623 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3624 (match_operand:SI 2 "logical_operand" "r,K08")))]
3626 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3628 [(set_attr "type" "arith")])
3630 (define_insn "*iorsi3_media"
3631 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3632 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3633 (match_operand:SI 2 "logical_operand" "r,I10")))]
3638 [(set_attr "type" "arith_media")])
3640 (define_insn "*iorsi3_bset"
3641 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3642 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3643 (match_operand:SI 2 "const_int_operand" "Pso")))]
3644 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3646 [(set_attr "type" "arith")])
3648 (define_insn "iordi3"
3649 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3650 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3651 (match_operand:DI 2 "logical_operand" "r,I10")))]
3656 [(set_attr "type" "arith_media")])
3658 (define_insn_and_split "*logical_sidi3"
3659 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3660 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3661 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3662 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3665 "&& reload_completed"
3666 [(set (match_dup 0) (match_dup 3))]
3669 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3670 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3671 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3674 (define_insn_and_split "*logical_sidisi3"
3675 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3676 (truncate:SI (sign_extend:DI
3677 (match_operator:SI 3 "logical_operator"
3678 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3679 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3683 [(set (match_dup 0) (match_dup 3))])
3685 (define_insn_and_split "*logical_sidi3_2"
3686 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3687 (sign_extend:DI (truncate:SI (sign_extend:DI
3688 (match_operator:SI 3 "logical_operator"
3689 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3690 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3694 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3696 (define_expand "xorsi3"
3697 [(set (match_operand:SI 0 "arith_reg_operand" "")
3698 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3699 (match_operand:SI 2 "xor_operand" "")))]
3703 (define_insn "*xorsi3_compact"
3704 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3705 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3706 (match_operand:SI 2 "logical_operand" "K08,r")))]
3709 [(set_attr "type" "arith")])
3711 ;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
3712 ;; of results where one of the inputs is a T bit store. Notice that this
3713 ;; pattern must not match during reload. If reload picks this pattern it
3714 ;; will be impossible to split it afterwards.
3715 (define_insn_and_split "*logical_op_t"
3716 [(set (match_operand:SI 0 "arith_reg_dest")
3717 (match_operator:SI 3 "logical_operator"
3718 [(match_operand:SI 1 "arith_reg_operand")
3719 (match_operand:SI 2 "t_reg_operand")]))]
3720 "TARGET_SH1 && can_create_pseudo_p ()"
3723 [(set (match_dup 4) (reg:SI T_REG))
3724 (set (match_dup 0) (match_dup 3))]
3726 operands[4] = gen_reg_rtx (SImode);
3727 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3728 operands[1], operands[4]);
3731 (define_insn "*xorsi3_media"
3732 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3733 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3734 (match_operand:SI 2 "xor_operand" "r,I06")))]
3739 [(set_attr "type" "arith_media")])
3741 (define_insn "xordi3"
3742 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3743 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3744 (match_operand:DI 2 "xor_operand" "r,I06")))]
3749 [(set_attr "type" "arith_media")])
3751 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3752 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3754 [(set (match_operand:DI 0 "arith_reg_dest" "")
3755 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3756 [(match_operand 1 "any_register_operand" "")
3757 (match_operand 2 "any_register_operand" "")])))]
3759 [(set (match_dup 5) (match_dup 4))
3760 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3762 enum machine_mode inmode = GET_MODE (operands[1]);
3765 if (GET_CODE (operands[0]) == SUBREG)
3767 offset = SUBREG_BYTE (operands[0]);
3768 operands[0] = SUBREG_REG (operands[0]);
3770 gcc_assert (REG_P (operands[0]));
3771 if (! TARGET_LITTLE_ENDIAN)
3772 offset += 8 - GET_MODE_SIZE (inmode);
3773 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3776 ;; -------------------------------------------------------------------------
3777 ;; Shifts and rotates
3778 ;; -------------------------------------------------------------------------
3780 (define_expand "rotldi3"
3781 [(set (match_operand:DI 0 "arith_reg_dest" "")
3782 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "")
3783 (match_operand:HI 2 "mextr_bit_offset" "")))]
3786 if (! mextr_bit_offset (operands[2], HImode))
3790 (define_insn "rotldi3_mextr"
3791 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3792 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3793 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3796 static char templ[16];
3797 sprintf (templ, "mextr%d %%1,%%1,%%0",
3798 8 - (int) (INTVAL (operands[2]) >> 3));
3801 [(set_attr "type" "arith_media")])
3803 (define_expand "rotrdi3"
3804 [(set (match_operand:DI 0 "arith_reg_dest" "")
3805 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "")
3806 (match_operand:HI 2 "mextr_bit_offset" "")))]
3809 if (! mextr_bit_offset (operands[2], HImode))
3813 (define_insn "rotrdi3_mextr"
3814 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3815 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3816 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3819 static char templ[16];
3820 sprintf (templ, "mextr%d %%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
3823 [(set_attr "type" "arith_media")])
3826 [(set (match_operand:DI 0 "arith_reg_dest" "")
3827 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3828 "ua_address_operand" "")))
3829 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3831 (clobber (match_operand:DI 3 "register_operand" ""))]
3833 [(match_dup 4) (match_dup 5)]
3835 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3836 (operands[3], operands[1]));
3837 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3838 GEN_INT (56), GEN_INT (8));
3841 (define_expand "rotrsi3"
3842 [(set (match_operand:SI 0 "arith_reg_dest")
3843 (rotatert:SI (match_operand:SI 1 "arith_reg_operand")
3844 (match_operand:SI 2 "const_int_operand")))]
3847 HOST_WIDE_INT ival = INTVAL (operands[2]);
3850 emit_insn (gen_rotrsi3_1 (operands[0], operands[1]));
3857 (define_insn "rotrsi3_1"
3858 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3859 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
3862 (and:SI (match_dup 1) (const_int 1)))]
3865 [(set_attr "type" "arith")])
3867 ;; A slimplified version of rotr for combine.
3868 (define_insn "*rotrsi3_1"
3869 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3870 (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0")
3872 (clobber (reg:SI T_REG))]
3875 [(set_attr "type" "arith")])
3877 (define_insn "rotlsi3_1"
3878 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3879 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3882 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3885 [(set_attr "type" "arith")])
3887 ;; A simplified version of rotl for combine.
3888 (define_insn "*rotlsi3_1"
3889 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3890 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3892 (clobber (reg:SI T_REG))]
3895 [(set_attr "type" "arith")])
3897 (define_insn "rotlsi3_31"
3898 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3899 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3901 (clobber (reg:SI T_REG))]
3904 [(set_attr "type" "arith")])
3906 (define_insn "rotlsi3_16"
3907 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3908 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3912 [(set_attr "type" "arith")])
3914 (define_expand "rotlsi3"
3915 [(set (match_operand:SI 0 "arith_reg_dest")
3916 (rotate:SI (match_operand:SI 1 "arith_reg_operand")
3917 (match_operand:SI 2 "const_int_operand")))]
3920 static const char rot_tab[] = {
3921 000, 000, 000, 000, 000, 000, 010, 001,
3922 001, 001, 011, 013, 003, 003, 003, 003,
3923 003, 003, 003, 003, 003, 013, 012, 002,
3924 002, 002, 010, 000, 000, 000, 000, 000,
3927 int count = INTVAL (operands[2]);
3928 int choice = rot_tab[count];
3929 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3935 emit_move_insn (operands[0], operands[1]);
3936 count -= (count & 16) * 2;
3939 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3946 parts[0] = gen_reg_rtx (SImode);
3947 parts[1] = gen_reg_rtx (SImode);
3948 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3949 emit_move_insn (parts[choice-1], operands[1]);
3950 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3951 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3952 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3953 count = (count & ~16) - 8;
3957 for (; count > 0; count--)
3958 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3959 for (; count < 0; count++)
3960 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3965 (define_insn "*rotlhi3_8"
3966 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3967 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3971 [(set_attr "type" "arith")])
3973 (define_expand "rotlhi3"
3974 [(set (match_operand:HI 0 "arith_reg_operand")
3975 (rotate:HI (match_operand:HI 1 "arith_reg_operand")
3976 (match_operand:HI 2 "const_int_operand")))]
3979 if (INTVAL (operands[2]) != 8)
3983 ;; The rotcr insn is used primarily in DImode right shifts (arithmetic
3984 ;; and logical). It can also be used to implement things like
3986 ;; int x = (y >> 1) | (t << 31);
3987 (define_insn "rotcr"
3988 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3989 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3991 (ashift:SI (match_operand:SI 2 "t_reg_operand")
3994 (and:SI (match_dup 1) (const_int 1)))]
3997 [(set_attr "type" "arith")])
3999 ;; Simplified rotcr version for combine, which allows arbitrary shift
4000 ;; amounts for the reg. If the shift amount is '1' rotcr can be used
4001 ;; directly. Otherwise we have to insert a shift in between.
4002 (define_insn_and_split "*rotcr"
4003 [(set (match_operand:SI 0 "arith_reg_dest")
4004 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4005 (match_operand:SI 2 "const_int_operand"))
4006 (ashift:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
4008 (clobber (reg:SI T_REG))]
4011 "&& can_create_pseudo_p ()"
4014 if (INTVAL (operands[2]) > 1)
4016 const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
4017 rtx prev_set_t_insn = NULL_RTX;
4018 rtx tmp_t_reg = NULL_RTX;
4020 /* If we're going to emit a shift sequence that clobbers the T_REG,
4021 try to find the previous insn that sets the T_REG and emit the
4022 shift insn before that insn, to remove the T_REG dependency.
4023 If the insn that sets the T_REG cannot be found, store the T_REG
4024 in a temporary reg and restore it after the shift. */
4025 if (sh_lshrsi_clobbers_t_reg_p (shift_count)
4026 && ! sh_dynamicalize_shift_p (shift_count))
4028 prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
4030 /* Skip the nott insn, which was probably inserted by the splitter
4031 of *rotcr_neg_t. Don't use one of the recog functions
4032 here during insn splitting, since that causes problems in later
4034 if (prev_set_t_insn != NULL_RTX)
4036 rtx pat = PATTERN (prev_set_t_insn);
4037 if (GET_CODE (pat) == SET
4038 && t_reg_operand (XEXP (pat, 0), SImode)
4039 && negt_reg_operand (XEXP (pat, 1), SImode))
4040 prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
4043 if (! (prev_set_t_insn != NULL_RTX
4044 && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
4045 && ! reg_referenced_p (get_t_reg_rtx (),
4046 PATTERN (prev_set_t_insn))))
4048 prev_set_t_insn = NULL_RTX;
4049 tmp_t_reg = gen_reg_rtx (SImode);
4050 emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
4054 rtx shift_result = gen_reg_rtx (SImode);
4055 rtx shift_insn = gen_lshrsi3 (shift_result, operands[1], shift_count);
4056 operands[1] = shift_result;
4058 /* Emit the shift insn before the insn that sets T_REG, if possible. */
4059 if (prev_set_t_insn != NULL_RTX)
4060 emit_insn_before (shift_insn, prev_set_t_insn);
4062 emit_insn (shift_insn);
4064 /* Restore T_REG if it has been saved before. */
4065 if (tmp_t_reg != NULL_RTX)
4066 emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
4069 /* For the rotcr insn to work, operands[3] must be in T_REG.
4070 If it is not we can get it there by shifting it right one bit.
4071 In this case T_REG is not an input for this insn, thus we don't have to
4072 pay attention as of where to insert the shlr insn. */
4073 if (! t_reg_operand (operands[3], SImode))
4075 /* We don't care about the shifted result here, only the T_REG. */
4076 emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
4077 operands[3] = get_t_reg_rtx ();
4080 emit_insn (gen_rotcr (operands[0], operands[1], operands[3]));
4084 ;; If combine tries the same as above but with swapped operands, split
4085 ;; it so that it will try the pattern above.
4087 [(set (match_operand:SI 0 "arith_reg_dest")
4088 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
4090 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4091 (match_operand:SI 3 "const_int_operand"))))]
4092 "TARGET_SH1 && can_create_pseudo_p ()"
4093 [(parallel [(set (match_dup 0)
4094 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4095 (ashift:SI (match_dup 1) (const_int 31))))
4096 (clobber (reg:SI T_REG))])])
4098 ;; rotcr combine bridge pattern which will make combine try out more
4099 ;; complex patterns.
4100 (define_insn_and_split "*rotcr"
4101 [(set (match_operand:SI 0 "arith_reg_dest")
4102 (ashift:SI (match_operand:SI 1 "t_reg_operand") (const_int 31)))]
4106 [(set (match_dup 0) (match_dup 1))
4107 (parallel [(set (match_dup 0)
4108 (ior:SI (lshiftrt:SI (match_dup 0) (const_int 1))
4109 (ashift:SI (match_dup 1) (const_int 31))))
4111 (and:SI (match_dup 0) (const_int 1)))])])
4113 (define_insn_and_split "*rotcr"
4114 [(set (match_operand:SI 0 "arith_reg_dest")
4115 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand")
4116 (const_int -2147483648)) ;; 0xffffffff80000000
4117 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4119 (clobber (reg:SI T_REG))]
4122 "&& can_create_pseudo_p ()"
4125 rtx tmp = gen_reg_rtx (SImode);
4126 emit_insn (gen_shll (tmp, operands[1]));
4127 emit_insn (gen_rotcr (operands[0], operands[2], get_t_reg_rtx ()));
4131 ;; rotcr combine patterns for rotating in the negated T_REG value.
4132 (define_insn_and_split "*rotcr_neg_t"
4133 [(set (match_operand:SI 0 "arith_reg_dest")
4134 (ior:SI (match_operand:SI 1 "negt_reg_shl31_operand")
4135 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand")
4136 (match_operand:SI 3 "const_int_operand"))))
4137 (clobber (reg:SI T_REG))]
4140 "&& can_create_pseudo_p ()"
4141 [(parallel [(set (match_dup 0)
4142 (ior:SI (lshiftrt:SI (match_dup 2) (match_dup 3))
4143 (ashift:SI (reg:SI T_REG) (const_int 31))))
4144 (clobber (reg:SI T_REG))])]
4146 emit_insn (gen_nott (get_t_reg_rtx ()));
4149 (define_insn_and_split "*rotcr_neg_t"
4150 [(set (match_operand:SI 0 "arith_reg_dest")
4151 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
4152 (match_operand:SI 2 "const_int_operand"))
4153 (match_operand:SI 3 "negt_reg_shl31_operand")))
4154 (clobber (reg:SI T_REG))]
4157 "&& can_create_pseudo_p ()"
4158 [(parallel [(set (match_dup 0)
4159 (ior:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
4160 (ashift:SI (reg:SI T_REG) (const_int 31))))
4161 (clobber (reg:SI T_REG))])]
4163 emit_insn (gen_nott (get_t_reg_rtx ()));
4166 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4167 ;; SImode shift left
4169 (define_expand "ashlsi3"
4170 [(set (match_operand:SI 0 "arith_reg_operand" "")
4171 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
4172 (match_operand:SI 2 "shift_count_operand" "")))]
4177 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
4181 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4182 operands[2] = force_reg (SImode, operands[2]);
4184 /* If the ashlsi3_* insn is going to clobber the T_REG it must be
4186 if (CONST_INT_P (operands[2])
4187 && sh_ashlsi_clobbers_t_reg_p (operands[2])
4188 && ! sh_dynamicalize_shift_p (operands[2]))
4190 emit_insn (gen_ashlsi3_n_clobbers_t (operands[0], operands[1],
4195 /* Expand a library call for the dynamic shift. */
4196 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4198 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4199 rtx funcaddr = gen_reg_rtx (Pmode);
4200 function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
4201 emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
4207 (define_insn "ashlsi3_k"
4208 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4209 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
4210 (match_operand:SI 2 "p27_shift_count_operand" "M,P27")))]
4215 [(set_attr "type" "arith")])
4217 (define_insn_and_split "ashlsi3_d"
4218 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4219 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4220 (match_operand:SI 2 "shift_count_operand" "r")))]
4223 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4224 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4227 if (satisfies_constraint_P27 (operands[2]))
4229 emit_insn (gen_ashlsi3_k (operands[0], operands[1], operands[2]));
4232 else if (! satisfies_constraint_P27 (operands[2]))
4234 /* This must happen before reload, otherwise the constant will be moved
4235 into a register due to the "r" constraint, after which this split
4236 cannot be done anymore.
4237 Unfortunately the move insn will not always be eliminated.
4238 Also, here we must not create a shift sequence that clobbers the
4240 emit_move_insn (operands[0], operands[1]);
4241 gen_shifty_op (ASHIFT, operands);
4247 [(set_attr "type" "dyn_shift")])
4249 ;; If dynamic shifts are not available use a library function.
4250 ;; By specifying the pattern we reduce the number of call clobbered regs.
4251 ;; In order to make combine understand the truncation of the shift amount
4252 ;; operand we have to allow it to use pseudo regs for the shift operands.
4253 (define_insn "ashlsi3_d_call"
4254 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4255 (ashift:SI (reg:SI R4_REG)
4256 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4258 (use (match_operand:SI 2 "arith_reg_operand" "r"))
4259 (clobber (reg:SI T_REG))
4260 (clobber (reg:SI PR_REG))]
4261 "TARGET_SH1 && !TARGET_DYNSHIFT"
4263 [(set_attr "type" "sfunc")
4264 (set_attr "needs_delay_slot" "yes")])
4266 (define_insn_and_split "ashlsi3_n"
4267 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4268 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4269 (match_operand:SI 2 "not_p27_shift_count_operand" "")))]
4270 "TARGET_SH1 && ! sh_ashlsi_clobbers_t_reg_p (operands[2])"
4272 "&& (reload_completed
4273 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4276 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4278 /* If this pattern was picked and dynamic shifts are supported, switch
4279 to dynamic shift pattern before reload. */
4280 operands[2] = force_reg (SImode, operands[2]);
4281 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4284 gen_shifty_op (ASHIFT, operands);
4289 (define_insn_and_split "ashlsi3_n_clobbers_t"
4290 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4291 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
4292 (match_operand:SI 2 "not_p27_shift_count_operand" "")))
4293 (clobber (reg:SI T_REG))]
4294 "TARGET_SH1 && sh_ashlsi_clobbers_t_reg_p (operands[2])"
4296 "&& (reload_completed || INTVAL (operands[2]) == 31
4297 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4300 if (INTVAL (operands[2]) == 31)
4302 /* If the shift amount is 31 we split into a different sequence before
4303 reload so that it gets a chance to allocate R0 for the sequence.
4304 If it fails to do so (due to pressure on R0), it will take one insn
4305 more for the and. */
4306 emit_insn (gen_andsi3 (operands[0], operands[1], const1_rtx));
4307 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
4309 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4311 /* If this pattern was picked and dynamic shifts are supported, switch
4312 to dynamic shift pattern before reload. */
4313 operands[2] = force_reg (SImode, operands[2]);
4314 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
4317 gen_shifty_op (ASHIFT, operands);
4323 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4324 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4326 (lt:SI (match_dup 1) (const_int 0)))]
4329 [(set_attr "type" "arith")])
4331 (define_insn "*ashlsi_c_void"
4332 [(set (reg:SI T_REG)
4333 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
4334 (clobber (match_scratch:SI 1 "=0"))]
4335 "TARGET_SH1 && cse_not_expected"
4337 [(set_attr "type" "arith")])
4340 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
4342 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
4344 && peep2_reg_dead_p (2, operands[0])
4345 && peep2_reg_dead_p (2, operands[1])"
4348 emit_insn (gen_shll (operands[1], operands[1]));
4352 (define_insn "ashlsi3_media"
4353 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4354 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4355 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4360 [(set_attr "type" "arith_media")
4361 (set_attr "highpart" "ignore")])
4363 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4364 ;; HImode shift left
4366 (define_expand "ashlhi3"
4367 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
4368 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
4369 (match_operand:SI 2 "nonmemory_operand" "")))
4370 (clobber (reg:SI T_REG))])]
4373 if (!CONST_INT_P (operands[2]))
4375 /* It may be possible to call gen_ashlhi3 directly with more generic
4376 operands. Make sure operands[1] is a HImode register here. */
4377 if (!arith_reg_operand (operands[1], HImode))
4378 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4381 (define_insn "ashlhi3_k"
4382 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4383 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
4384 (match_operand:HI 2 "const_int_operand" "M,P27")))]
4385 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
4389 [(set_attr "type" "arith")])
4391 (define_insn_and_split "*ashlhi3_n"
4392 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4393 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
4394 (match_operand:HI 2 "const_int_operand" "n")))
4395 (clobber (reg:SI T_REG))]
4398 "&& reload_completed"
4399 [(use (reg:SI R0_REG))]
4401 gen_shifty_hi_op (ASHIFT, operands);
4405 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4406 ;; DImode shift left
4408 (define_expand "ashldi3"
4409 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4410 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4411 (match_operand:DI 2 "immediate_operand" "")))
4412 (clobber (reg:SI T_REG))])]
4417 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4420 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
4422 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4425 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
4427 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4434 ;; Expander for DImode shift left with SImode operations.
4435 (define_expand "ashldi3_std"
4436 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4437 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4438 (match_operand:DI 2 "const_int_operand" "n")))]
4439 "TARGET_SH1 && INTVAL (operands[2]) < 32"
4441 rtx low_src = gen_lowpart (SImode, operands[1]);
4442 rtx high_src = gen_highpart (SImode, operands[1]);
4443 rtx dst = gen_reg_rtx (DImode);
4444 rtx low_dst = gen_lowpart (SImode, dst);
4445 rtx high_dst = gen_highpart (SImode, dst);
4446 rtx tmp0 = gen_reg_rtx (SImode);
4447 rtx tmp1 = gen_reg_rtx (SImode);
4449 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4450 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
4451 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
4452 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4453 emit_move_insn (operands[0], dst);
4457 ;; This should be an define_insn_and_split.
4458 (define_insn "ashldi3_k"
4459 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4460 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
4462 (clobber (reg:SI T_REG))]
4464 "shll %R0\;rotcl %S0"
4465 [(set_attr "length" "4")
4466 (set_attr "type" "arith")])
4468 (define_insn "ashldi3_media"
4469 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4470 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4471 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4476 [(set_attr "type" "arith_media")])
4478 (define_insn "*ashldisi3_media"
4479 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4480 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4481 (match_operand:DI 2 "const_int_operand" "n")))]
4482 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4483 "shlli.l %1, %2, %0"
4484 [(set_attr "type" "arith_media")
4485 (set_attr "highpart" "ignore")])
4487 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4488 ;; SImode arithmetic shift right
4490 ;; We can't do HImode right shifts correctly unless we start out with an
4491 ;; explicit zero / sign extension; doing that would result in worse overall
4492 ;; code, so just let the machine independent code widen the mode.
4493 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
4495 (define_expand "ashrsi3"
4496 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4497 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4498 (match_operand:SI 2 "nonmemory_operand" "")))
4499 (clobber (reg:SI T_REG))])]
4504 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
4507 if (expand_ashiftrt (operands))
4514 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4515 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4518 (and:SI (match_dup 1) (const_int 1)))]
4521 [(set_attr "type" "arith")])
4523 (define_insn "ashrsi3_k"
4524 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4525 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4526 (match_operand:SI 2 "const_int_operand" "M")))
4527 (clobber (reg:SI T_REG))]
4528 "TARGET_SH1 && INTVAL (operands[2]) == 1"
4530 [(set_attr "type" "arith")])
4532 (define_insn_and_split "ashrsi2_16"
4533 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4534 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
4539 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
4540 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
4542 operands[2] = gen_lowpart (HImode, operands[0]);
4545 (define_insn_and_split "ashrsi2_31"
4546 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4547 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4549 (clobber (reg:SI T_REG))]
4555 emit_insn (gen_shll (operands[0], operands[1]));
4556 emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
4560 (define_insn "ashrsi3_d"
4561 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4562 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4563 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4566 [(set_attr "type" "dyn_shift")])
4568 (define_insn "ashrsi3_n"
4569 [(set (reg:SI R4_REG)
4570 (ashiftrt:SI (reg:SI R4_REG)
4571 (match_operand:SI 0 "const_int_operand" "i")))
4572 (clobber (reg:SI T_REG))
4573 (clobber (reg:SI PR_REG))
4574 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
4577 [(set_attr "type" "sfunc")
4578 (set_attr "needs_delay_slot" "yes")])
4580 (define_insn "ashrsi3_media"
4581 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4582 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4583 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4588 [(set_attr "type" "arith_media")
4589 (set_attr "highpart" "ignore")])
4591 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4592 ;; DImode arithmetic shift right
4594 (define_expand "ashrdi3"
4595 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4596 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4597 (match_operand:DI 2 "immediate_operand" "")))
4598 (clobber (reg:SI T_REG))])]
4603 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4606 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4610 (define_insn_and_split "ashrdi3_k"
4611 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4612 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4614 (clobber (reg:SI T_REG))]
4617 "&& reload_completed"
4620 rtx high = gen_highpart (SImode, operands[0]);
4621 rtx low = gen_lowpart (SImode, operands[0]);
4622 emit_insn (gen_shar (high, high));
4623 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
4627 (define_insn "ashrdi3_media"
4628 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4629 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4630 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4632 && (arith_reg_dest (operands[0], DImode)
4633 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4637 [(set_attr "type" "arith_media")])
4639 (define_insn "*ashrdisi3_media"
4640 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4641 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4642 (match_operand:DI 2 "const_int_operand" "n")))]
4643 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4644 "shari.l %1, %2, %0"
4645 [(set_attr "type" "arith_media")
4646 (set_attr "highpart" "ignore")])
4648 (define_insn "ashrdisi3_media_high"
4649 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4651 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4652 (match_operand:DI 2 "const_int_operand" "n"))))]
4653 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4655 [(set_attr "type" "arith_media")])
4657 (define_insn "ashrdisi3_media_opaque"
4658 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4659 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4660 (match_operand:DI 2 "const_int_operand" "n")]
4664 [(set_attr "type" "arith_media")])
4666 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4667 ;; SImode logical shift right
4669 (define_expand "lshrsi3"
4670 [(set (match_operand:SI 0 "arith_reg_dest" "")
4671 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
4672 (match_operand:SI 2 "shift_count_operand" "")))]
4677 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
4681 /* If a dynamic shift is supposed to be used, expand the lshrsi3_d insn
4682 here, otherwise the pattern will never match due to the shift amount reg
4685 && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
4687 rtx neg_count = force_reg (SImode,
4688 gen_int_mode (- INTVAL (operands[2]), SImode));
4689 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
4693 if (TARGET_DYNSHIFT && ! CONST_INT_P (operands[2]))
4695 rtx neg_count = gen_reg_rtx (SImode);
4696 emit_insn (gen_negsi2 (neg_count, operands[2]));
4697 emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
4701 /* If the lshrsi3_* insn is going to clobber the T_REG it must be
4703 if (CONST_INT_P (operands[2])
4704 && sh_lshrsi_clobbers_t_reg_p (operands[2])
4705 && ! sh_dynamicalize_shift_p (operands[2]))
4707 emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1],
4712 /* Expand a library call for the dynamic shift. */
4713 if (!CONST_INT_P (operands[2]) && !TARGET_DYNSHIFT)
4715 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
4716 rtx funcaddr = gen_reg_rtx (Pmode);
4717 function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
4718 emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
4723 (define_insn "lshrsi3_k"
4724 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4725 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4726 (match_operand:SI 2 "p27_rshift_count_operand" "P27")))]
4729 [(set_attr "type" "arith")])
4731 (define_insn_and_split "lshrsi3_d"
4732 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4733 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4734 (neg:SI (match_operand:SI 2 "shift_count_operand" "r"))))]
4737 "&& CONST_INT_P (operands[2]) && ! sh_dynamicalize_shift_p (operands[2])
4738 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
4741 if (satisfies_constraint_P27 (operands[2]))
4743 /* This will not be done for a shift amount of 1, because it would
4744 clobber the T_REG. */
4745 emit_insn (gen_lshrsi3_k (operands[0], operands[1], operands[2]));
4748 else if (! satisfies_constraint_P27 (operands[2]))
4750 /* This must happen before reload, otherwise the constant will be moved
4751 into a register due to the "r" constraint, after which this split
4752 cannot be done anymore.
4753 Unfortunately the move insn will not always be eliminated.
4754 Also, here we must not create a shift sequence that clobbers the
4756 emit_move_insn (operands[0], operands[1]);
4757 gen_shifty_op (LSHIFTRT, operands);
4763 [(set_attr "type" "dyn_shift")])
4765 ;; If dynamic shifts are not available use a library function.
4766 ;; By specifying the pattern we reduce the number of call clobbered regs.
4767 ;; In order to make combine understand the truncation of the shift amount
4768 ;; operand we have to allow it to use pseudo regs for the shift operands.
4769 (define_insn "lshrsi3_d_call"
4770 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
4771 (lshiftrt:SI (reg:SI R4_REG)
4772 (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
4774 (use (match_operand:SI 2 "arith_reg_operand" "r"))
4775 (clobber (reg:SI T_REG))
4776 (clobber (reg:SI PR_REG))]
4777 "TARGET_SH1 && !TARGET_DYNSHIFT"
4779 [(set_attr "type" "sfunc")
4780 (set_attr "needs_delay_slot" "yes")])
4782 (define_insn_and_split "lshrsi3_n"
4783 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4784 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4785 (match_operand:SI 2 "not_p27_rshift_count_operand")))]
4786 "TARGET_SH1 && ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
4788 "&& (reload_completed
4789 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4792 if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4794 /* If this pattern was picked and dynamic shifts are supported, switch
4795 to dynamic shift pattern before reload. */
4796 operands[2] = force_reg (SImode,
4797 gen_int_mode (- INTVAL (operands[2]), SImode));
4798 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
4801 gen_shifty_op (LSHIFTRT, operands);
4806 ;; The lshrsi3_n_clobbers_t pattern also works as a simplified version of
4807 ;; the shlr pattern.
4808 (define_insn_and_split "lshrsi3_n_clobbers_t"
4809 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4810 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4811 (match_operand:SI 2 "not_p27_rshift_count_operand")))
4812 (clobber (reg:SI T_REG))]
4813 "TARGET_SH1 && sh_lshrsi_clobbers_t_reg_p (operands[2])"
4815 "&& (reload_completed || INTVAL (operands[2]) == 31
4816 || (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ()))"
4819 if (INTVAL (operands[2]) == 31)
4821 emit_insn (gen_shll (operands[0], operands[1]));
4822 emit_insn (gen_movt (operands[0], get_t_reg_rtx ()));
4824 else if (sh_dynamicalize_shift_p (operands[2]) && can_create_pseudo_p ())
4826 /* If this pattern was picked and dynamic shifts are supported, switch
4827 to dynamic shift pattern before reload. */
4828 operands[2] = force_reg (SImode,
4829 gen_int_mode (- INTVAL (operands[2]), SImode));
4830 emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
4833 gen_shifty_op (LSHIFTRT, operands);
4839 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4840 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4843 (and:SI (match_dup 1) (const_int 1)))]
4846 [(set_attr "type" "arith")])
4848 (define_insn "lshrsi3_media"
4849 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4850 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
4851 (match_operand:SI 2 "shift_count_operand" "r,n")))]
4856 [(set_attr "type" "arith_media")
4857 (set_attr "highpart" "ignore")])
4859 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4860 ;; DImode logical shift right
4862 (define_expand "lshrdi3"
4863 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4864 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4865 (match_operand:DI 2 "immediate_operand" "")))
4866 (clobber (reg:SI T_REG))])]
4871 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4874 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4878 (define_insn_and_split "lshrdi3_k"
4879 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4880 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4882 (clobber (reg:SI T_REG))]
4885 "&& reload_completed"
4888 rtx high = gen_highpart (SImode, operands[0]);
4889 rtx low = gen_lowpart (SImode, operands[0]);
4890 emit_insn (gen_shlr (high, high));
4891 emit_insn (gen_rotcr (low, low, get_t_reg_rtx ()));
4895 (define_insn "lshrdi3_media"
4896 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4897 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4898 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4900 && (arith_reg_dest (operands[0], DImode)
4901 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4905 [(set_attr "type" "arith_media")])
4907 (define_insn "*lshrdisi3_media"
4908 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4909 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4910 (match_operand:DI 2 "const_int_operand" "n")))]
4911 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4912 "shlri.l %1, %2, %0"
4913 [(set_attr "type" "arith_media")
4914 (set_attr "highpart" "ignore")])
4916 ;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4917 ;; Combined left/right shifts
4920 [(set (match_operand:SI 0 "register_operand" "")
4921 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4922 (match_operand:SI 2 "const_int_operand" ""))
4923 (match_operand:SI 3 "const_int_operand" "")))]
4924 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4925 [(use (reg:SI R0_REG))]
4927 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4933 [(set (match_operand:SI 0 "register_operand" "")
4934 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4935 (match_operand:SI 2 "const_int_operand" ""))
4936 (match_operand:SI 3 "const_int_operand" "")))
4937 (clobber (reg:SI T_REG))]
4938 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4939 [(use (reg:SI R0_REG))]
4941 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4947 [(set (match_operand:SI 0 "register_operand" "=r")
4948 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4949 (match_operand:SI 2 "const_int_operand" "n"))
4950 (match_operand:SI 3 "const_int_operand" "n")))
4951 (clobber (reg:SI T_REG))]
4952 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4954 [(set (attr "length")
4955 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4957 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4959 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4961 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4963 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4965 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4967 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4968 (const_string "16")]
4969 (const_string "18")))
4970 (set_attr "type" "arith")])
4973 [(set (match_operand:SI 0 "register_operand" "=z")
4974 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4975 (match_operand:SI 2 "const_int_operand" "n"))
4976 (match_operand:SI 3 "const_int_operand" "n")))
4977 (clobber (reg:SI T_REG))]
4978 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4980 [(set (attr "length")
4981 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4983 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4985 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4987 (const_string "10")))
4988 (set_attr "type" "arith")])
4990 ;; shift left / and combination with a scratch register: The combine pass
4991 ;; does not accept the individual instructions, even though they are
4992 ;; cheap. But it needs a precise description so that it is usable after
4994 (define_insn "and_shl_scratch"
4995 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4999 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
5000 (match_operand:SI 2 "const_int_operand" "N,n"))
5001 (match_operand:SI 3 "" "0,r"))
5002 (match_operand:SI 4 "const_int_operand" "n,n"))
5003 (match_operand:SI 5 "const_int_operand" "n,n")))
5004 (clobber (reg:SI T_REG))]
5007 [(set (attr "length")
5008 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
5010 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
5012 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
5014 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
5015 (const_string "10")]
5016 (const_string "12")))
5017 (set_attr "type" "arith")])
5020 [(set (match_operand:SI 0 "register_operand" "")
5024 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5025 (match_operand:SI 2 "const_int_operand" ""))
5026 (match_operand:SI 3 "register_operand" ""))
5027 (match_operand:SI 4 "const_int_operand" ""))
5028 (match_operand:SI 5 "const_int_operand" "")))
5029 (clobber (reg:SI T_REG))]
5031 [(use (reg:SI R0_REG))]
5033 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
5035 if (INTVAL (operands[2]))
5037 gen_shifty_op (LSHIFTRT, operands);
5039 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
5040 operands[2] = operands[4];
5041 gen_shifty_op (ASHIFT, operands);
5042 if (INTVAL (operands[5]))
5044 operands[2] = operands[5];
5045 gen_shifty_op (LSHIFTRT, operands);
5050 ;; signed left/right shift combination.
5052 [(set (match_operand:SI 0 "register_operand" "")
5054 (ashift:SI (match_operand:SI 1 "register_operand" "")
5055 (match_operand:SI 2 "const_int_operand" ""))
5056 (match_operand:SI 3 "const_int_operand" "")
5058 (clobber (reg:SI T_REG))]
5060 [(use (reg:SI R0_REG))]
5062 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
5067 (define_insn "shl_sext_ext"
5068 [(set (match_operand:SI 0 "register_operand" "=r")
5070 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5071 (match_operand:SI 2 "const_int_operand" "n"))
5072 (match_operand:SI 3 "const_int_operand" "n")
5074 (clobber (reg:SI T_REG))]
5075 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
5077 [(set (attr "length")
5078 (cond [(match_test "shl_sext_length (insn)")
5080 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
5082 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5084 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5086 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5088 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5090 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
5092 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
5093 (const_string "16")]
5094 (const_string "18")))
5095 (set_attr "type" "arith")])
5097 (define_insn "shl_sext_sub"
5098 [(set (match_operand:SI 0 "register_operand" "=z")
5100 (ashift:SI (match_operand:SI 1 "register_operand" "0")
5101 (match_operand:SI 2 "const_int_operand" "n"))
5102 (match_operand:SI 3 "const_int_operand" "n")
5104 (clobber (reg:SI T_REG))]
5105 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
5107 [(set (attr "length")
5108 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
5110 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
5112 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
5114 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
5115 (const_string "12")]
5116 (const_string "14")))
5117 (set_attr "type" "arith")])
5119 ;; These patterns are found in expansions of DImode shifts by 16, and
5120 ;; allow the xtrct instruction to be generated from C source.
5122 (define_insn "xtrct_left"
5123 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5124 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5126 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
5130 [(set_attr "type" "arith")])
5132 (define_insn "xtrct_right"
5133 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5134 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
5136 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
5140 [(set_attr "type" "arith")])
5142 ;; -------------------------------------------------------------------------
5144 ;; -------------------------------------------------------------------------
5147 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5148 (neg:SI (plus:SI (reg:SI T_REG)
5149 (match_operand:SI 1 "arith_reg_operand" "r"))))
5151 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
5155 [(set_attr "type" "arith")])
5157 ;; A simplified version of the negc insn, where the exact value of the
5158 ;; T bit doesn't matter. This is easier for combine to pick up.
5159 ;; Notice that '0 - x - 1' is the same as '~x', thus we don't specify
5160 ;; extra patterns for this case.
5161 (define_insn "*negc"
5162 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5163 (minus:SI (neg:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5164 (match_operand:SI 2 "t_reg_operand" "")))
5165 (clobber (reg:SI T_REG))]
5168 [(set_attr "type" "arith")])
5170 (define_insn "*negdi_media"
5171 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5172 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5175 [(set_attr "type" "arith_media")])
5177 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
5179 (define_expand "negdi2"
5180 [(set (match_operand:DI 0 "arith_reg_dest" "")
5181 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
5182 (clobber (reg:SI T_REG))]
5186 (define_insn_and_split "*negdi2"
5187 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5188 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5194 rtx low_src = gen_lowpart (SImode, operands[1]);
5195 rtx high_src = gen_highpart (SImode, operands[1]);
5196 rtx low_dst = gen_lowpart (SImode, operands[0]);
5197 rtx high_dst = gen_highpart (SImode, operands[0]);
5199 emit_insn (gen_clrt ());
5200 emit_insn (gen_negc (low_dst, low_src));
5201 emit_insn (gen_negc (high_dst, high_src));
5205 (define_insn "negsi2"
5206 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5207 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5210 [(set_attr "type" "arith")])
5212 (define_insn_and_split "one_cmplsi2"
5213 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5214 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5217 "&& can_create_pseudo_p ()"
5218 [(set (reg:SI T_REG) (ge:SI (match_dup 1) (const_int 0)))
5219 (set (match_dup 0) (reg:SI T_REG))]
5222 If the result of 'unsigned int <= 0x7FFFFFFF' ends up as the following
5225 (set (reg0) (not:SI (reg0) (reg1)))
5226 (parallel [(set (reg2) (lshiftrt:SI (reg0) (const_int 31)))
5227 (clobber (reg:SI T_REG))])
5229 ... match and combine the sequence manually in the split pass after the
5230 combine pass. Notice that combine does try the target pattern of this
5231 split, but if the pattern is added it interferes with other patterns, in
5232 particular with the div0s comparisons.
5233 This could also be done with a peephole but doing it here before register
5234 allocation can save one temporary.
5235 When we're here, the not:SI pattern obviously has been matched already
5236 and we only have to see whether the following insn is the left shift. */
5238 rtx i = next_nonnote_insn_bb (curr_insn);
5239 if (i == NULL_RTX || !NONJUMP_INSN_P (i))
5242 rtx p = PATTERN (i);
5243 if (GET_CODE (p) != PARALLEL || XVECLEN (p, 0) != 2)
5246 rtx p0 = XVECEXP (p, 0, 0);
5247 rtx p1 = XVECEXP (p, 0, 1);
5249 if (/* (set (reg2) (lshiftrt:SI (reg0) (const_int 31))) */
5250 GET_CODE (p0) == SET
5251 && GET_CODE (XEXP (p0, 1)) == LSHIFTRT
5252 && REG_P (XEXP (XEXP (p0, 1), 0))
5253 && REGNO (XEXP (XEXP (p0, 1), 0)) == REGNO (operands[0])
5254 && CONST_INT_P (XEXP (XEXP (p0, 1), 1))
5255 && INTVAL (XEXP (XEXP (p0, 1), 1)) == 31
5257 /* (clobber (reg:SI T_REG)) */
5258 && GET_CODE (p1) == CLOBBER && REG_P (XEXP (p1, 0))
5259 && REGNO (XEXP (p1, 0)) == T_REG)
5261 operands[0] = XEXP (p0, 0);
5262 set_insn_deleted (i);
5267 [(set_attr "type" "arith")])
5269 (define_expand "one_cmpldi2"
5270 [(set (match_operand:DI 0 "arith_reg_dest" "")
5271 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
5273 "TARGET_SHMEDIA" "")
5275 (define_expand "abssi2"
5276 [(set (match_operand:SI 0 "arith_reg_dest" "")
5277 (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
5278 (clobber (reg:SI T_REG))]
5282 (define_insn_and_split "*abssi2"
5283 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5284 (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
5290 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5291 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
5296 (define_insn_and_split "*negabssi2"
5297 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5298 (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
5304 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
5305 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
5310 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
5311 ;; This can be used as some kind of conditional execution, which is useful
5313 ;; Actually the instruction scheduling should decide whether to use a
5314 ;; zero-offset branch or not for any generic case involving a single
5315 ;; instruction on SH4 202.
5317 (define_insn_and_split "negsi_cond"
5318 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5319 (if_then_else:SI (eq:SI (reg:SI T_REG)
5320 (match_operand:SI 3 "const_int_operand" "M,N"))
5321 (match_operand:SI 1 "arith_reg_operand" "0,0")
5322 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
5323 "TARGET_SH1 && TARGET_ZDCBRANCH"
5325 static const char* alt[] =
5335 return alt[which_alternative];
5337 "TARGET_SH1 && ! TARGET_ZDCBRANCH"
5340 rtx skip_neg_label = gen_label_rtx ();
5342 emit_insn (gen_movsi (operands[0], operands[1]));
5344 emit_jump_insn (INTVAL (operands[3])
5345 ? gen_branch_true (skip_neg_label)
5346 : gen_branch_false (skip_neg_label));
5348 emit_label_after (skip_neg_label,
5349 emit_insn (gen_negsi2 (operands[0], operands[1])));
5352 [(set_attr "type" "arith") ;; poor approximation
5353 (set_attr "length" "4")])
5355 (define_expand "absdi2"
5356 [(set (match_operand:DI 0 "arith_reg_dest" "")
5357 (abs:DI (match_operand:DI 1 "arith_reg_operand" "")))
5358 (clobber (reg:SI T_REG))]
5362 (define_insn_and_split "*absdi2"
5363 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5364 (abs:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
5367 "&& reload_completed"
5370 rtx high_src = gen_highpart (SImode, operands[1]);
5371 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5372 emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
5377 (define_insn_and_split "*negabsdi2"
5378 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5379 (neg:DI (abs:DI (match_operand:DI 1 "arith_reg_operand" "r"))))]
5382 "&& reload_completed"
5385 rtx high_src = gen_highpart (SImode, operands[1]);
5386 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
5387 emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
5392 (define_insn_and_split "negdi_cond"
5393 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
5394 (if_then_else:DI (eq:SI (reg:SI T_REG)
5395 (match_operand:SI 3 "const_int_operand" "M,N"))
5396 (match_operand:DI 1 "arith_reg_operand" "r,r")
5397 (neg:DI (match_operand:DI 2 "arith_reg_operand" "1,1"))))]
5403 rtx low_src = gen_lowpart (SImode, operands[1]);
5404 rtx high_src = gen_highpart (SImode, operands[1]);
5405 rtx low_dst = gen_lowpart (SImode, operands[0]);
5406 rtx high_dst = gen_highpart (SImode, operands[0]);
5408 rtx skip_neg_label = gen_label_rtx ();
5410 emit_insn (gen_movsi (low_dst, low_src));
5411 emit_insn (gen_movsi (high_dst, high_src));
5413 emit_jump_insn (INTVAL (operands[3])
5414 ? gen_branch_true (skip_neg_label)
5415 : gen_branch_false (skip_neg_label));
5417 if (!INTVAL (operands[3]))
5418 emit_insn (gen_clrt ());
5420 emit_insn (gen_negc (low_dst, low_src));
5421 emit_label_after (skip_neg_label, emit_insn (gen_negc (high_dst, high_src)));
5425 (define_expand "bswapsi2"
5426 [(set (match_operand:SI 0 "arith_reg_dest" "")
5427 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
5430 if (! can_create_pseudo_p ())
5434 rtx tmp0 = gen_reg_rtx (SImode);
5435 rtx tmp1 = gen_reg_rtx (SImode);
5437 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
5438 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
5439 emit_insn (gen_swapbsi2 (operands[0], tmp1));
5444 (define_insn "swapbsi2"
5445 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5446 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
5447 (const_int 4294901760))
5448 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5450 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5451 (const_int 255)))))]
5454 [(set_attr "type" "arith")])
5456 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
5457 ;; partial byte swap expressions such as...
5458 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
5459 ;; ...which are currently not handled by the tree optimizers.
5460 ;; The combine pass will not initially try to combine the full expression,
5461 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
5462 ;; pattern acts as an intermediate pattern that will eventually lead combine
5463 ;; to the swapbsi2 pattern above.
5464 ;; As a side effect this also improves code that does (x & 0xFF) << 8
5465 ;; or (x << 8) & 0xFF00.
5466 (define_insn_and_split "*swapbisi2_and_shl8"
5467 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5468 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5471 (match_operand:SI 2 "arith_reg_operand" "r")))]
5472 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5474 "&& can_create_pseudo_p ()"
5477 rtx tmp0 = gen_reg_rtx (SImode);
5478 rtx tmp1 = gen_reg_rtx (SImode);
5480 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
5481 emit_insn (gen_swapbsi2 (tmp1, tmp0));
5482 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
5486 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
5487 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
5488 (define_insn_and_split "*swapbhisi2"
5489 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5490 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
5493 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
5494 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
5496 "&& can_create_pseudo_p ()"
5499 rtx tmp = gen_reg_rtx (SImode);
5501 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
5502 emit_insn (gen_swapbsi2 (operands[0], tmp));
5506 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
5510 ;; which can be simplified to...
5513 [(set (match_operand:SI 0 "arith_reg_dest" "")
5514 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5515 (const_int 4294901760))
5516 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5518 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5520 (set (match_operand:SI 2 "arith_reg_dest" "")
5522 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
5524 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
5525 (const_int 4294901760))
5526 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
5528 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
5529 (const_int 255)))))])
5532 ;; -------------------------------------------------------------------------
5533 ;; Zero extension instructions
5534 ;; -------------------------------------------------------------------------
5536 (define_insn "zero_extendsidi2"
5537 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
5538 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
5540 "addz.l %1, r63, %0"
5541 [(set_attr "type" "arith_media")
5542 (set_attr "highpart" "extend")])
5544 (define_insn "zero_extendhidi2"
5545 [(set (match_operand:DI 0 "register_operand" "=r,r")
5546 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5551 [(set_attr "type" "*,load_media")
5552 (set (attr "highpart")
5553 (cond [(match_test "sh_contains_memref_p (insn)")
5554 (const_string "user")]
5555 (const_string "ignore")))])
5558 [(set (match_operand:DI 0 "register_operand" "")
5559 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5560 "TARGET_SHMEDIA && reload_completed"
5561 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5562 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
5564 if (GET_CODE (operands[1]) == TRUNCATE)
5565 operands[1] = XEXP (operands[1], 0);
5568 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
5569 ;; reload the entire truncate expression.
5570 (define_insn_and_split "*loaddi_trunc"
5571 [(set (match_operand 0 "any_register_operand" "=r")
5572 (truncate (match_operand:DI 1 "memory_operand" "m")))]
5573 "TARGET_SHMEDIA && reload_completed"
5575 "TARGET_SHMEDIA && reload_completed"
5576 [(set (match_dup 0) (match_dup 1))]
5578 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5581 (define_insn "zero_extendqidi2"
5582 [(set (match_operand:DI 0 "register_operand" "=r,r")
5583 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5588 [(set_attr "type" "arith_media,load_media")
5589 (set (attr "highpart")
5590 (cond [(match_test "sh_contains_memref_p (insn)")
5591 (const_string "user")]
5592 (const_string "ignore")))])
5594 (define_expand "zero_extend<mode>si2"
5595 [(set (match_operand:SI 0 "arith_reg_dest")
5596 (zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
5598 (define_insn_and_split "*zero_extend<mode>si2_compact"
5599 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5600 (zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
5603 "&& can_create_pseudo_p ()"
5604 [(set (match_dup 0) (match_dup 2))]
5606 /* Sometimes combine fails to combine a T bit or negated T bit store to a
5607 reg with a following zero extension. In the split pass after combine,
5608 try to figure the extended reg was set. If it originated from the T
5609 bit we can replace the zero extension with a reg move, which will be
5610 eliminated. Notice that this also helps the *cbranch_t splitter when
5611 it tries to post-combine tests and conditional branches, as it does not
5612 check for zero extensions. */
5613 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
5614 if (operands[2] == NULL_RTX)
5617 [(set_attr "type" "arith")])
5619 (define_insn "*zero_extendhisi2_media"
5620 [(set (match_operand:SI 0 "register_operand" "=r,r")
5621 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5626 [(set_attr "type" "arith_media,load_media")
5627 (set (attr "highpart")
5628 (cond [(match_test "sh_contains_memref_p (insn)")
5629 (const_string "user")]
5630 (const_string "ignore")))])
5633 [(set (match_operand:SI 0 "register_operand" "")
5634 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
5635 "TARGET_SHMEDIA && reload_completed"
5636 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5637 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5639 rtx op1 = operands[1];
5641 if (GET_CODE (op1) == TRUNCATE)
5642 op1 = XEXP (op1, 0);
5644 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
5645 subreg_lowpart_offset (SImode, GET_MODE (op1)));
5648 (define_insn "*zero_extendqisi2_media"
5649 [(set (match_operand:SI 0 "register_operand" "=r,r")
5650 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5655 [(set_attr "type" "arith_media,load_media")
5656 (set (attr "highpart")
5657 (cond [(match_test "sh_contains_memref_p (insn)")
5658 (const_string "user")]
5659 (const_string "ignore")))])
5661 (define_insn "zero_extendqihi2"
5662 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
5663 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
5666 [(set_attr "type" "arith")])
5668 ;; SH2A supports two zero extending load instructions: movu.b and movu.w.
5669 ;; They could also be used for simple memory addresses like @Rn by setting
5670 ;; the displacement value to zero. However, doing so too early results in
5671 ;; missed opportunities for other optimizations such as post-inc or index
5672 ;; addressing loads.
5673 ;; Although the 'zero_extend_movu_operand' predicate does not allow simple
5674 ;; register addresses (an address without a displacement, index, post-inc),
5675 ;; zero-displacement addresses might be generated during reload, wich are
5676 ;; simplified to simple register addresses in turn. Thus, we have to
5677 ;; provide the Sdd and Sra alternatives in the patterns.
5678 (define_insn "*zero_extend<mode>si2_disp_mem"
5679 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
5681 (match_operand:QIHI 1 "zero_extend_movu_operand" "Sdd,Sra")))]
5685 movu.<bw> @(0,%t1),%0"
5686 [(set_attr "type" "load")
5687 (set_attr "length" "4")])
5689 ;; Convert the zero extending loads in sequences such as:
5690 ;; movu.b @(1,r5),r0 movu.w @(2,r5),r0
5691 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
5693 ;; back to sign extending loads like:
5694 ;; mov.b @(1,r5),r0 mov.w @(2,r5),r0
5695 ;; mov.b r0,@(1,r4) mov.b r0,@(1,r4)
5697 ;; if the extension type is irrelevant. The sign extending mov.{b|w} insn
5698 ;; is only 2 bytes in size if the displacement is {K04|K05}.
5699 ;; If the displacement is greater it doesn't matter, so we convert anyways.
5701 [(set (match_operand:SI 0 "arith_reg_dest" "")
5702 (zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
5703 (set (match_operand 2 "general_operand" "")
5704 (match_operand 3 "arith_reg_operand" ""))]
5706 && REGNO (operands[0]) == REGNO (operands[3])
5707 && peep2_reg_dead_p (2, operands[0])
5708 && GET_MODE_SIZE (GET_MODE (operands[2]))
5709 <= GET_MODE_SIZE (GET_MODE (operands[1]))"
5710 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
5711 (set (match_dup 2) (match_dup 3))])
5713 ;; Fold sequences such as
5717 ;; movu.b @(0,r3),r7
5718 ;; This does not reduce the code size but the number of instructions is
5719 ;; halved, which results in faster code.
5721 [(set (match_operand:SI 0 "arith_reg_dest" "")
5722 (sign_extend:SI (match_operand 1 "simple_mem_operand" "")))
5723 (set (match_operand:SI 2 "arith_reg_dest" "")
5724 (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
5726 && GET_MODE (operands[1]) == GET_MODE (operands[3])
5727 && (GET_MODE (operands[1]) == QImode || GET_MODE (operands[1]) == HImode)
5728 && REGNO (operands[0]) == REGNO (operands[3])
5729 && (REGNO (operands[2]) == REGNO (operands[0])
5730 || peep2_reg_dead_p (2, operands[0]))"
5731 [(set (match_dup 2) (zero_extend:SI (match_dup 4)))]
5734 = replace_equiv_address (operands[1],
5735 gen_rtx_PLUS (SImode, XEXP (operands[1], 0),
5739 ;; -------------------------------------------------------------------------
5740 ;; Sign extension instructions
5741 ;; -------------------------------------------------------------------------
5743 ;; ??? This should be a define expand.
5744 ;; ??? Or perhaps it should be dropped?
5746 ;; convert_move generates good code for SH[1-4].
5747 (define_insn "extendsidi2"
5748 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5749 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
5755 [(set_attr "type" "arith_media,load_media,fpconv_media")
5756 (set (attr "highpart")
5757 (cond [(match_test "sh_contains_memref_p (insn)")
5758 (const_string "user")]
5759 (const_string "extend")))])
5761 (define_insn "extendhidi2"
5762 [(set (match_operand:DI 0 "register_operand" "=r,r")
5763 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5768 [(set_attr "type" "*,load_media")
5769 (set (attr "highpart")
5770 (cond [(match_test "sh_contains_memref_p (insn)")
5771 (const_string "user")]
5772 (const_string "ignore")))])
5775 [(set (match_operand:DI 0 "register_operand" "")
5776 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
5777 "TARGET_SHMEDIA && reload_completed"
5778 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
5779 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
5781 if (GET_CODE (operands[1]) == TRUNCATE)
5782 operands[1] = XEXP (operands[1], 0);
5785 (define_insn "extendqidi2"
5786 [(set (match_operand:DI 0 "register_operand" "=r,r")
5787 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5792 [(set_attr "type" "*,load_media")
5793 (set (attr "highpart")
5794 (cond [(match_test "sh_contains_memref_p (insn)")
5795 (const_string "user")]
5796 (const_string "ignore")))])
5799 [(set (match_operand:DI 0 "register_operand" "")
5800 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
5801 "TARGET_SHMEDIA && reload_completed"
5802 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
5803 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
5805 if (GET_CODE (operands[1]) == TRUNCATE)
5806 operands[1] = XEXP (operands[1], 0);
5809 (define_expand "extend<mode>si2"
5810 [(set (match_operand:SI 0 "arith_reg_dest")
5811 (sign_extend:SI (match_operand:QIHI 1 "general_extend_operand")))])
5813 (define_insn "*extendhisi2_media"
5814 [(set (match_operand:SI 0 "register_operand" "=r,r")
5815 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
5820 [(set_attr "type" "arith_media,load_media")
5821 (set (attr "highpart")
5822 (cond [(match_test "sh_contains_memref_p (insn)")
5823 (const_string "user")]
5824 (const_string "ignore")))])
5827 [(set (match_operand:SI 0 "register_operand" "")
5828 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
5829 "TARGET_SHMEDIA && reload_completed"
5830 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5831 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5833 rtx op1 = operands[1];
5834 if (GET_CODE (op1) == TRUNCATE)
5835 op1 = XEXP (op1, 0);
5837 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
5838 subreg_lowpart_offset (SImode, GET_MODE (op1)));
5841 (define_insn_and_split "*extend<mode>si2_compact_reg"
5842 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5843 (sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
5846 "&& can_create_pseudo_p ()"
5847 [(set (match_dup 0) (match_dup 2))]
5849 /* Sometimes combine fails to combine a T bit or negated T bit store to a
5850 reg with a following sign extension. In the split pass after combine,
5851 try to figure the extended reg was set. If it originated from the T
5852 bit we can replace the sign extension with a reg move, which will be
5854 operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
5855 if (operands[2] == NULL_RTX)
5858 [(set_attr "type" "arith")])
5860 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
5862 (define_insn "*extend<mode>si2_compact_mem_disp"
5863 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
5867 (match_operand:SI 1 "arith_reg_operand" "%r,r")
5868 (match_operand:SI 2 "const_int_operand" "<disp04>,N")))))]
5869 "TARGET_SH1 && ! TARGET_SH2A
5870 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
5872 mov.<bw> @(%O2,%1),%0
5874 [(set_attr "type" "load")])
5876 (define_insn "*extend<mode>si2_compact_mem_disp"
5877 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
5881 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
5882 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>")))))]
5883 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
5885 mov.<bw> @(%O2,%1),%0
5887 mov.<bw> @(%O2,%1),%0"
5888 [(set_attr "type" "load")
5889 (set_attr "length" "2,2,4")])
5891 ;; The *_snd patterns will take care of other QImode/HImode addressing
5892 ;; modes than displacement addressing. They must be defined _after_ the
5893 ;; displacement addressing patterns. Otherwise the displacement addressing
5894 ;; patterns will not be picked.
5895 (define_insn "*extend<mode>si2_compact_snd"
5896 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5898 (match_operand:QIHI 1 "movsrc_no_disp_mem_operand" "Snd")))]
5901 [(set_attr "type" "load")])
5903 (define_insn "*extendqisi2_media"
5904 [(set (match_operand:SI 0 "register_operand" "=r,r")
5905 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5910 [(set_attr "type" "arith_media,load_media")
5911 (set (attr "highpart")
5912 (cond [(match_test "sh_contains_memref_p (insn)")
5913 (const_string "user")]
5914 (const_string "ignore")))])
5917 [(set (match_operand:SI 0 "register_operand" "")
5918 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
5919 "TARGET_SHMEDIA && reload_completed"
5920 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5921 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5923 rtx op1 = operands[1];
5924 if (GET_CODE (op1) == TRUNCATE)
5925 op1 = XEXP (op1, 0);
5927 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
5928 subreg_lowpart_offset (SImode, GET_MODE (op1)));
5931 (define_expand "extendqihi2"
5932 [(set (match_operand:HI 0 "arith_reg_dest" "")
5933 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
5937 (define_insn "*extendqihi2_compact_reg"
5938 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
5939 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
5942 [(set_attr "type" "arith")])
5944 ;; It would seem useful to combine the truncXi patterns into the movXi
5945 ;; patterns, but unary operators are ignored when matching constraints,
5946 ;; so we need separate patterns.
5947 (define_insn "truncdisi2"
5948 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
5949 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
5958 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
5959 (set (attr "highpart")
5960 (cond [(match_test "sh_contains_memref_p (insn)")
5961 (const_string "user")]
5962 (const_string "extend")))])
5964 (define_insn "truncdihi2"
5965 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
5966 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
5969 static const char* alt[] =
5971 "shlli %1,48,%0" "\n"
5976 return alt[which_alternative];
5978 [(set_attr "type" "arith_media,store_media")
5979 (set_attr "length" "8,4")
5980 (set (attr "highpart")
5981 (cond [(match_test "sh_contains_memref_p (insn)")
5982 (const_string "user")]
5983 (const_string "extend")))])
5985 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
5986 ; Because we use zero extension, we can't provide signed QImode compares
5987 ; using a simple compare or conditional branch insn.
5988 (define_insn "truncdiqi2"
5989 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
5990 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
5995 [(set_attr "type" "arith_media,store")
5996 (set (attr "highpart")
5997 (cond [(match_test "sh_contains_memref_p (insn)")
5998 (const_string "user")]
5999 (const_string "extend")))])
6000 ;; -------------------------------------------------------------------------
6001 ;; Move instructions
6002 ;; -------------------------------------------------------------------------
6004 ;; define push and pop so it is easy for sh.c
6005 ;; We can't use push and pop on SHcompact because the stack must always
6006 ;; be 8-byte aligned.
6008 (define_expand "push"
6009 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6010 (match_operand:SI 0 "register_operand" "r,l,x"))]
6011 "TARGET_SH1 && ! TARGET_SH5"
6014 (define_expand "pop"
6015 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
6016 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
6017 "TARGET_SH1 && ! TARGET_SH5"
6020 (define_expand "push_e"
6021 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
6022 (match_operand:SF 0 "" ""))
6023 (use (reg:PSI FPSCR_REG))
6024 (clobber (scratch:SI))])]
6025 "TARGET_SH1 && ! TARGET_SH5"
6028 (define_insn "push_fpul"
6029 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
6030 "TARGET_SH2E && ! TARGET_SH5"
6032 [(set_attr "type" "fstore")
6033 (set_attr "late_fp_use" "yes")
6034 (set_attr "hit_stack" "yes")])
6036 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
6038 (define_expand "push_4"
6039 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
6040 (match_operand:DF 0 "" ""))
6041 (use (reg:PSI FPSCR_REG))
6042 (clobber (scratch:SI))])]
6043 "TARGET_SH1 && ! TARGET_SH5"
6046 (define_expand "pop_e"
6047 [(parallel [(set (match_operand:SF 0 "" "")
6048 (mem:SF (post_inc:SI (reg:SI SP_REG))))
6049 (use (reg:PSI FPSCR_REG))
6050 (clobber (scratch:SI))])]
6051 "TARGET_SH1 && ! TARGET_SH5"
6054 (define_insn "pop_fpul"
6055 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
6056 "TARGET_SH2E && ! TARGET_SH5"
6058 [(set_attr "type" "load")
6059 (set_attr "hit_stack" "yes")])
6061 (define_expand "pop_4"
6062 [(parallel [(set (match_operand:DF 0 "" "")
6063 (mem:DF (post_inc:SI (reg:SI SP_REG))))
6064 (use (reg:PSI FPSCR_REG))
6065 (clobber (scratch:SI))])]
6066 "TARGET_SH1 && ! TARGET_SH5"
6069 (define_expand "push_fpscr"
6073 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
6074 gen_rtx_PRE_DEC (Pmode,
6075 stack_pointer_rtx)),
6077 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6081 (define_expand "pop_fpscr"
6085 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
6086 gen_frame_mem (PSImode,
6087 gen_rtx_POST_INC (Pmode,
6088 stack_pointer_rtx))));
6089 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6093 ;; The clrt and sett patterns can happen as the result of optimization and
6095 ;; Comparisons might get simplified to a move of zero or 1 into the T reg.
6096 ;; In this case they might not disappear completely, because the T reg is
6097 ;; a fixed hard reg.
6098 ;; When DImode operations that use the T reg as carry/borrow are split into
6099 ;; individual SImode operations, the T reg is usually cleared before the
6100 ;; first SImode insn.
6103 [(set (reg:SI T_REG) (const_int 0))]
6106 [(set_attr "type" "mt_group")])
6109 [(set (reg:SI T_REG) (const_int 1))]
6112 [(set_attr "type" "mt_group")])
6114 ;; Use the combine pass to transform sequences such as
6118 ;; mov.l @(r0,r4),r0
6124 ;; See also PR 39423.
6125 ;; Notice that these patterns have a T_REG clobber, because the shift
6126 ;; sequence that will be split out might clobber the T_REG. Ideally, the
6127 ;; clobber would be added conditionally, depending on the result of
6128 ;; sh_ashlsi_clobbers_t_reg_p. When splitting out the shifts we must go
6129 ;; through the ashlsi3 expander in order to get the right shift insn --
6130 ;; a T_REG clobbering or non-clobbering shift sequence or dynamic shift.
6131 ;; FIXME: Combine never tries this kind of patterns for DImode.
6132 (define_insn_and_split "*movsi_index_disp_load"
6133 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6134 (match_operand:SI 1 "mem_index_disp_operand" "m"))
6135 (clobber (reg:SI T_REG))]
6138 "&& can_create_pseudo_p ()"
6139 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6140 (set (match_dup 0) (match_dup 7))]
6142 rtx mem = operands[1];
6143 rtx plus0_rtx = XEXP (mem, 0);
6144 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6145 rtx mult_rtx = XEXP (plus1_rtx, 0);
6147 operands[1] = XEXP (mult_rtx, 0);
6148 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6149 operands[3] = XEXP (plus1_rtx, 1);
6150 operands[4] = XEXP (plus0_rtx, 1);
6151 operands[5] = gen_reg_rtx (SImode);
6152 operands[6] = gen_reg_rtx (SImode);
6154 replace_equiv_address (mem,
6155 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6157 emit_insn (gen_ashlsi3 (operands[5], operands[1], operands[2]));
6160 (define_insn_and_split "*movhi_index_disp_load"
6161 [(set (match_operand:SI 0 "arith_reg_dest")
6162 (SZ_EXTEND:SI (match_operand:HI 1 "mem_index_disp_operand")))
6163 (clobber (reg:SI T_REG))]
6166 "&& can_create_pseudo_p ()"
6169 rtx mem = operands[1];
6170 rtx plus0_rtx = XEXP (mem, 0);
6171 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6172 rtx mult_rtx = XEXP (plus1_rtx, 0);
6174 rtx op_1 = XEXP (mult_rtx, 0);
6175 rtx op_2 = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6176 rtx op_3 = XEXP (plus1_rtx, 1);
6177 rtx op_4 = XEXP (plus0_rtx, 1);
6178 rtx op_5 = gen_reg_rtx (SImode);
6179 rtx op_6 = gen_reg_rtx (SImode);
6180 rtx op_7 = replace_equiv_address (mem, gen_rtx_PLUS (SImode, op_6, op_4));
6182 emit_insn (gen_ashlsi3 (op_5, op_1, op_2));
6183 emit_insn (gen_addsi3 (op_6, op_5, op_3));
6185 if (<CODE> == SIGN_EXTEND)
6187 emit_insn (gen_extendhisi2 (operands[0], op_7));
6190 else if (<CODE> == ZERO_EXTEND)
6192 /* On SH2A the movu.w insn can be used for zero extending loads. */
6194 emit_insn (gen_zero_extendhisi2 (operands[0], op_7));
6197 emit_insn (gen_extendhisi2 (operands[0], op_7));
6198 emit_insn (gen_zero_extendhisi2 (operands[0],
6199 gen_lowpart (HImode, operands[0])));
6207 (define_insn_and_split "*mov<mode>_index_disp_store"
6208 [(set (match_operand:HISI 0 "mem_index_disp_operand" "=m")
6209 (match_operand:HISI 1 "arith_reg_operand" "r"))
6210 (clobber (reg:SI T_REG))]
6213 "&& can_create_pseudo_p ()"
6214 [(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 3)))
6215 (set (match_dup 7) (match_dup 1))]
6217 rtx mem = operands[0];
6218 rtx plus0_rtx = XEXP (mem, 0);
6219 rtx plus1_rtx = XEXP (plus0_rtx, 0);
6220 rtx mult_rtx = XEXP (plus1_rtx, 0);
6222 operands[0] = XEXP (mult_rtx, 0);
6223 operands[2] = GEN_INT (exact_log2 (INTVAL (XEXP (mult_rtx, 1))));
6224 operands[3] = XEXP (plus1_rtx, 1);
6225 operands[4] = XEXP (plus0_rtx, 1);
6226 operands[5] = gen_reg_rtx (SImode);
6227 operands[6] = gen_reg_rtx (SImode);
6229 replace_equiv_address (mem,
6230 gen_rtx_PLUS (SImode, operands[6], operands[4]));
6232 emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
6235 ;; t/r must come after r/r, lest reload will try to reload stuff like
6236 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
6237 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
6238 (define_insn "movsi_i"
6239 [(set (match_operand:SI 0 "general_movdst_operand"
6240 "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
6241 (match_operand:SI 1 "general_movsrc_operand"
6242 "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
6246 && (register_operand (operands[0], SImode)
6247 || register_operand (operands[1], SImode))"
6263 [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
6264 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
6266 ;; t/r must come after r/r, lest reload will try to reload stuff like
6267 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
6268 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
6269 ;; will require a reload.
6270 ;; ??? We can't include f/f because we need the proper FPSCR setting when
6271 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
6272 (define_insn "movsi_ie"
6273 [(set (match_operand:SI 0 "general_movdst_operand"
6274 "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
6275 (match_operand:SI 1 "general_movsrc_operand"
6276 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
6277 "(TARGET_SH2E || TARGET_SH2A)
6278 && (register_operand (operands[0], SImode)
6279 || register_operand (operands[1], SImode))"
6304 ! move optimized away"
6305 [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
6306 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
6307 (set_attr_alternative "length"
6314 (match_test "TARGET_SH2A")
6315 (const_int 4) (const_int 2))
6319 (match_test "TARGET_SH2A")
6320 (const_int 4) (const_int 2))
6337 (define_insn "movsi_i_lowpart"
6338 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
6339 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
6341 && (register_operand (operands[0], SImode)
6342 || register_operand (operands[1], SImode))"
6352 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
6354 (define_insn_and_split "load_ra"
6355 [(set (match_operand:SI 0 "general_movdst_operand" "")
6356 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
6359 "&& ! currently_expanding_to_rtl"
6360 [(set (match_dup 0) (match_dup 1))]
6362 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
6363 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
6366 ;; The '?'s in the following constraints may not reflect the time taken
6367 ;; to perform the move. They are there to discourage the use of floating-
6368 ;; point registers for storing integer values.
6369 (define_insn "*movsi_media"
6370 [(set (match_operand:SI 0 "general_movdst_operand"
6371 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
6372 (match_operand:SI 1 "general_movsrc_operand"
6373 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6375 && (register_operand (operands[0], SImode)
6376 || sh_register_operand (operands[1], SImode)
6377 || GET_CODE (operands[1]) == TRUNCATE)"
6392 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
6393 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
6394 (set (attr "highpart")
6395 (cond [(match_test "sh_contains_memref_p (insn)")
6396 (const_string "user")]
6397 (const_string "ignore")))])
6399 (define_insn "*movsi_media_nofpu"
6400 [(set (match_operand:SI 0 "general_movdst_operand"
6401 "=r,r,r,r,m,*b,r,*b")
6402 (match_operand:SI 1 "general_movsrc_operand"
6403 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
6405 && (register_operand (operands[0], SImode)
6406 || sh_register_operand (operands[1], SImode)
6407 || GET_CODE (operands[1]) == TRUNCATE)"
6417 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
6418 (set_attr "length" "4,4,8,4,4,4,4,12")
6419 (set (attr "highpart")
6420 (cond [(match_test "sh_contains_memref_p (insn)")
6421 (const_string "user")]
6422 (const_string "ignore")))])
6424 (define_expand "movsi_const"
6425 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6426 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6427 (const_int 16)] UNSPEC_EXTRACT_S16)))
6429 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
6430 (const:SI (unspec:SI [(match_dup 1)
6431 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6432 "TARGET_SHMEDIA && reload_completed
6433 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6435 if (GET_CODE (operands[1]) == LABEL_REF
6436 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
6437 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
6438 else if (GOTOFF_P (operands[1]))
6440 rtx unspec = XEXP (operands[1], 0);
6442 if (! UNSPEC_GOTOFF_P (unspec))
6444 unspec = XEXP (unspec, 0);
6445 if (! UNSPEC_GOTOFF_P (unspec))
6448 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
6449 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
6450 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
6454 (define_expand "movsi_const_16bit"
6455 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6456 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
6457 (const_int 0)] UNSPEC_EXTRACT_S16)))]
6458 "TARGET_SHMEDIA && flag_pic && reload_completed
6459 && GET_CODE (operands[1]) == SYMBOL_REF"
6463 [(set (match_operand:SI 0 "arith_reg_dest" "")
6464 (match_operand:SI 1 "immediate_operand" ""))]
6465 "TARGET_SHMEDIA && reload_completed
6466 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6469 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
6471 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6477 [(set (match_operand:SI 0 "register_operand" "")
6478 (match_operand:SI 1 "immediate_operand" ""))]
6479 "TARGET_SHMEDIA && reload_completed
6480 && ((CONST_INT_P (operands[1])
6481 && ! satisfies_constraint_I16 (operands[1]))
6482 || GET_CODE (operands[1]) == CONST_DOUBLE)"
6483 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6485 (define_expand "movsi"
6486 [(set (match_operand:SI 0 "general_movdst_operand" "")
6487 (match_operand:SI 1 "general_movsrc_operand" ""))]
6490 prepare_move_operands (operands, SImode);
6493 (define_expand "ic_invalidate_line"
6494 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
6495 (match_dup 1)] UNSPEC_ICACHE)
6496 (clobber (scratch:SI))])]
6497 "TARGET_HARD_SH4 || TARGET_SH5"
6501 emit_insn (gen_ic_invalidate_line_media (operands[0]));
6504 else if (TARGET_SHCOMPACT)
6506 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
6507 operands[1] = force_reg (Pmode, operands[1]);
6508 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
6511 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
6513 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
6516 operands[0] = force_reg (Pmode, operands[0]);
6517 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
6521 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
6522 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
6523 ;; the requirement *1*00 for associative address writes. The alignment of
6524 ;; %0 implies that its least significant bit is cleared,
6525 ;; thus we clear the V bit of a matching entry if there is one.
6526 (define_insn "ic_invalidate_line_i"
6527 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
6528 (match_operand:SI 1 "register_operand" "r")]
6530 (clobber (match_scratch:SI 2 "=&r"))]
6533 return "ocbwb @%0" "\n"
6534 " extu.w %0,%2" "\n"
6538 [(set_attr "length" "8")
6539 (set_attr "type" "cwb")])
6541 (define_insn "ic_invalidate_line_sh4a"
6542 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6544 "TARGET_SH4A_ARCH || TARGET_SH4_300"
6546 return "ocbwb @%0" "\n"
6550 [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
6551 (set_attr "type" "cwb")])
6553 ;; ??? could make arg 0 an offsettable memory operand to allow to save
6554 ;; an add in the code that calculates the address.
6555 (define_insn "ic_invalidate_line_media"
6556 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
6560 return "ocbwb %0,0" "\n"
6565 [(set_attr "length" "16")
6566 (set_attr "type" "invalidate_line_media")])
6568 (define_insn "ic_invalidate_line_compact"
6569 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6570 (match_operand:SI 1 "register_operand" "r")]
6572 (clobber (reg:SI PR_REG))]
6575 [(set_attr "type" "sfunc")
6576 (set_attr "needs_delay_slot" "yes")])
6578 (define_expand "initialize_trampoline"
6579 [(match_operand:SI 0 "" "")
6580 (match_operand:SI 1 "" "")
6581 (match_operand:SI 2 "" "")]
6586 tramp = force_reg (Pmode, operands[0]);
6587 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
6589 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
6590 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
6592 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
6596 (define_insn "initialize_trampoline_compact"
6597 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
6598 (match_operand:SI 1 "register_operand" "r")
6599 (reg:SI R2_REG) (reg:SI R3_REG)]
6602 (clobber (reg:SI PR_REG))]
6605 [(set_attr "type" "sfunc")
6606 (set_attr "needs_delay_slot" "yes")])
6608 (define_expand "movhi"
6609 [(set (match_operand:HI 0 "general_movdst_operand" "")
6610 (match_operand:HI 1 "general_movsrc_operand" ""))]
6613 prepare_move_operands (operands, HImode);
6616 (define_expand "movqi"
6617 [(set (match_operand:QI 0 "general_operand" "")
6618 (match_operand:QI 1 "general_operand" ""))]
6621 prepare_move_operands (operands, QImode);
6624 ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
6625 ;; selected to copy QImode regs. If one of them happens to be allocated
6626 ;; on the stack, reload will stick to movqi insn and generate wrong
6627 ;; displacement addressing because of the generic m alternatives.
6628 ;; With the movqi_reg_reg being specified before movqi it will be initially
6629 ;; picked to load/store regs. If the regs regs are on the stack reload will
6630 ;; try other insns and not stick to movqi_reg_reg.
6631 ;; The same applies to the movhi variants.
6633 ;; Notice, that T bit is not allowed as a mov src operand here. This is to
6634 ;; avoid things like (set (reg:QI) (subreg:QI (reg:SI T_REG) 0)), which
6635 ;; introduces zero extensions after T bit stores and redundant reg copies.
6637 ;; FIXME: We can't use 'arith_reg_operand' (which disallows T_REG) as a
6638 ;; predicate for the mov src operand because reload will have trouble
6639 ;; reloading MAC subregs otherwise. For that probably special patterns
6640 ;; would be required.
6641 (define_insn "*mov<mode>_reg_reg"
6642 [(set (match_operand:QIHI 0 "arith_reg_dest" "=r")
6643 (match_operand:QIHI 1 "register_operand" "r"))]
6644 "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
6646 [(set_attr "type" "move")])
6648 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
6649 ;; "enabled" attribute as it is done in other targets.
6650 (define_insn "*mov<mode>_store_mem_disp04"
6652 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
6653 (match_operand:SI 1 "const_int_operand" "<disp04>,N")))
6654 (match_operand:QIHI 2 "arith_reg_operand" "z,r"))]
6655 "TARGET_SH1 && sh_legitimate_index_p (<MODE>mode, operands[1], false, true)"
6657 mov.<bw> %2,@(%O1,%0)
6659 [(set_attr "type" "store")])
6661 (define_insn "*mov<mode>_store_mem_disp12"
6663 (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
6664 (match_operand:SI 1 "const_int_operand" "<disp12>")))
6665 (match_operand:QIHI 2 "arith_reg_operand" "r"))]
6666 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[1], true, true)"
6667 "mov.<bw> %2,@(%O1,%0)"
6668 [(set_attr "type" "store")
6669 (set_attr "length" "4")])
6671 (define_insn "*mov<mode>_load_mem_disp04"
6672 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r")
6674 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
6675 (match_operand:SI 2 "const_int_operand" "<disp04>,N"))))]
6676 "TARGET_SH1 && ! TARGET_SH2A
6677 && sh_legitimate_index_p (<MODE>mode, operands[2], false, true)"
6679 mov.<bw> @(%O2,%1),%0
6681 [(set_attr "type" "load")])
6683 (define_insn "*mov<mode>_load_mem_disp12"
6684 [(set (match_operand:QIHI 0 "arith_reg_dest" "=z,r,r")
6687 (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
6688 (match_operand:SI 2 "const_int_operand" "<disp04>,N,<disp12>"))))]
6689 "TARGET_SH2A && sh_legitimate_index_p (<MODE>mode, operands[2], true, true)"
6691 mov.<bw> @(%O2,%1),%0
6693 mov.<bw> @(%O2,%1),%0"
6694 [(set_attr "type" "load")
6695 (set_attr "length" "2,2,4")])
6697 ;; The m constraints basically allow any kind of addresses to be used with any
6698 ;; source/target register as the other operand. This is not true for
6699 ;; displacement addressing modes on anything but SH2A. That's why the
6700 ;; specialized load/store insns are specified above.
6701 (define_insn "*movqi"
6702 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
6703 (match_operand:QI 1 "general_movsrc_operand" "i,m,r,l,r"))]
6705 && (arith_reg_operand (operands[0], QImode)
6706 || arith_reg_operand (operands[1], QImode))"
6713 [(set_attr "type" "movi8,load,store,prget,prset")])
6715 (define_insn "*movhi"
6716 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l")
6717 (match_operand:HI 1 "general_movsrc_operand" "Q,i,m,r,l,r"))]
6719 && (arith_reg_operand (operands[0], HImode)
6720 || arith_reg_operand (operands[1], HImode))"
6728 [(set_attr "type" "pcload,movi8,load,store,prget,prset")])
6730 (define_insn "*movqi_media"
6731 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
6732 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
6734 && (arith_reg_operand (operands[0], QImode)
6735 || extend_reg_or_0_operand (operands[1], QImode))"
6741 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
6742 (set (attr "highpart")
6743 (cond [(match_test "sh_contains_memref_p (insn)")
6744 (const_string "user")]
6745 (const_string "ignore")))])
6747 (define_expand "reload_inqi"
6748 [(set (match_operand:SI 2 "" "=&r")
6749 (match_operand:QI 1 "inqhi_operand" ""))
6750 (set (match_operand:QI 0 "arith_reg_operand" "=r")
6751 (truncate:QI (match_dup 3)))]
6754 rtx inner = XEXP (operands[1], 0);
6755 int regno = REGNO (inner);
6757 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
6758 operands[1] = gen_rtx_REG (SImode, regno);
6759 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
6762 (define_insn "*movhi_media"
6763 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
6764 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
6766 && (arith_reg_operand (operands[0], HImode)
6767 || arith_reg_or_0_operand (operands[1], HImode))"
6774 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
6775 (set (attr "highpart")
6776 (cond [(match_test "sh_contains_memref_p (insn)")
6777 (const_string "user")]
6778 (const_string "ignore")))])
6781 [(set (match_operand:HI 0 "register_operand" "")
6782 (match_operand:HI 1 "immediate_operand" ""))]
6783 "TARGET_SHMEDIA && reload_completed
6784 && ! satisfies_constraint_I16 (operands[1])"
6785 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
6787 (define_expand "reload_inhi"
6788 [(set (match_operand:SI 2 "" "=&r")
6789 (match_operand:HI 1 "inqhi_operand" ""))
6790 (set (match_operand:HI 0 "arith_reg_operand" "=r")
6791 (truncate:HI (match_dup 3)))]
6794 rtx inner = XEXP (operands[1], 0);
6795 int regno = REGNO (inner);
6797 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
6798 operands[1] = gen_rtx_REG (SImode, regno);
6799 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
6802 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
6803 ;; compiled with -m2 -ml -O3 -funroll-loops
6804 (define_insn "*movdi_i"
6805 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
6806 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
6808 && (arith_reg_operand (operands[0], DImode)
6809 || arith_reg_operand (operands[1], DImode))"
6811 return output_movedouble (insn, operands, DImode);
6813 [(set_attr "length" "4")
6814 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
6816 ;; If the output is a register and the input is memory or a register, we have
6817 ;; to be careful and see which word needs to be loaded first.
6820 [(set (match_operand:DI 0 "general_movdst_operand" "")
6821 (match_operand:DI 1 "general_movsrc_operand" ""))]
6822 "TARGET_SH1 && reload_completed"
6823 [(set (match_dup 2) (match_dup 3))
6824 (set (match_dup 4) (match_dup 5))]
6828 if ((MEM_P (operands[0])
6829 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6830 || (MEM_P (operands[1])
6831 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6834 switch (GET_CODE (operands[0]))
6837 regno = REGNO (operands[0]);
6840 regno = subreg_regno (operands[0]);
6850 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6852 operands[2] = operand_subword (operands[0], 0, 0, DImode);
6853 operands[3] = operand_subword (operands[1], 0, 0, DImode);
6854 operands[4] = operand_subword (operands[0], 1, 0, DImode);
6855 operands[5] = operand_subword (operands[1], 1, 0, DImode);
6859 operands[2] = operand_subword (operands[0], 1, 0, DImode);
6860 operands[3] = operand_subword (operands[1], 1, 0, DImode);
6861 operands[4] = operand_subword (operands[0], 0, 0, DImode);
6862 operands[5] = operand_subword (operands[1], 0, 0, DImode);
6865 if (operands[2] == 0 || operands[3] == 0
6866 || operands[4] == 0 || operands[5] == 0)
6870 ;; The '?'s in the following constraints may not reflect the time taken
6871 ;; to perform the move. They are there to discourage the use of floating-
6872 ;; point registers for storing integer values.
6873 (define_insn "*movdi_media"
6874 [(set (match_operand:DI 0 "general_movdst_operand"
6875 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
6876 (match_operand:DI 1 "general_movsrc_operand"
6877 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
6879 && (register_operand (operands[0], DImode)
6880 || sh_register_operand (operands[1], DImode))"
6895 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
6896 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
6898 (define_insn "*movdi_media_nofpu"
6899 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
6900 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
6902 && (register_operand (operands[0], DImode)
6903 || sh_register_operand (operands[1], DImode))"
6913 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
6914 (set_attr "length" "4,4,16,4,4,4,4,*")])
6916 (define_insn "*movdi_media_I16"
6917 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
6918 (match_operand:DI 1 "const_int_operand" "I16"))]
6919 "TARGET_SHMEDIA && reload_completed"
6921 [(set_attr "type" "arith_media")
6922 (set_attr "length" "4")])
6925 [(set (match_operand:DI 0 "arith_reg_dest" "")
6926 (match_operand:DI 1 "immediate_operand" ""))]
6927 "TARGET_SHMEDIA && reload_completed
6928 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6929 [(set (match_dup 0) (match_dup 1))]
6933 if (TARGET_SHMEDIA64)
6934 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
6936 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
6938 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
6943 (define_expand "movdi_const"
6944 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6945 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
6946 (const_int 48)] UNSPEC_EXTRACT_S16)))
6948 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
6949 (const:DI (unspec:DI [(match_dup 1)
6950 (const_int 32)] UNSPEC_EXTRACT_U16))))
6952 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
6953 (const:DI (unspec:DI [(match_dup 1)
6954 (const_int 16)] UNSPEC_EXTRACT_U16))))
6956 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
6957 (const:DI (unspec:DI [(match_dup 1)
6958 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6959 "TARGET_SHMEDIA64 && reload_completed
6960 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6962 sh_mark_label (operands[1], 4);
6965 (define_expand "movdi_const_32bit"
6966 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6967 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
6968 (const_int 16)] UNSPEC_EXTRACT_S16)))
6970 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
6971 (const:DI (unspec:DI [(match_dup 1)
6972 (const_int 0)] UNSPEC_EXTRACT_U16))))]
6973 "TARGET_SHMEDIA32 && reload_completed
6974 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
6976 sh_mark_label (operands[1], 2);
6979 (define_expand "movdi_const_16bit"
6980 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6981 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
6982 (const_int 0)] UNSPEC_EXTRACT_S16)))]
6983 "TARGET_SHMEDIA && flag_pic && reload_completed
6984 && GET_CODE (operands[1]) == SYMBOL_REF"
6988 [(set (match_operand:DI 0 "ext_dest_operand" "")
6989 (match_operand:DI 1 "immediate_operand" ""))]
6990 "TARGET_SHMEDIA && reload_completed
6991 && CONST_INT_P (operands[1])
6992 && ! satisfies_constraint_I16 (operands[1])"
6993 [(set (match_dup 0) (match_dup 2))
6996 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
6997 unsigned HOST_WIDE_INT low = val;
6998 unsigned HOST_WIDE_INT high = val;
6999 unsigned HOST_WIDE_INT sign;
7000 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
7002 /* Zero-extend the 16 least-significant bits. */
7005 /* Arithmetic shift right the word by 16 bits. */
7007 if (GET_CODE (operands[0]) == SUBREG
7008 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
7017 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7023 /* If we can't generate the constant with a two-insn movi / shori
7024 sequence, try some other strategies. */
7025 if (! CONST_OK_FOR_I16 (high))
7027 /* Try constant load / left shift. We know VAL != 0. */
7028 val2 = val ^ (val-1);
7031 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
7033 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
7034 || (! CONST_OK_FOR_I16 (high >> 16)
7035 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
7037 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
7038 operands[1] = gen_ashldi3_media (operands[0], operands[0],
7039 GEN_INT (trailing_zeroes));
7043 /* Try constant load / right shift. */
7044 val2 = (val >> 15) + 1;
7045 if (val2 == (val2 & -val2))
7047 int shift = 49 - exact_log2 (val2);
7049 val2 = trunc_int_for_mode (val << shift, DImode);
7050 if (CONST_OK_FOR_I16 (val2))
7052 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
7058 val2 = val & 0xffff;
7059 if ((val >> 16 & 0xffff) == val2
7060 && (val >> 32 & 0xffff) == val2
7061 && (val >> 48 & 0xffff) == val2)
7063 val2 = (HOST_WIDE_INT) val >> 48;
7064 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
7065 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
7068 /* Try movi / mshflo.l */
7069 val2 = (HOST_WIDE_INT) val >> 32;
7070 if (val2 == ((unsigned HOST_WIDE_INT)
7071 trunc_int_for_mode (val, SImode)))
7073 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7077 /* Try movi / mshflo.l w/ r63. */
7078 val2 = val + ((HOST_WIDE_INT) -1 << 32);
7079 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
7081 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
7087 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
7090 operands[2] = GEN_INT (val2);
7094 [(set (match_operand:DI 0 "ext_dest_operand" "")
7095 (match_operand:DI 1 "immediate_operand" ""))]
7096 "TARGET_SHMEDIA && reload_completed
7097 && GET_CODE (operands[1]) == CONST_DOUBLE"
7098 [(set (match_dup 0) (match_dup 2))
7100 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
7102 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
7103 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
7104 unsigned HOST_WIDE_INT val = low;
7105 unsigned HOST_WIDE_INT sign;
7107 /* Zero-extend the 16 least-significant bits. */
7109 operands[1] = GEN_INT (val);
7111 /* Arithmetic shift right the double-word by 16 bits. */
7113 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
7116 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
7120 /* This will only be true if high is a sign-extension of low, i.e.,
7121 it must be either 0 or (unsigned)-1, and be zero iff the
7122 most-significant bit of low is set. */
7123 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
7124 operands[2] = GEN_INT (low);
7126 operands[2] = immed_double_const (low, high, DImode);
7129 (define_insn "shori_media"
7130 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
7131 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
7133 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
7134 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
7138 [(set_attr "type" "arith_media,*")])
7140 (define_insn "*shori_media_si"
7141 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
7142 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
7144 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
7148 (define_expand "movdi"
7149 [(set (match_operand:DI 0 "general_movdst_operand" "")
7150 (match_operand:DI 1 "general_movsrc_operand" ""))]
7153 prepare_move_operands (operands, DImode);
7156 (define_insn "movdf_media"
7157 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7158 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7160 && (register_operand (operands[0], DFmode)
7161 || sh_register_operand (operands[1], DFmode))"
7172 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
7174 (define_insn "movdf_media_nofpu"
7175 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7176 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7178 && (register_operand (operands[0], DFmode)
7179 || sh_register_operand (operands[1], DFmode))"
7185 [(set_attr "type" "arith_media,*,load_media,store_media")])
7188 [(set (match_operand:DF 0 "arith_reg_dest" "")
7189 (match_operand:DF 1 "immediate_operand" ""))]
7190 "TARGET_SHMEDIA && reload_completed"
7191 [(set (match_dup 3) (match_dup 2))]
7193 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
7195 REAL_VALUE_TYPE value;
7197 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7198 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
7200 if (HOST_BITS_PER_WIDE_INT >= 64)
7201 operands[2] = immed_double_const ((unsigned long) values[endian]
7202 | ((HOST_WIDE_INT) values[1 - endian]
7206 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
7207 operands[2] = immed_double_const (values[endian], values[1 - endian],
7211 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7214 ;; ??? This should be a define expand.
7216 (define_insn "movdf_k"
7217 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
7218 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
7220 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
7221 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
7222 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7223 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7224 && (arith_reg_operand (operands[0], DFmode)
7225 || arith_reg_operand (operands[1], DFmode))"
7227 return output_movedouble (insn, operands, DFmode);
7229 [(set_attr "length" "4")
7230 (set_attr "type" "move,pcload,load,store")])
7232 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
7233 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
7234 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
7235 ;; the d/m/c/X alternative, which is split later into single-precision
7236 ;; instructions. And when not optimizing, no splits are done before fixing
7237 ;; up pcloads, so we need usable length information for that.
7238 (define_insn "movdf_i4"
7239 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
7240 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
7241 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
7242 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
7243 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7244 && (arith_reg_operand (operands[0], DFmode)
7245 || arith_reg_operand (operands[1], DFmode))"
7247 switch (which_alternative)
7251 return "fmov %1,%0";
7252 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
7253 return "fmov %R1,%R0" "\n"
7256 return "fmov %S1,%S0" "\n"
7260 return "fmov.d %1,%0";
7265 [(set_attr_alternative "length"
7266 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
7268 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7269 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7270 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
7272 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
7273 ;; We can't use 4-byte push/pop on SHcompact, so we have to
7274 ;; increment or decrement r15 explicitly.
7276 (match_test "TARGET_SHCOMPACT")
7277 (const_int 10) (const_int 8))
7279 (match_test "TARGET_SHCOMPACT")
7280 (const_int 10) (const_int 8))])
7281 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
7282 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
7283 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7284 (const_string "double")
7285 (const_string "none")))])
7287 ;; Moving DFmode between fp/general registers through memory
7288 ;; (the top of the stack) is faster than moving through fpul even for
7289 ;; little endian. Because the type of an instruction is important for its
7290 ;; scheduling, it is beneficial to split these operations, rather than
7291 ;; emitting them in one single chunk, even if this will expose a stack
7292 ;; use that will prevent scheduling of other stack accesses beyond this
7295 [(set (match_operand:DF 0 "register_operand" "")
7296 (match_operand:DF 1 "register_operand" ""))
7297 (use (match_operand:PSI 2 "fpscr_operand" ""))
7298 (clobber (match_scratch:SI 3 "=X"))]
7299 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
7300 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
7305 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
7307 emit_move_insn (stack_pointer_rtx,
7308 plus_constant (Pmode, stack_pointer_rtx, -8));
7309 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7312 tos = gen_tmp_stack_mem (DFmode,
7313 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
7314 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
7315 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
7316 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7317 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7318 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
7320 tos = gen_tmp_stack_mem (DFmode,
7321 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
7322 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
7323 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
7324 emit_move_insn (stack_pointer_rtx,
7325 plus_constant (Pmode, stack_pointer_rtx, 8));
7327 add_reg_note (insn, REG_INC, stack_pointer_rtx);
7331 ;; local-alloc sometimes allocates scratch registers even when not required,
7332 ;; so we must be prepared to handle these.
7334 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
7336 [(set (match_operand:DF 0 "general_movdst_operand" "")
7337 (match_operand:DF 1 "general_movsrc_operand" ""))
7338 (use (match_operand:PSI 2 "fpscr_operand" ""))
7339 (clobber (match_scratch:SI 3 ""))]
7340 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
7342 && true_regnum (operands[0]) < 16
7343 && true_regnum (operands[1]) < 16"
7344 [(set (match_dup 0) (match_dup 1))]
7346 /* If this was a reg <-> mem operation with base + index reg addressing,
7347 we have to handle this in a special way. */
7348 rtx mem = operands[0];
7350 if (! memory_operand (mem, DFmode))
7355 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
7356 mem = SUBREG_REG (mem);
7359 rtx addr = XEXP (mem, 0);
7360 if (GET_CODE (addr) == PLUS
7361 && REG_P (XEXP (addr, 0))
7362 && REG_P (XEXP (addr, 1)))
7365 rtx reg0 = gen_rtx_REG (Pmode, 0);
7366 rtx regop = operands[store_p], word0 ,word1;
7368 if (GET_CODE (regop) == SUBREG)
7369 alter_subreg (®op);
7370 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
7374 mem = copy_rtx (mem);
7375 PUT_MODE (mem, SImode);
7376 word0 = gen_rtx_SUBREG (SImode, regop, 0);
7377 alter_subreg (&word0);
7378 word1 = gen_rtx_SUBREG (SImode, regop, 4);
7379 alter_subreg (&word1);
7380 if (store_p || ! refers_to_regno_p (REGNO (word0),
7381 REGNO (word0) + 1, addr, 0))
7384 ? gen_movsi_ie (mem, word0)
7385 : gen_movsi_ie (word0, mem));
7386 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7387 mem = copy_rtx (mem);
7389 ? gen_movsi_ie (mem, word1)
7390 : gen_movsi_ie (word1, mem));
7391 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7395 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
7396 emit_insn (gen_movsi_ie (word1, mem));
7397 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
7398 mem = copy_rtx (mem);
7399 emit_insn (gen_movsi_ie (word0, mem));
7406 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
7408 [(set (match_operand:DF 0 "register_operand" "")
7409 (match_operand:DF 1 "memory_operand" ""))
7410 (use (match_operand:PSI 2 "fpscr_operand" ""))
7411 (clobber (reg:SI R0_REG))]
7412 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
7413 [(parallel [(set (match_dup 0) (match_dup 1))
7415 (clobber (scratch:SI))])]
7418 (define_expand "reload_indf__frn"
7419 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
7420 (match_operand:DF 1 "immediate_operand" "FQ"))
7421 (use (reg:PSI FPSCR_REG))
7422 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7426 (define_expand "reload_outdf__RnFRm"
7427 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
7428 (match_operand:DF 1 "register_operand" "af,r"))
7429 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
7433 ;; Simplify no-op moves.
7435 [(set (match_operand:SF 0 "register_operand" "")
7436 (match_operand:SF 1 "register_operand" ""))
7437 (use (match_operand:PSI 2 "fpscr_operand" ""))
7438 (clobber (match_scratch:SI 3 ""))]
7439 "TARGET_SH2E && reload_completed
7440 && true_regnum (operands[0]) == true_regnum (operands[1])"
7441 [(set (match_dup 0) (match_dup 0))]
7444 ;; fmovd substitute post-reload splits
7446 [(set (match_operand:DF 0 "register_operand" "")
7447 (match_operand:DF 1 "register_operand" ""))
7448 (use (match_operand:PSI 2 "fpscr_operand" ""))
7449 (clobber (match_scratch:SI 3 ""))]
7450 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
7451 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7452 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7455 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
7456 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
7457 gen_rtx_REG (SFmode, src), operands[2]));
7458 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
7459 gen_rtx_REG (SFmode, src + 1), operands[2]));
7464 [(set (match_operand:DF 0 "register_operand" "")
7465 (mem:DF (match_operand:SI 1 "register_operand" "")))
7466 (use (match_operand:PSI 2 "fpscr_operand" ""))
7467 (clobber (match_scratch:SI 3 ""))]
7468 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7469 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
7470 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
7473 int regno = true_regnum (operands[0]);
7475 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
7477 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
7478 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7479 regno + !! TARGET_LITTLE_ENDIAN),
7480 mem2, operands[2]));
7481 add_reg_note (insn, REG_INC, operands[1]);
7482 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
7483 regno + ! TARGET_LITTLE_ENDIAN),
7484 change_address (mem, SFmode, NULL_RTX),
7490 [(set (match_operand:DF 0 "register_operand" "")
7491 (match_operand:DF 1 "memory_operand" ""))
7492 (use (match_operand:PSI 2 "fpscr_operand" ""))
7493 (clobber (match_scratch:SI 3 ""))]
7494 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7495 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
7498 int regno = true_regnum (operands[0]);
7500 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
7501 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7502 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7504 operands[1] = copy_rtx (mem2);
7505 addr = XEXP (mem2, 0);
7507 switch (GET_CODE (addr))
7510 /* This is complicated. If the register is an arithmetic register
7511 we can just fall through to the REG+DISP case below. Otherwise
7512 we have to use a combination of POST_INC and REG addressing... */
7513 if (! arith_reg_operand (operands[1], SFmode))
7515 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
7516 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
7517 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7519 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7521 /* If we have modified the stack pointer, the value that we have
7522 read with post-increment might be modified by an interrupt,
7523 so write it back. */
7524 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
7525 emit_insn (gen_push_e (reg0));
7527 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
7533 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7534 operands[1] = copy_rtx (operands[1]);
7535 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
7536 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7540 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
7541 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7543 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
7544 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7556 [(set (match_operand:DF 0 "memory_operand" "")
7557 (match_operand:DF 1 "register_operand" ""))
7558 (use (match_operand:PSI 2 "fpscr_operand" ""))
7559 (clobber (match_scratch:SI 3 ""))]
7560 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
7561 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
7564 int regno = true_regnum (operands[1]);
7566 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
7567 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
7569 operands[0] = copy_rtx (operands[0]);
7570 PUT_MODE (operands[0], SFmode);
7571 addr = XEXP (operands[0], 0);
7573 switch (GET_CODE (addr))
7576 /* This is complicated. If the register is an arithmetic register
7577 we can just fall through to the REG+DISP case below. Otherwise
7578 we have to use a combination of REG and PRE_DEC addressing... */
7579 if (! arith_reg_operand (operands[0], SFmode))
7581 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
7582 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7584 operands[0] = copy_rtx (operands[0]);
7585 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
7587 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7588 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7594 /* Since REG+DISP addressing has already been decided upon by gcc
7595 we can rely upon it having chosen an arithmetic register as the
7596 register component of the address. Just emit the lower numbered
7597 register first, to the lower address, then the higher numbered
7598 register to the higher address. */
7599 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7601 operands[0] = copy_rtx (operands[0]);
7602 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
7604 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7608 /* This is easy. Output the word to go to the higher address
7609 first (ie the word in the higher numbered register) then the
7610 word to go to the lower address. */
7612 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
7613 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7615 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
7616 add_reg_note (insn, REG_INC, XEXP (addr, 0));
7628 ;; If the output is a register and the input is memory or a register, we have
7629 ;; to be careful and see which word needs to be loaded first.
7632 [(set (match_operand:DF 0 "general_movdst_operand" "")
7633 (match_operand:DF 1 "general_movsrc_operand" ""))]
7634 "TARGET_SH1 && reload_completed"
7635 [(set (match_dup 2) (match_dup 3))
7636 (set (match_dup 4) (match_dup 5))]
7640 if ((MEM_P (operands[0])
7641 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
7642 || (MEM_P (operands[1])
7643 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
7646 switch (GET_CODE (operands[0]))
7649 regno = REGNO (operands[0]);
7652 regno = subreg_regno (operands[0]);
7662 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
7664 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
7665 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
7666 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
7667 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
7671 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
7672 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
7673 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
7674 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
7677 if (operands[2] == 0 || operands[3] == 0
7678 || operands[4] == 0 || operands[5] == 0)
7682 (define_expand "movdf"
7683 [(set (match_operand:DF 0 "general_movdst_operand" "")
7684 (match_operand:DF 1 "general_movsrc_operand" ""))]
7687 prepare_move_operands (operands, DFmode);
7690 if (TARGET_SHMEDIA_FPU)
7691 emit_insn (gen_movdf_media (operands[0], operands[1]));
7693 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
7696 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
7698 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7703 ;;This is incompatible with the way gcc uses subregs.
7704 ;;(define_insn "movv2sf_i"
7705 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
7706 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
7707 ;; "TARGET_SHMEDIA_FPU
7708 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
7709 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
7713 ;; fst%M0.p %m0, %1"
7714 ;; [(set_attr "type" "*,fload_media,fstore_media")])
7716 (define_insn_and_split "movv2sf_i"
7717 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7718 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7719 "TARGET_SHMEDIA_FPU"
7721 "TARGET_SHMEDIA_FPU && reload_completed"
7722 [(set (match_dup 0) (match_dup 1))]
7724 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
7725 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
7728 (define_expand "movv2sf"
7729 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
7730 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
7731 "TARGET_SHMEDIA_FPU"
7733 prepare_move_operands (operands, V2SFmode);
7736 (define_expand "addv2sf3"
7737 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7738 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7739 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7740 "TARGET_SHMEDIA_FPU"
7742 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
7746 (define_expand "subv2sf3"
7747 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7748 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7749 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7750 "TARGET_SHMEDIA_FPU"
7752 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
7756 (define_expand "mulv2sf3"
7757 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7758 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7759 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7760 "TARGET_SHMEDIA_FPU"
7762 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
7766 (define_expand "divv2sf3"
7767 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
7768 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
7769 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
7770 "TARGET_SHMEDIA_FPU"
7772 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
7776 (define_insn_and_split "*movv4sf_i"
7777 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
7778 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
7779 "TARGET_SHMEDIA_FPU"
7781 "&& reload_completed"
7786 for (i = 0; i < 4/2; i++)
7790 if (MEM_P (operands[0]))
7791 x = adjust_address (operands[0], V2SFmode,
7792 i * GET_MODE_SIZE (V2SFmode));
7794 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
7796 if (MEM_P (operands[1]))
7797 y = adjust_address (operands[1], V2SFmode,
7798 i * GET_MODE_SIZE (V2SFmode));
7800 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
7802 emit_insn (gen_movv2sf_i (x, y));
7807 [(set_attr "length" "8")])
7809 (define_expand "movv4sf"
7810 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
7811 (match_operand:V4SF 1 "general_operand" ""))]
7812 "TARGET_SHMEDIA_FPU"
7814 prepare_move_operands (operands, V4SFmode);
7817 (define_insn_and_split "*movv16sf_i"
7818 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
7819 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
7820 "TARGET_SHMEDIA_FPU"
7822 "&& reload_completed"
7827 for (i = 0; i < 16/2; i++)
7831 if (MEM_P (operands[0]))
7832 x = adjust_address (operands[0], V2SFmode,
7833 i * GET_MODE_SIZE (V2SFmode));
7836 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
7840 if (MEM_P (operands[1]))
7841 y = adjust_address (operands[1], V2SFmode,
7842 i * GET_MODE_SIZE (V2SFmode));
7845 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
7849 emit_insn (gen_movv2sf_i (x, y));
7854 [(set_attr "length" "32")])
7856 (define_expand "movv16sf"
7857 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
7858 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
7859 "TARGET_SHMEDIA_FPU"
7861 prepare_move_operands (operands, V16SFmode);
7864 (define_insn "movsf_media"
7865 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
7866 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
7868 && (register_operand (operands[0], SFmode)
7869 || sh_register_operand (operands[1], SFmode))"
7880 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
7881 (set (attr "highpart")
7882 (cond [(match_test "sh_contains_memref_p (insn)")
7883 (const_string "user")]
7884 (const_string "ignore")))])
7886 (define_insn "movsf_media_nofpu"
7887 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
7888 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
7890 && (register_operand (operands[0], SFmode)
7891 || sh_register_operand (operands[1], SFmode))"
7897 [(set_attr "type" "arith_media,*,load_media,store_media")
7898 (set (attr "highpart")
7899 (cond [(match_test "sh_contains_memref_p (insn)")
7900 (const_string "user")]
7901 (const_string "ignore")))])
7904 [(set (match_operand:SF 0 "arith_reg_dest" "")
7905 (match_operand:SF 1 "immediate_operand" ""))]
7906 "TARGET_SHMEDIA && reload_completed
7907 && ! FP_REGISTER_P (true_regnum (operands[0]))"
7908 [(set (match_dup 3) (match_dup 2))]
7911 REAL_VALUE_TYPE value;
7913 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
7914 REAL_VALUE_TO_TARGET_SINGLE (value, values);
7915 operands[2] = GEN_INT (values);
7917 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
7920 (define_insn "movsf_i"
7921 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
7922 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
7925 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
7926 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
7927 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
7928 && (arith_reg_operand (operands[0], SFmode)
7929 || arith_reg_operand (operands[1], SFmode))"
7938 [(set_attr "type" "move,move,pcload,load,store,move,move")])
7940 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
7941 ;; update_flow_info would not know where to put REG_EQUAL notes
7942 ;; when the destination changes mode.
7943 (define_insn "movsf_ie"
7944 [(set (match_operand:SF 0 "general_movdst_operand"
7945 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
7946 (match_operand:SF 1 "general_movsrc_operand"
7947 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
7948 (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"))
7949 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
7951 && (arith_reg_operand (operands[0], SFmode)
7952 || arith_reg_operand (operands[1], SFmode)
7953 || arith_reg_operand (operands[3], SImode)
7954 || (fpul_operand (operands[0], SFmode)
7955 && memory_operand (operands[1], SFmode)
7956 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
7957 || (fpul_operand (operands[1], SFmode)
7958 && memory_operand (operands[0], SFmode)
7959 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
7979 ! move optimized away"
7980 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
7981 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
7982 (set_attr_alternative "length"
7989 (match_test "TARGET_SH2A")
7990 (const_int 4) (const_int 2))
7992 (match_test "TARGET_SH2A")
7993 (const_int 4) (const_int 2))
7996 (match_test "TARGET_SH2A")
7997 (const_int 4) (const_int 2))
7999 (match_test "TARGET_SH2A")
8000 (const_int 4) (const_int 2))
8010 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
8011 (const_string "single")
8012 (const_string "single")))])
8015 [(set (match_operand:SF 0 "register_operand" "")
8016 (match_operand:SF 1 "register_operand" ""))
8017 (use (match_operand:PSI 2 "fpscr_operand" ""))
8018 (clobber (reg:SI FPUL_REG))]
8020 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
8022 (clobber (scratch:SI))])
8023 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
8025 (clobber (scratch:SI))])]
8028 (define_expand "movsf"
8029 [(set (match_operand:SF 0 "general_movdst_operand" "")
8030 (match_operand:SF 1 "general_movsrc_operand" ""))]
8033 prepare_move_operands (operands, SFmode);
8036 if (TARGET_SHMEDIA_FPU)
8037 emit_insn (gen_movsf_media (operands[0], operands[1]));
8039 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
8044 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
8049 (define_insn "mov_nop"
8050 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
8053 [(set_attr "length" "0")
8054 (set_attr "type" "nil")])
8056 (define_expand "reload_insf__frn"
8057 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
8058 (match_operand:SF 1 "immediate_operand" "FQ"))
8059 (use (reg:PSI FPSCR_REG))
8060 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8064 (define_expand "reload_insi__i_fpul"
8065 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
8066 (match_operand:SI 1 "immediate_operand" "i"))
8067 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
8071 (define_expand "ptabs"
8072 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
8075 if (!TARGET_PT_FIXED)
8077 rtx eq = operands[1];
8079 /* ??? For canonical RTL we really should remove any CONST from EQ
8080 before wrapping it in the AND, and finally wrap the EQ into a
8081 const if is constant. However, for reload we must expose the
8082 input register or symbolic constant, and we can't have
8083 different insn structures outside of the operands for different
8084 alternatives of the same pattern. */
8085 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
8088 = (gen_rtx_IF_THEN_ELSE
8091 gen_rtx_MEM (PDImode, operands[1]),
8092 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
8093 PDImode, operands[1])));
8097 ;; expanded by ptabs expander.
8098 (define_insn "*extendsipdi_media"
8099 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8100 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
8104 (mem:PDI (match_dup 1))
8105 (sign_extend:PDI (match_dup 1))))]
8106 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8110 [(set_attr "type" "ptabs_media,pt_media")
8111 (set_attr "length" "4,*")])
8113 (define_insn "*truncdipdi_media"
8114 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
8115 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
8119 (mem:PDI (match_dup 1))
8120 (truncate:PDI (match_dup 1))))]
8121 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
8125 [(set_attr "type" "ptabs_media,pt_media")
8126 (set_attr "length" "4,*")])
8128 (define_insn "*movsi_y"
8129 [(set (match_operand:SI 0 "register_operand" "=y,y")
8130 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
8131 (clobber (match_scratch:SI 2 "=&z,r"))]
8133 && (reload_in_progress || reload_completed)"
8135 [(set_attr "length" "4")
8136 (set_attr "type" "pcload,move")])
8139 [(set (match_operand:SI 0 "register_operand" "")
8140 (match_operand:SI 1 "immediate_operand" ""))
8141 (clobber (match_operand:SI 2 "register_operand" ""))]
8143 [(set (match_dup 2) (match_dup 1))
8144 (set (match_dup 0) (match_dup 2))]
8147 ;; ------------------------------------------------------------------------
8148 ;; Define the real conditional branch instructions.
8149 ;; ------------------------------------------------------------------------
8151 (define_expand "branch_true"
8152 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
8153 (label_ref (match_operand 0))
8157 (define_expand "branch_false"
8158 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8159 (label_ref (match_operand 0))
8163 (define_insn_and_split "*cbranch_t"
8164 [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
8165 (label_ref (match_operand 0))
8169 return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
8171 "&& can_create_pseudo_p ()"
8172 [(set (pc) (if_then_else (eq (reg:SI T_REG) (match_dup 2))
8173 (label_ref (match_dup 0))
8176 /* Try to find missed test and branch combine opportunities which result
8177 in redundant T bit tests before conditional branches.
8178 FIXME: Probably this would not be needed if CCmode was used
8179 together with TARGET_FIXED_CONDITION_CODE_REGS. */
8181 const int treg_value = sh_eval_treg_value (operands[1]);
8182 operands[2] = NULL_RTX;
8184 /* Scan the insns backwards for an insn that sets the T bit by testing a
8185 reg against zero like:
8186 (set (reg T_REG) (eq (reg) (const_int 0))) */
8187 rtx testing_insn = NULL_RTX;
8188 rtx tested_reg = NULL_RTX;
8190 set_of_reg s0 = sh_find_set_of_reg (get_t_reg_rtx (), curr_insn,
8191 prev_nonnote_insn_bb);
8192 if (s0.set_src != NULL_RTX
8193 && GET_CODE (s0.set_src) == EQ
8194 && REG_P (XEXP (s0.set_src, 0))
8195 && satisfies_constraint_Z (XEXP (s0.set_src, 1)))
8197 testing_insn = s0.insn;
8198 tested_reg = XEXP (s0.set_src, 0);
8203 /* Continue scanning the insns backwards and try to find the insn that
8204 sets the tested reg which we found above. If the reg is set by storing
8205 the T bit or the negated T bit we can eliminate the test insn before
8206 the branch. Notice that the branch condition has to be inverted if the
8207 test is eliminated. */
8209 /* If the T bit is used between the testing insn and the brach insn
8211 if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
8216 set_of_reg s1 = sh_find_set_of_reg (tested_reg, s0.insn,
8217 prev_nonnote_insn_bb);
8218 if (s1.set_src == NULL_RTX)
8221 if (t_reg_operand (s1.set_src, VOIDmode))
8222 operands[2] = GEN_INT (treg_value ^ 1);
8223 else if (negt_reg_operand (s1.set_src, VOIDmode))
8224 operands[2] = GEN_INT (treg_value);
8225 else if (REG_P (s1.set_src))
8227 /* If it's a reg-reg copy follow the copied reg. This can
8228 happen e.g. when T bit store zero-extensions are
8230 tested_reg = s1.set_src;
8235 /* It's only safe to remove the testing insn if the T bit is not
8236 modified between the testing insn and the insn that stores the
8237 T bit. Notice that some T bit stores such as negc also modify
8239 if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
8240 || modified_in_p (get_t_reg_rtx (), s1.insn))
8241 operands[2] = NULL_RTX;
8246 if (operands[2] == NULL_RTX)
8249 set_insn_deleted (testing_insn);
8251 [(set_attr "type" "cbranch")])
8253 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
8254 ;; which destination is too far away.
8255 ;; The const_int_operand is distinct for each branch target; it avoids
8256 ;; unwanted matches with redundant_insn.
8257 (define_insn "block_branch_redirect"
8258 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
8261 [(set_attr "length" "0")])
8263 ;; This one has the additional purpose to record a possible scratch register
8264 ;; for the following branch.
8265 ;; ??? Unfortunately, just setting the scratch register is not good enough,
8266 ;; because the insn then might be deemed dead and deleted. And we can't
8267 ;; make the use in the jump insn explicit because that would disable
8268 ;; delay slot scheduling from the target.
8269 (define_insn "indirect_jump_scratch"
8270 [(set (match_operand:SI 0 "register_operand" "=r")
8271 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
8272 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
8275 [(set_attr "length" "0")])
8277 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
8278 ;; being pulled into the delay slot of a condbranch that has been made to
8279 ;; jump around the unconditional jump because it was out of range.
8280 (define_insn "stuff_delay_slot"
8282 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
8283 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
8286 [(set_attr "length" "0")
8287 (set_attr "cond_delay_slot" "yes")])
8289 ;; Conditional branch insns
8291 (define_expand "cbranchint4_media"
8293 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
8294 [(match_operand 1 "" "")
8295 (match_operand 2 "" "")])
8296 (match_operand 3 "" "")
8300 enum machine_mode mode = GET_MODE (operands[1]);
8301 if (mode == VOIDmode)
8302 mode = GET_MODE (operands[2]);
8303 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
8305 operands[1] = force_reg (mode, operands[1]);
8306 if (CONSTANT_P (operands[2])
8307 && (! satisfies_constraint_I06 (operands[2])))
8308 operands[2] = force_reg (mode, operands[2]);
8312 if (operands[1] != const0_rtx)
8313 operands[1] = force_reg (mode, operands[1]);
8314 if (operands[2] != const0_rtx)
8315 operands[2] = force_reg (mode, operands[2]);
8317 switch (GET_CODE (operands[0]))
8323 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
8324 VOIDmode, operands[2], operands[1]);
8325 operands[1] = XEXP (operands[0], 0);
8326 operands[2] = XEXP (operands[0], 1);
8329 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
8330 VOIDmode, operands[1], operands[2]);
8333 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8336 (define_expand "cbranchfp4_media"
8338 (if_then_else (match_operator 0 "sh_float_comparison_operator"
8339 [(match_operand 1 "" "")
8340 (match_operand 2 "" "")])
8341 (match_operand 3 "" "")
8345 rtx tmp = gen_reg_rtx (SImode);
8347 if (GET_CODE (operands[0]) == NE)
8348 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
8350 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
8351 operands[1], operands[2]);
8353 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
8355 if (GET_CODE (cmp) == GET_CODE (operands[0]))
8356 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
8358 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8360 operands[2] = const0_rtx;
8361 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
8364 (define_insn "*beq_media_i"
8366 (if_then_else (match_operator 3 "equality_comparison_operator"
8367 [(match_operand:DI 1 "arith_reg_operand" "r,r")
8368 (match_operand:DI 2 "arith_operand" "r,I06")])
8369 (match_operand 0 "target_operand" "b,b")
8374 b%o3i%' %1, %2, %0%>"
8375 [(set_attr "type" "cbranch_media")])
8377 (define_insn "*beq_media_i32"
8379 (if_then_else (match_operator 3 "equality_comparison_operator"
8380 [(match_operand:SI 1 "arith_reg_operand" "r,r")
8381 (match_operand:SI 2 "arith_operand" "r,I06")])
8382 (match_operand 0 "target_operand" "b,b")
8387 b%o3i%' %1, %2, %0%>"
8388 [(set_attr "type" "cbranch_media")])
8390 (define_insn "*bgt_media_i"
8392 (if_then_else (match_operator 3 "greater_comparison_operator"
8393 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8394 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8395 (match_operand 0 "target_operand" "b")
8398 "b%o3%' %N1, %N2, %0%>"
8399 [(set_attr "type" "cbranch_media")])
8401 (define_insn "*bgt_media_i32"
8403 (if_then_else (match_operator 3 "greater_comparison_operator"
8404 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8405 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8406 (match_operand 0 "target_operand" "b")
8409 "b%o3%' %N1, %N2, %0%>"
8410 [(set_attr "type" "cbranch_media")])
8412 ;; These are only needed to make invert_jump() happy - otherwise, jump
8413 ;; optimization will be silently disabled.
8414 (define_insn "*blt_media_i"
8416 (if_then_else (match_operator 3 "less_comparison_operator"
8417 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
8418 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
8419 (match_operand 0 "target_operand" "b")
8422 "b%o3%' %N2, %N1, %0%>"
8423 [(set_attr "type" "cbranch_media")])
8425 (define_insn "*blt_media_i32"
8427 (if_then_else (match_operator 3 "less_comparison_operator"
8428 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
8429 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
8430 (match_operand 0 "target_operand" "b")
8433 "b%o3%' %N2, %N1, %0%>"
8434 [(set_attr "type" "cbranch_media")])
8436 ;; combiner splitter for test-and-branch on single bit in register. This
8437 ;; is endian dependent because the non-paradoxical subreg looks different
8442 (match_operator 3 "equality_comparison_operator"
8443 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
8444 "extend_reg_operand" "")
8448 "const_int_operand" "")) 0)
8450 (match_operand 0 "target_operand" "")
8452 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
8453 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
8454 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
8455 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
8457 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
8458 operands[6] = (GET_CODE (operands[3]) == EQ
8459 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
8460 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
8463 ; operand 0 is the loop count pseudo register
8464 ; operand 1 is the number of loop iterations or 0 if it is unknown
8465 ; operand 2 is the maximum number of loop iterations
8466 ; operand 3 is the number of levels of enclosed loops
8467 ; operand 4 is the label to jump to at the top of the loop
8469 (define_expand "doloop_end"
8470 [(parallel [(set (pc) (if_then_else
8471 (ne:SI (match_operand:SI 0 "" "")
8473 (label_ref (match_operand 4 "" ""))
8476 (plus:SI (match_dup 0) (const_int -1)))
8477 (clobber (reg:SI T_REG))])
8478 (match_operand 5 "" "")]
8481 if (GET_MODE (operands[0]) != SImode)
8483 emit_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
8487 (define_insn_and_split "doloop_end_split"
8489 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
8491 (label_ref (match_operand 1 "" ""))
8493 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8494 (plus (match_dup 2) (const_int -1)))
8495 (clobber (reg:SI T_REG))]
8499 [(parallel [(set (reg:SI T_REG)
8500 (eq:SI (match_dup 2) (const_int 1)))
8501 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
8502 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
8503 (label_ref (match_dup 1))
8506 [(set_attr "type" "cbranch")])
8509 ;; ------------------------------------------------------------------------
8510 ;; Jump and linkage insns
8511 ;; ------------------------------------------------------------------------
8513 (define_insn "jump_compact"
8515 (label_ref (match_operand 0 "" "")))]
8516 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
8518 /* The length is 16 if the delay slot is unfilled. */
8519 if (get_attr_length(insn) > 4)
8520 return output_far_jump(insn, operands[0]);
8524 [(set_attr "type" "jump")
8525 (set_attr "needs_delay_slot" "yes")])
8527 ;; ??? It would be much saner to explicitly use the scratch register
8528 ;; in the jump insn, and have indirect_jump_scratch only set it,
8529 ;; but fill_simple_delay_slots would refuse to do delay slot filling
8530 ;; from the target then, as it uses simplejump_p.
8531 ;;(define_insn "jump_compact_far"
8533 ;; (label_ref (match_operand 0 "" "")))
8534 ;; (use (match_operand 1 "register_operand" "r")]
8536 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
8537 ;; [(set_attr "type" "jump")
8538 ;; (set_attr "needs_delay_slot" "yes")])
8540 (define_insn "jump_media"
8542 (match_operand 0 "target_operand" "b"))]
8545 [(set_attr "type" "jump_media")])
8547 (define_expand "jump"
8549 (label_ref (match_operand 0 "" "")))]
8553 emit_jump_insn (gen_jump_compact (operands[0]));
8554 else if (TARGET_SHMEDIA)
8556 if (reload_in_progress || reload_completed)
8558 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
8564 (define_insn "force_mode_for_call"
8565 [(use (reg:PSI FPSCR_REG))]
8568 [(set_attr "length" "0")
8569 (set (attr "fp_mode")
8570 (if_then_else (eq_attr "fpu_single" "yes")
8571 (const_string "single") (const_string "double")))])
8573 (define_insn "calli"
8574 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8575 (match_operand 1 "" ""))
8576 (use (reg:PSI FPSCR_REG))
8577 (clobber (reg:SI PR_REG))]
8580 if (TARGET_SH2A && (dbr_sequence_length () == 0))
8585 [(set_attr "type" "call")
8586 (set (attr "fp_mode")
8587 (if_then_else (eq_attr "fpu_single" "yes")
8588 (const_string "single") (const_string "double")))
8589 (set_attr "needs_delay_slot" "yes")
8590 (set_attr "fp_set" "unknown")])
8592 ;; This is TBR relative jump instruction for SH2A architecture.
8593 ;; Its use is enabled assigning an attribute "function_vector"
8594 ;; and the vector number to a function during its declaration.
8596 (define_insn "calli_tbr_rel"
8597 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
8598 (match_operand 1 "" ""))
8599 (use (reg:PSI FPSCR_REG))
8600 (clobber (reg:SI PR_REG))]
8601 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
8603 unsigned HOST_WIDE_INT vect_num;
8604 vect_num = sh2a_get_function_vector_number (operands[0]);
8605 operands[2] = GEN_INT (vect_num * 4);
8607 return "jsr/n @@(%O2,tbr)";
8609 [(set_attr "type" "call")
8610 (set (attr "fp_mode")
8611 (if_then_else (eq_attr "fpu_single" "yes")
8612 (const_string "single") (const_string "double")))
8613 (set_attr "needs_delay_slot" "no")
8614 (set_attr "fp_set" "unknown")])
8616 ;; This is a pc-rel call, using bsrf, for use with PIC.
8618 (define_insn "calli_pcrel"
8619 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8620 (match_operand 1 "" ""))
8621 (use (reg:PSI FPSCR_REG))
8622 (use (reg:SI PIC_REG))
8623 (use (match_operand 2 "" ""))
8624 (clobber (reg:SI PR_REG))]
8627 return "bsrf %0" "\n"
8630 [(set_attr "type" "call")
8631 (set (attr "fp_mode")
8632 (if_then_else (eq_attr "fpu_single" "yes")
8633 (const_string "single") (const_string "double")))
8634 (set_attr "needs_delay_slot" "yes")
8635 (set_attr "fp_set" "unknown")])
8637 (define_insn_and_split "call_pcrel"
8638 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8639 (match_operand 1 "" ""))
8640 (use (reg:PSI FPSCR_REG))
8641 (use (reg:SI PIC_REG))
8642 (clobber (reg:SI PR_REG))
8643 (clobber (match_scratch:SI 2 "=r"))]
8649 rtx lab = PATTERN (gen_call_site ());
8651 if (SYMBOL_REF_LOCAL_P (operands[0]))
8652 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8654 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
8655 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
8658 [(set_attr "type" "call")
8659 (set (attr "fp_mode")
8660 (if_then_else (eq_attr "fpu_single" "yes")
8661 (const_string "single") (const_string "double")))
8662 (set_attr "needs_delay_slot" "yes")
8663 (set_attr "fp_set" "unknown")])
8665 (define_insn "call_compact"
8666 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8667 (match_operand 1 "" ""))
8668 (match_operand 2 "immediate_operand" "n")
8669 (use (reg:SI R0_REG))
8670 (use (reg:SI R1_REG))
8671 (use (reg:PSI FPSCR_REG))
8672 (clobber (reg:SI PR_REG))]
8673 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8675 [(set_attr "type" "call")
8676 (set (attr "fp_mode")
8677 (if_then_else (eq_attr "fpu_single" "yes")
8678 (const_string "single") (const_string "double")))
8679 (set_attr "needs_delay_slot" "yes")])
8681 (define_insn "call_compact_rettramp"
8682 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8683 (match_operand 1 "" ""))
8684 (match_operand 2 "immediate_operand" "n")
8685 (use (reg:SI R0_REG))
8686 (use (reg:SI R1_REG))
8687 (use (reg:PSI FPSCR_REG))
8688 (clobber (reg:SI R10_REG))
8689 (clobber (reg:SI PR_REG))]
8690 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8692 [(set_attr "type" "call")
8693 (set (attr "fp_mode")
8694 (if_then_else (eq_attr "fpu_single" "yes")
8695 (const_string "single") (const_string "double")))
8696 (set_attr "needs_delay_slot" "yes")])
8698 (define_insn "call_media"
8699 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
8700 (match_operand 1 "" ""))
8701 (clobber (reg:DI PR_MEDIA_REG))]
8704 [(set_attr "type" "jump_media")])
8706 (define_insn "call_valuei"
8707 [(set (match_operand 0 "" "=rf")
8708 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8709 (match_operand 2 "" "")))
8710 (use (reg:PSI FPSCR_REG))
8711 (clobber (reg:SI PR_REG))]
8714 if (TARGET_SH2A && (dbr_sequence_length () == 0))
8719 [(set_attr "type" "call")
8720 (set (attr "fp_mode")
8721 (if_then_else (eq_attr "fpu_single" "yes")
8722 (const_string "single") (const_string "double")))
8723 (set_attr "needs_delay_slot" "yes")
8724 (set_attr "fp_set" "unknown")])
8726 ;; This is TBR relative jump instruction for SH2A architecture.
8727 ;; Its use is enabled by assigning an attribute "function_vector"
8728 ;; and the vector number to a function during its declaration.
8730 (define_insn "call_valuei_tbr_rel"
8731 [(set (match_operand 0 "" "=rf")
8732 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8733 (match_operand 2 "" "")))
8734 (use (reg:PSI FPSCR_REG))
8735 (clobber (reg:SI PR_REG))]
8736 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
8738 unsigned HOST_WIDE_INT vect_num;
8739 vect_num = sh2a_get_function_vector_number (operands[1]);
8740 operands[3] = GEN_INT (vect_num * 4);
8742 return "jsr/n @@(%O3,tbr)";
8744 [(set_attr "type" "call")
8745 (set (attr "fp_mode")
8746 (if_then_else (eq_attr "fpu_single" "yes")
8747 (const_string "single") (const_string "double")))
8748 (set_attr "needs_delay_slot" "no")
8749 (set_attr "fp_set" "unknown")])
8751 (define_insn "call_valuei_pcrel"
8752 [(set (match_operand 0 "" "=rf")
8753 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8754 (match_operand 2 "" "")))
8755 (use (reg:PSI FPSCR_REG))
8756 (use (reg:SI PIC_REG))
8757 (use (match_operand 3 "" ""))
8758 (clobber (reg:SI PR_REG))]
8761 return "bsrf %1" "\n"
8764 [(set_attr "type" "call")
8765 (set (attr "fp_mode")
8766 (if_then_else (eq_attr "fpu_single" "yes")
8767 (const_string "single") (const_string "double")))
8768 (set_attr "needs_delay_slot" "yes")
8769 (set_attr "fp_set" "unknown")])
8771 (define_insn_and_split "call_value_pcrel"
8772 [(set (match_operand 0 "" "=rf")
8773 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8774 (match_operand 2 "" "")))
8775 (use (reg:PSI FPSCR_REG))
8776 (use (reg:SI PIC_REG))
8777 (clobber (reg:SI PR_REG))
8778 (clobber (match_scratch:SI 3 "=r"))]
8784 rtx lab = PATTERN (gen_call_site ());
8786 if (SYMBOL_REF_LOCAL_P (operands[1]))
8787 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8789 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
8790 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
8791 operands[2], copy_rtx (lab)));
8794 [(set_attr "type" "call")
8795 (set (attr "fp_mode")
8796 (if_then_else (eq_attr "fpu_single" "yes")
8797 (const_string "single") (const_string "double")))
8798 (set_attr "needs_delay_slot" "yes")
8799 (set_attr "fp_set" "unknown")])
8801 (define_insn "call_value_compact"
8802 [(set (match_operand 0 "" "=rf")
8803 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8804 (match_operand 2 "" "")))
8805 (match_operand 3 "immediate_operand" "n")
8806 (use (reg:SI R0_REG))
8807 (use (reg:SI R1_REG))
8808 (use (reg:PSI FPSCR_REG))
8809 (clobber (reg:SI PR_REG))]
8810 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8812 [(set_attr "type" "call")
8813 (set (attr "fp_mode")
8814 (if_then_else (eq_attr "fpu_single" "yes")
8815 (const_string "single") (const_string "double")))
8816 (set_attr "needs_delay_slot" "yes")])
8818 (define_insn "call_value_compact_rettramp"
8819 [(set (match_operand 0 "" "=rf")
8820 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8821 (match_operand 2 "" "")))
8822 (match_operand 3 "immediate_operand" "n")
8823 (use (reg:SI R0_REG))
8824 (use (reg:SI R1_REG))
8825 (use (reg:PSI FPSCR_REG))
8826 (clobber (reg:SI R10_REG))
8827 (clobber (reg:SI PR_REG))]
8828 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8830 [(set_attr "type" "call")
8831 (set (attr "fp_mode")
8832 (if_then_else (eq_attr "fpu_single" "yes")
8833 (const_string "single") (const_string "double")))
8834 (set_attr "needs_delay_slot" "yes")])
8836 (define_insn "call_value_media"
8837 [(set (match_operand 0 "" "=rf")
8838 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
8839 (match_operand 2 "" "")))
8840 (clobber (reg:DI PR_MEDIA_REG))]
8843 [(set_attr "type" "jump_media")])
8845 (define_expand "call"
8846 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8847 (match_operand 1 "" ""))
8848 (match_operand 2 "" "")
8849 (use (reg:PSI FPSCR_REG))
8850 (clobber (reg:SI PR_REG))])]
8855 operands[0] = shmedia_prepare_call_address (operands[0], 0);
8856 emit_call_insn (gen_call_media (operands[0], operands[1]));
8859 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
8861 rtx cookie_rtx = operands[2];
8862 long cookie = INTVAL (cookie_rtx);
8863 rtx func = XEXP (operands[0], 0);
8868 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8870 rtx reg = gen_reg_rtx (Pmode);
8872 emit_insn (gen_symGOTPLT2reg (reg, func));
8876 func = legitimize_pic_address (func, Pmode, 0);
8879 r0 = gen_rtx_REG (SImode, R0_REG);
8880 r1 = gen_rtx_REG (SImode, R1_REG);
8882 /* Since such a call function may use all call-clobbered
8883 registers, we force a mode switch earlier, so that we don't
8884 run out of registers when adjusting fpscr for the call. */
8885 emit_insn (gen_force_mode_for_call ());
8888 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8889 operands[0] = force_reg (SImode, operands[0]);
8891 emit_move_insn (r0, func);
8892 emit_move_insn (r1, cookie_rtx);
8894 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8895 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
8898 emit_call_insn (gen_call_compact (operands[0], operands[1],
8903 else if (TARGET_SHCOMPACT && flag_pic
8904 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8905 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8907 rtx reg = gen_reg_rtx (Pmode);
8909 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
8910 XEXP (operands[0], 0) = reg;
8912 if (!flag_pic && TARGET_SH2A
8913 && MEM_P (operands[0])
8914 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
8916 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
8918 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
8923 if (flag_pic && TARGET_SH2
8924 && MEM_P (operands[0])
8925 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
8927 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
8932 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8933 operands[1] = operands[2];
8936 emit_call_insn (gen_calli (operands[0], operands[1]));
8940 (define_insn "call_pop_compact"
8941 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8942 (match_operand 1 "" ""))
8943 (match_operand 2 "immediate_operand" "n")
8944 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8945 (match_operand 3 "immediate_operand" "n")))
8946 (use (reg:SI R0_REG))
8947 (use (reg:SI R1_REG))
8948 (use (reg:PSI FPSCR_REG))
8949 (clobber (reg:SI PR_REG))]
8950 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8952 [(set_attr "type" "call")
8953 (set (attr "fp_mode")
8954 (if_then_else (eq_attr "fpu_single" "yes")
8955 (const_string "single") (const_string "double")))
8956 (set_attr "needs_delay_slot" "yes")])
8958 (define_insn "call_pop_compact_rettramp"
8959 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
8960 (match_operand 1 "" ""))
8961 (match_operand 2 "immediate_operand" "n")
8962 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8963 (match_operand 3 "immediate_operand" "n")))
8964 (use (reg:SI R0_REG))
8965 (use (reg:SI R1_REG))
8966 (use (reg:PSI FPSCR_REG))
8967 (clobber (reg:SI R10_REG))
8968 (clobber (reg:SI PR_REG))]
8969 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
8971 [(set_attr "type" "call")
8972 (set (attr "fp_mode")
8973 (if_then_else (eq_attr "fpu_single" "yes")
8974 (const_string "single") (const_string "double")))
8975 (set_attr "needs_delay_slot" "yes")])
8977 (define_expand "call_pop"
8978 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8979 (match_operand 1 "" ""))
8980 (match_operand 2 "" "")
8981 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8982 (match_operand 3 "" "")))])]
8990 gcc_assert (operands[2] && INTVAL (operands[2]));
8991 cookie_rtx = operands[2];
8992 cookie = INTVAL (cookie_rtx);
8993 func = XEXP (operands[0], 0);
8997 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8999 rtx reg = gen_reg_rtx (Pmode);
9000 emit_insn (gen_symGOTPLT2reg (reg, func));
9004 func = legitimize_pic_address (func, Pmode, 0);
9007 r0 = gen_rtx_REG (SImode, R0_REG);
9008 r1 = gen_rtx_REG (SImode, R1_REG);
9010 /* Since such a call function may use all call-clobbered
9011 registers, we force a mode switch earlier, so that we don't
9012 run out of registers when adjusting fpscr for the call. */
9013 emit_insn (gen_force_mode_for_call ());
9015 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9017 operands[0] = force_reg (SImode, operands[0]);
9019 emit_move_insn (r0, func);
9020 emit_move_insn (r1, cookie_rtx);
9022 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9023 emit_call_insn (gen_call_pop_compact_rettramp
9024 (operands[0], operands[1], operands[2], operands[3]));
9026 emit_call_insn (gen_call_pop_compact
9027 (operands[0], operands[1], operands[2], operands[3]));
9032 (define_expand "call_value"
9033 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9034 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9035 (match_operand 2 "" "")))
9036 (match_operand 3 "" "")
9037 (use (reg:PSI FPSCR_REG))
9038 (clobber (reg:SI PR_REG))])]
9043 operands[1] = shmedia_prepare_call_address (operands[1], 0);
9044 emit_call_insn (gen_call_value_media (operands[0], operands[1],
9048 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
9050 rtx cookie_rtx = operands[3];
9051 long cookie = INTVAL (cookie_rtx);
9052 rtx func = XEXP (operands[1], 0);
9057 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9059 rtx reg = gen_reg_rtx (Pmode);
9061 emit_insn (gen_symGOTPLT2reg (reg, func));
9065 func = legitimize_pic_address (func, Pmode, 0);
9068 r0 = gen_rtx_REG (SImode, R0_REG);
9069 r1 = gen_rtx_REG (SImode, R1_REG);
9071 /* Since such a call function may use all call-clobbered
9072 registers, we force a mode switch earlier, so that we don't
9073 run out of registers when adjusting fpscr for the call. */
9074 emit_insn (gen_force_mode_for_call ());
9077 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9078 operands[1] = force_reg (SImode, operands[1]);
9080 emit_move_insn (r0, func);
9081 emit_move_insn (r1, cookie_rtx);
9083 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9084 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
9089 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
9090 operands[2], operands[3]));
9094 else if (TARGET_SHCOMPACT && flag_pic
9095 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9096 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9098 rtx reg = gen_reg_rtx (Pmode);
9100 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
9101 XEXP (operands[1], 0) = reg;
9103 if (!flag_pic && TARGET_SH2A
9104 && MEM_P (operands[1])
9105 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9107 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
9109 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
9110 XEXP (operands[1], 0), operands[2]));
9114 if (flag_pic && TARGET_SH2
9115 && MEM_P (operands[1])
9116 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
9118 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
9123 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9125 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
9129 (define_insn "sibcalli"
9130 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
9131 (match_operand 1 "" ""))
9132 (use (reg:PSI FPSCR_REG))
9136 [(set_attr "needs_delay_slot" "yes")
9137 (set (attr "fp_mode")
9138 (if_then_else (eq_attr "fpu_single" "yes")
9139 (const_string "single") (const_string "double")))
9140 (set_attr "type" "jump_ind")])
9142 (define_insn "sibcalli_pcrel"
9143 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
9144 (match_operand 1 "" ""))
9145 (use (match_operand 2 "" ""))
9146 (use (reg:PSI FPSCR_REG))
9150 return "braf %0" "\n"
9153 [(set_attr "needs_delay_slot" "yes")
9154 (set (attr "fp_mode")
9155 (if_then_else (eq_attr "fpu_single" "yes")
9156 (const_string "single") (const_string "double")))
9157 (set_attr "type" "jump_ind")])
9159 ;; This uses an unspec to describe that the symbol_ref is very close.
9160 (define_insn "sibcalli_thunk"
9161 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
9163 (match_operand 1 "" ""))
9164 (use (reg:PSI FPSCR_REG))
9168 [(set_attr "needs_delay_slot" "yes")
9169 (set (attr "fp_mode")
9170 (if_then_else (eq_attr "fpu_single" "yes")
9171 (const_string "single") (const_string "double")))
9172 (set_attr "type" "jump")
9173 (set_attr "length" "2")])
9175 (define_insn_and_split "sibcall_pcrel"
9176 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
9177 (match_operand 1 "" ""))
9178 (use (reg:PSI FPSCR_REG))
9179 (clobber (match_scratch:SI 2 "=k"))
9186 rtx lab = PATTERN (gen_call_site ());
9189 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
9190 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
9192 SIBLING_CALL_P (call_insn) = 1;
9195 [(set_attr "needs_delay_slot" "yes")
9196 (set (attr "fp_mode")
9197 (if_then_else (eq_attr "fpu_single" "yes")
9198 (const_string "single") (const_string "double")))
9199 (set_attr "type" "jump_ind")])
9201 (define_insn "sibcall_compact"
9202 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
9203 (match_operand 1 "" ""))
9205 (use (match_operand:SI 2 "register_operand" "z,x"))
9206 (use (reg:SI R1_REG))
9207 (use (reg:PSI FPSCR_REG))
9208 ;; We want to make sure the `x' above will only match MACH_REG
9209 ;; because sibcall_epilogue may clobber MACL_REG.
9210 (clobber (reg:SI MACL_REG))]
9213 static const char* alt[] =
9220 return alt[which_alternative];
9222 [(set_attr "needs_delay_slot" "yes,no")
9223 (set_attr "length" "2,4")
9224 (set (attr "fp_mode") (const_string "single"))
9225 (set_attr "type" "jump_ind")])
9227 (define_insn "sibcall_media"
9228 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
9229 (match_operand 1 "" ""))
9230 (use (reg:SI PR_MEDIA_REG))
9234 [(set_attr "type" "jump_media")])
9236 (define_expand "sibcall"
9238 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
9239 (match_operand 1 "" ""))
9240 (match_operand 2 "" "")
9241 (use (reg:PSI FPSCR_REG))
9247 operands[0] = shmedia_prepare_call_address (operands[0], 1);
9248 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
9251 else if (TARGET_SHCOMPACT && operands[2]
9252 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9254 rtx cookie_rtx = operands[2];
9255 long cookie = INTVAL (cookie_rtx);
9256 rtx func = XEXP (operands[0], 0);
9261 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9263 rtx reg = gen_reg_rtx (Pmode);
9265 emit_insn (gen_symGOT2reg (reg, func));
9269 func = legitimize_pic_address (func, Pmode, 0);
9272 /* FIXME: if we could tell whether all argument registers are
9273 already taken, we could decide whether to force the use of
9274 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9275 simple way to tell. We could use the CALL_COOKIE, but we
9276 can't currently tell a register used for regular argument
9277 passing from one that is unused. If we leave it up to reload
9278 to decide which register to use, it seems to always choose
9279 R0_REG, which leaves no available registers in SIBCALL_REGS
9280 to hold the address of the trampoline. */
9281 mach = gen_rtx_REG (SImode, MACH_REG);
9282 r1 = gen_rtx_REG (SImode, R1_REG);
9284 /* Since such a call function may use all call-clobbered
9285 registers, we force a mode switch earlier, so that we don't
9286 run out of registers when adjusting fpscr for the call. */
9287 emit_insn (gen_force_mode_for_call ());
9290 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9291 operands[0] = force_reg (SImode, operands[0]);
9293 /* We don't need a return trampoline, since the callee will
9294 return directly to the upper caller. */
9295 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9297 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9298 cookie_rtx = GEN_INT (cookie);
9301 emit_move_insn (mach, func);
9302 emit_move_insn (r1, cookie_rtx);
9304 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
9307 else if (TARGET_SHCOMPACT && flag_pic
9308 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9309 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9311 rtx reg = gen_reg_rtx (Pmode);
9313 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
9314 XEXP (operands[0], 0) = reg;
9316 if (flag_pic && TARGET_SH2
9317 && MEM_P (operands[0])
9318 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9319 /* The PLT needs the PIC register, but the epilogue would have
9320 to restore it, so we can only use PC-relative PIC calls for
9321 static functions. */
9322 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
9324 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
9328 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9330 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
9334 (define_insn "sibcall_valuei"
9335 [(set (match_operand 0 "" "=rf")
9336 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
9337 (match_operand 2 "" "")))
9338 (use (reg:PSI FPSCR_REG))
9342 [(set_attr "needs_delay_slot" "yes")
9343 (set (attr "fp_mode")
9344 (if_then_else (eq_attr "fpu_single" "yes")
9345 (const_string "single") (const_string "double")))
9346 (set_attr "type" "jump_ind")])
9348 (define_insn "sibcall_valuei_pcrel"
9349 [(set (match_operand 0 "" "=rf")
9350 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
9351 (match_operand 2 "" "")))
9352 (use (match_operand 3 "" ""))
9353 (use (reg:PSI FPSCR_REG))
9357 return "braf %1" "\n"
9360 [(set_attr "needs_delay_slot" "yes")
9361 (set (attr "fp_mode")
9362 (if_then_else (eq_attr "fpu_single" "yes")
9363 (const_string "single") (const_string "double")))
9364 (set_attr "type" "jump_ind")])
9366 (define_insn_and_split "sibcall_value_pcrel"
9367 [(set (match_operand 0 "" "=rf")
9368 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
9369 (match_operand 2 "" "")))
9370 (use (reg:PSI FPSCR_REG))
9371 (clobber (match_scratch:SI 3 "=k"))
9378 rtx lab = PATTERN (gen_call_site ());
9381 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
9382 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
9386 SIBLING_CALL_P (call_insn) = 1;
9389 [(set_attr "needs_delay_slot" "yes")
9390 (set (attr "fp_mode")
9391 (if_then_else (eq_attr "fpu_single" "yes")
9392 (const_string "single") (const_string "double")))
9393 (set_attr "type" "jump_ind")])
9395 (define_insn "sibcall_value_compact"
9396 [(set (match_operand 0 "" "=rf,rf")
9397 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
9398 (match_operand 2 "" "")))
9400 (use (match_operand:SI 3 "register_operand" "z,x"))
9401 (use (reg:SI R1_REG))
9402 (use (reg:PSI FPSCR_REG))
9403 ;; We want to make sure the `x' above will only match MACH_REG
9404 ;; because sibcall_epilogue may clobber MACL_REG.
9405 (clobber (reg:SI MACL_REG))]
9408 static const char* alt[] =
9415 return alt[which_alternative];
9417 [(set_attr "needs_delay_slot" "yes,no")
9418 (set_attr "length" "2,4")
9419 (set (attr "fp_mode") (const_string "single"))
9420 (set_attr "type" "jump_ind")])
9422 (define_insn "sibcall_value_media"
9423 [(set (match_operand 0 "" "=rf")
9424 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
9425 (match_operand 2 "" "")))
9426 (use (reg:SI PR_MEDIA_REG))
9430 [(set_attr "type" "jump_media")])
9432 (define_expand "sibcall_value"
9434 [(set (match_operand 0 "arith_reg_operand" "")
9435 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9436 (match_operand 2 "" "")))
9437 (match_operand 3 "" "")
9438 (use (reg:PSI FPSCR_REG))
9444 operands[1] = shmedia_prepare_call_address (operands[1], 1);
9445 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
9449 else if (TARGET_SHCOMPACT && operands[3]
9450 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
9452 rtx cookie_rtx = operands[3];
9453 long cookie = INTVAL (cookie_rtx);
9454 rtx func = XEXP (operands[1], 0);
9459 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9461 rtx reg = gen_reg_rtx (Pmode);
9463 emit_insn (gen_symGOT2reg (reg, func));
9467 func = legitimize_pic_address (func, Pmode, 0);
9470 /* FIXME: if we could tell whether all argument registers are
9471 already taken, we could decide whether to force the use of
9472 MACH_REG or to stick to R0_REG. Unfortunately, there's no
9473 simple way to tell. We could use the CALL_COOKIE, but we
9474 can't currently tell a register used for regular argument
9475 passing from one that is unused. If we leave it up to reload
9476 to decide which register to use, it seems to always choose
9477 R0_REG, which leaves no available registers in SIBCALL_REGS
9478 to hold the address of the trampoline. */
9479 mach = gen_rtx_REG (SImode, MACH_REG);
9480 r1 = gen_rtx_REG (SImode, R1_REG);
9482 /* Since such a call function may use all call-clobbered
9483 registers, we force a mode switch earlier, so that we don't
9484 run out of registers when adjusting fpscr for the call. */
9485 emit_insn (gen_force_mode_for_call ());
9488 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
9489 operands[1] = force_reg (SImode, operands[1]);
9491 /* We don't need a return trampoline, since the callee will
9492 return directly to the upper caller. */
9493 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9495 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
9496 cookie_rtx = GEN_INT (cookie);
9499 emit_move_insn (mach, func);
9500 emit_move_insn (r1, cookie_rtx);
9502 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
9503 operands[2], mach));
9506 else if (TARGET_SHCOMPACT && flag_pic
9507 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9508 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9510 rtx reg = gen_reg_rtx (Pmode);
9512 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
9513 XEXP (operands[1], 0) = reg;
9515 if (flag_pic && TARGET_SH2
9516 && MEM_P (operands[1])
9517 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9518 /* The PLT needs the PIC register, but the epilogue would have
9519 to restore it, so we can only use PC-relative PIC calls for
9520 static functions. */
9521 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
9523 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
9524 XEXP (operands[1], 0),
9529 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9531 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
9535 (define_insn "call_value_pop_compact"
9536 [(set (match_operand 0 "" "=rf")
9537 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9538 (match_operand 2 "" "")))
9539 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9540 (match_operand 4 "immediate_operand" "n")))
9541 (match_operand 3 "immediate_operand" "n")
9542 (use (reg:SI R0_REG))
9543 (use (reg:SI R1_REG))
9544 (use (reg:PSI FPSCR_REG))
9545 (clobber (reg:SI PR_REG))]
9546 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9548 [(set_attr "type" "call")
9549 (set (attr "fp_mode")
9550 (if_then_else (eq_attr "fpu_single" "yes")
9551 (const_string "single") (const_string "double")))
9552 (set_attr "needs_delay_slot" "yes")])
9554 (define_insn "call_value_pop_compact_rettramp"
9555 [(set (match_operand 0 "" "=rf")
9556 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
9557 (match_operand 2 "" "")))
9558 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9559 (match_operand 4 "immediate_operand" "n")))
9560 (match_operand 3 "immediate_operand" "n")
9561 (use (reg:SI R0_REG))
9562 (use (reg:SI R1_REG))
9563 (use (reg:PSI FPSCR_REG))
9564 (clobber (reg:SI R10_REG))
9565 (clobber (reg:SI PR_REG))]
9566 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
9568 [(set_attr "type" "call")
9569 (set (attr "fp_mode")
9570 (if_then_else (eq_attr "fpu_single" "yes")
9571 (const_string "single") (const_string "double")))
9572 (set_attr "needs_delay_slot" "yes")])
9574 (define_expand "call_value_pop"
9575 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
9576 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
9577 (match_operand 2 "" "")))
9578 (match_operand 3 "" "")
9579 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
9580 (match_operand 4 "" "")))])]
9588 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
9589 cookie_rtx = operands[3];
9590 cookie = INTVAL (cookie_rtx);
9591 func = XEXP (operands[1], 0);
9595 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
9597 rtx reg = gen_reg_rtx (Pmode);
9599 emit_insn (gen_symGOTPLT2reg (reg, func));
9603 func = legitimize_pic_address (func, Pmode, 0);
9606 r0 = gen_rtx_REG (SImode, R0_REG);
9607 r1 = gen_rtx_REG (SImode, R1_REG);
9609 /* Since such a call function may use all call-clobbered
9610 registers, we force a mode switch earlier, so that we don't
9611 run out of registers when adjusting fpscr for the call. */
9612 emit_insn (gen_force_mode_for_call ());
9614 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
9616 operands[1] = force_reg (SImode, operands[1]);
9618 emit_move_insn (r0, func);
9619 emit_move_insn (r1, cookie_rtx);
9621 if (cookie & CALL_COOKIE_RET_TRAMP (1))
9622 emit_call_insn (gen_call_value_pop_compact_rettramp
9623 (operands[0], operands[1], operands[2],
9624 operands[3], operands[4]));
9626 emit_call_insn (gen_call_value_pop_compact
9627 (operands[0], operands[1], operands[2],
9628 operands[3], operands[4]));
9633 (define_expand "sibcall_epilogue"
9637 sh_expand_epilogue (true);
9638 if (TARGET_SHCOMPACT)
9642 /* If epilogue clobbers r0, preserve it in macl. */
9643 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9644 if ((set = single_set (insn))
9645 && REG_P (SET_DEST (set))
9646 && REGNO (SET_DEST (set)) == R0_REG)
9648 rtx r0 = gen_rtx_REG (SImode, R0_REG);
9649 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
9651 /* We can't tell at this point whether the sibcall is a
9652 sibcall_compact and, if it is, whether it uses r0 or
9653 mach as operand 2, so let the instructions that
9654 preserve r0 be optimized away if r0 turns out to be
9656 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
9657 emit_move_insn (r0, tmp);
9664 (define_insn "indirect_jump_compact"
9666 (match_operand:SI 0 "arith_reg_operand" "r"))]
9669 [(set_attr "needs_delay_slot" "yes")
9670 (set_attr "type" "jump_ind")])
9672 (define_expand "indirect_jump"
9674 (match_operand 0 "register_operand" ""))]
9677 if (GET_MODE (operands[0]) != Pmode)
9678 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
9681 ;; The use of operand 1 / 2 helps us distinguish case table jumps
9682 ;; which can be present in structured code from indirect jumps which can not
9683 ;; be present in structured code. This allows -fprofile-arcs to work.
9685 ;; For SH1 processors.
9686 (define_insn "casesi_jump_1"
9688 (match_operand:SI 0 "register_operand" "r"))
9689 (use (label_ref (match_operand 1 "" "")))]
9692 [(set_attr "needs_delay_slot" "yes")
9693 (set_attr "type" "jump_ind")])
9695 ;; For all later processors.
9696 (define_insn "casesi_jump_2"
9697 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
9698 (label_ref (match_operand 1 "" ""))))
9699 (use (label_ref (match_operand 2 "" "")))]
9701 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
9703 [(set_attr "needs_delay_slot" "yes")
9704 (set_attr "type" "jump_ind")])
9706 (define_insn "casesi_jump_media"
9707 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
9708 (use (label_ref (match_operand 1 "" "")))]
9711 [(set_attr "type" "jump_media")])
9713 ;; Call subroutine returning any type.
9714 ;; ??? This probably doesn't work.
9716 (define_expand "untyped_call"
9717 [(parallel [(call (match_operand 0 "" "")
9719 (match_operand 1 "" "")
9720 (match_operand 2 "" "")])]
9721 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
9725 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9727 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9729 rtx set = XVECEXP (operands[2], 0, i);
9730 emit_move_insn (SET_DEST (set), SET_SRC (set));
9733 /* The optimizer does not know that the call sets the function value
9734 registers we stored in the result block. We avoid problems by
9735 claiming that all hard registers are used and clobbered at this
9737 emit_insn (gen_blockage ());
9742 ;; ------------------------------------------------------------------------
9744 ;; ------------------------------------------------------------------------
9747 [(set (reg:SI T_REG)
9748 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
9749 (set (match_operand:SI 0 "arith_reg_dest" "=r")
9750 (plus:SI (match_dup 1) (const_int -1)))]
9753 [(set_attr "type" "arith")])
9760 ;; Load address of a label. This is only generated by the casesi expand,
9761 ;; and by machine_dependent_reorg (fixing up fp moves).
9762 ;; This must use unspec, because this only works for labels that are
9766 [(set (reg:SI R0_REG)
9767 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
9770 [(set_attr "in_delay_slot" "no")
9771 (set_attr "type" "arith")])
9773 ;; machine_dependent_reorg will make this a `mova'.
9774 (define_insn "mova_const"
9775 [(set (reg:SI R0_REG)
9776 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
9779 [(set_attr "in_delay_slot" "no")
9780 (set_attr "type" "arith")])
9782 (define_expand "GOTaddr2picreg"
9783 [(set (reg:SI R0_REG)
9784 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
9786 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
9787 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9790 if (TARGET_VXWORKS_RTP)
9792 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
9793 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
9794 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
9798 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
9799 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
9803 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
9804 rtx pic = operands[0];
9805 rtx lab = PATTERN (gen_call_site ());
9808 equiv = operands[1];
9809 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
9810 UNSPEC_PCREL_SYMOFF);
9811 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
9813 if (Pmode == SImode)
9815 emit_insn (gen_movsi_const (pic, operands[1]));
9816 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
9820 emit_insn (gen_movdi_const (pic, operands[1]));
9821 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
9824 insn = emit_move_insn (operands[0], tr);
9826 set_unique_reg_note (insn, REG_EQUAL, equiv);
9832 ;; A helper for GOTaddr2picreg to finish up the initialization of the
9835 (define_expand "vxworks_picreg"
9836 [(set (reg:SI PIC_REG)
9837 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
9838 (set (reg:SI R0_REG)
9839 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
9840 (set (reg:SI PIC_REG)
9841 (mem:SI (reg:SI PIC_REG)))
9842 (set (reg:SI PIC_REG)
9843 (mem:SI (plus:SI (reg:SI PIC_REG)
9845 "TARGET_VXWORKS_RTP")
9848 [(set (match_operand 0 "target_reg_operand" "=b")
9849 (const (unspec [(match_operand 1 "" "Csy")]
9850 UNSPEC_DATALABEL)))]
9851 "TARGET_SHMEDIA && flag_pic
9852 && satisfies_constraint_Csy (operands[1])"
9853 "ptb/u datalabel %1, %0"
9854 [(set_attr "type" "ptabs_media")
9855 (set_attr "length" "*")])
9857 (define_insn "ptrel_si"
9858 [(set (match_operand:SI 0 "target_reg_operand" "=b")
9859 (plus:SI (match_operand:SI 1 "register_operand" "r")
9861 (match_operand:SI 2 "" "")]
9863 "%O2: ptrel/u %1, %0"
9864 [(set_attr "type" "ptabs_media")])
9866 (define_insn "ptrel_di"
9867 [(set (match_operand:DI 0 "target_reg_operand" "=b")
9868 (plus:DI (match_operand:DI 1 "register_operand" "r")
9870 (match_operand:DI 2 "" "")]
9872 "%O2: ptrel/u %1, %0"
9873 [(set_attr "type" "ptabs_media")])
9875 (define_expand "builtin_setjmp_receiver"
9876 [(match_operand 0 "" "")]
9879 emit_insn (gen_GOTaddr2picreg ());
9883 (define_expand "call_site"
9884 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
9887 static HOST_WIDE_INT i = 0;
9888 operands[0] = GEN_INT (i);
9892 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
9893 ;; in symGOT_load expand.
9895 (define_insn_and_split "chk_guard_add"
9896 [(set (match_operand:SI 0 "register_operand" "=&r")
9897 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
9902 "TARGET_SH1 && reload_completed"
9903 [(set (match_dup 0) (reg:SI PIC_REG))
9904 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9906 [(set_attr "type" "arith")])
9908 (define_expand "sym_label2reg"
9909 [(set (match_operand:SI 0 "" "")
9910 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
9911 (const (plus:SI (match_operand:SI 2 "" "")
9916 (define_expand "symGOT_load"
9917 [(set (match_dup 2) (match_operand 1 "" ""))
9918 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
9919 (set (match_operand 0 "" "") (mem (match_dup 3)))]
9924 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
9925 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
9929 rtx reg = operands[2];
9931 if (Pmode == DImode)
9934 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
9936 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
9941 emit_insn (gen_movsi_const (reg, operands[1]));
9943 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
9947 emit_move_insn (operands[2], operands[1]);
9949 /* When stack protector inserts codes after the result is set to
9950 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
9951 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
9952 when rX is a GOT address for the guard symbol. Ugly but doesn't
9953 matter because this is a rare situation. */
9955 && flag_stack_protect
9956 && GET_CODE (operands[1]) == CONST
9957 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
9958 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
9959 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
9960 "__stack_chk_guard") == 0)
9961 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
9963 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
9964 gen_rtx_REG (Pmode, PIC_REG)));
9966 /* N.B. This is not constant for a GOTPLT relocation. */
9967 mem = gen_rtx_MEM (Pmode, operands[3]);
9968 MEM_NOTRAP_P (mem) = 1;
9969 /* ??? Should we have a special alias set for the GOT? */
9970 emit_move_insn (operands[0], mem);
9975 (define_expand "sym2GOT"
9976 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
9980 (define_expand "symGOT2reg"
9981 [(match_operand 0 "" "") (match_operand 1 "" "")]
9986 gotsym = gen_sym2GOT (operands[1]);
9987 PUT_MODE (gotsym, Pmode);
9988 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
9990 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
9995 (define_expand "symGOTPLT2reg"
9996 [(match_operand 0 "" "") (match_operand 1 "" "")]
9999 rtx pltsym = gen_rtx_CONST (Pmode,
10000 gen_rtx_UNSPEC (Pmode,
10001 gen_rtvec (1, operands[1]),
10003 emit_insn (gen_symGOT_load (operands[0], pltsym));
10007 (define_expand "sym2GOTOFF"
10008 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
10012 (define_expand "symGOTOFF2reg"
10013 [(match_operand 0 "" "") (match_operand 1 "" "")]
10016 rtx gotoffsym, insn;
10017 rtx t = (!can_create_pseudo_p ()
10019 : gen_reg_rtx (GET_MODE (operands[0])));
10021 gotoffsym = gen_sym2GOTOFF (operands[1]);
10022 PUT_MODE (gotoffsym, Pmode);
10023 emit_move_insn (t, gotoffsym);
10024 insn = emit_move_insn (operands[0],
10025 gen_rtx_PLUS (Pmode, t,
10026 gen_rtx_REG (Pmode, PIC_REG)));
10028 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
10033 (define_expand "symPLT_label2reg"
10034 [(set (match_operand:SI 0 "" "")
10037 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
10038 (const:SI (plus:SI (match_operand:SI 2 "" "")
10039 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
10040 ;; Even though the PIC register is not really used by the call
10041 ;; sequence in which this is expanded, the PLT code assumes the PIC
10042 ;; register is set, so we must not skip its initialization. Since
10043 ;; we only use this expand as part of calling sequences, and never
10044 ;; to take the address of a function, this is the best point to
10045 ;; insert the (use). Using the PLT to take the address of a
10046 ;; function would be wrong, not only because the PLT entry could
10047 ;; then be called from a function that doesn't initialize the PIC
10048 ;; register to the proper GOT, but also because pointers to the
10049 ;; same function might not compare equal, should they be set by
10050 ;; different shared libraries.
10051 (use (reg:SI PIC_REG))]
10055 (define_expand "sym2PIC"
10056 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
10060 ;; TLS code generation.
10061 ;; ??? this should be a define_insn_and_split
10062 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
10063 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
10066 (define_insn "tls_global_dynamic"
10067 [(set (match_operand:SI 0 "register_operand" "=&z")
10068 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10071 (use (reg:PSI FPSCR_REG))
10072 (use (reg:SI PIC_REG))
10073 (clobber (reg:SI PR_REG))
10074 (clobber (scratch:SI))]
10077 return "mov.l 1f,r4" "\n"
10079 " mov.l 2f,r1" "\n"
10086 "1: .long %a1@TLSGD" "\n"
10087 "2: .long __tls_get_addr@PLT" "\n"
10090 [(set_attr "type" "tls_load")
10091 (set_attr "length" "26")])
10093 (define_insn "tls_local_dynamic"
10094 [(set (match_operand:SI 0 "register_operand" "=&z")
10095 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
10098 (use (reg:PSI FPSCR_REG))
10099 (use (reg:SI PIC_REG))
10100 (clobber (reg:SI PR_REG))
10101 (clobber (scratch:SI))]
10104 return "mov.l 1f,r4" "\n"
10106 " mov.l 2f,r1" "\n"
10113 "1: .long %a1@TLSLDM" "\n"
10114 "2: .long __tls_get_addr@PLT" "\n"
10117 [(set_attr "type" "tls_load")
10118 (set_attr "length" "26")])
10120 (define_expand "sym2DTPOFF"
10121 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
10125 (define_expand "symDTPOFF2reg"
10126 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
10130 rtx t = (!can_create_pseudo_p ()
10132 : gen_reg_rtx (GET_MODE (operands[0])));
10134 dtpoffsym = gen_sym2DTPOFF (operands[1]);
10135 PUT_MODE (dtpoffsym, Pmode);
10136 emit_move_insn (t, dtpoffsym);
10137 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
10141 (define_expand "sym2GOTTPOFF"
10142 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
10146 (define_insn "tls_initial_exec"
10147 [(set (match_operand:SI 0 "register_operand" "=&r")
10148 (unspec:SI [(match_operand:SI 1 "" "")]
10150 (use (reg:SI GBR_REG))
10151 (use (reg:SI PIC_REG))
10152 (clobber (reg:SI R0_REG))]
10155 return "mov.l 1f,r0" "\n"
10157 " mov.l @(r0,r12),r0" "\n"
10161 "1: .long %a1" "\n"
10164 [(set_attr "type" "tls_load")
10165 (set_attr "length" "16")])
10167 (define_expand "sym2TPOFF"
10168 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
10172 (define_expand "symTPOFF2reg"
10173 [(match_operand 0 "" "") (match_operand 1 "" "")]
10178 tpoffsym = gen_sym2TPOFF (operands[1]);
10179 PUT_MODE (tpoffsym, Pmode);
10180 emit_move_insn (operands[0], tpoffsym);
10184 ;;------------------------------------------------------------------------------
10185 ;; Thread pointer getter and setter.
10187 ;; On SH the thread pointer is kept in the GBR.
10188 ;; These patterns are usually expanded from the respective built-in functions.
10189 (define_expand "get_thread_pointersi"
10190 [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
10193 ;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
10194 (define_insn "store_gbr"
10195 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
10198 [(set_attr "type" "tls_load")])
10200 (define_expand "set_thread_pointersi"
10201 [(set (reg:SI GBR_REG)
10202 (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
10206 (define_insn "load_gbr"
10207 [(set (reg:SI GBR_REG)
10208 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
10212 [(set_attr "type" "move")])
10214 ;;------------------------------------------------------------------------------
10215 ;; Thread pointer relative memory loads and stores.
10217 ;; On SH there are GBR displacement address modes which can be utilized to
10218 ;; access memory behind the thread pointer.
10219 ;; Since we do not allow using GBR for general purpose memory accesses, these
10220 ;; GBR addressing modes are formed by the combine pass.
10221 ;; This could be done with fewer patterns than below by using a mem predicate
10222 ;; for the GBR mem, but then reload would try to reload addresses with a
10223 ;; zero displacement for some strange reason.
10225 (define_insn "*mov<mode>_gbr_load"
10226 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10227 (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10228 (match_operand:QIHISI 1 "gbr_displacement"))))]
10230 "mov.<bwl> @(%O1,gbr),%0"
10231 [(set_attr "type" "load")])
10233 (define_insn "*mov<mode>_gbr_load"
10234 [(set (match_operand:QIHISI 0 "register_operand" "=z")
10235 (mem:QIHISI (reg:SI GBR_REG)))]
10237 "mov.<bwl> @(0,gbr),%0"
10238 [(set_attr "type" "load")])
10240 (define_insn "*mov<mode>_gbr_load"
10241 [(set (match_operand:SI 0 "register_operand" "=z")
10243 (mem:QIHI (plus:SI (reg:SI GBR_REG)
10244 (match_operand:QIHI 1 "gbr_displacement")))))]
10246 "mov.<bw> @(%O1,gbr),%0"
10247 [(set_attr "type" "load")])
10249 (define_insn "*mov<mode>_gbr_load"
10250 [(set (match_operand:SI 0 "register_operand" "=z")
10251 (sign_extend:SI (mem:QIHI (reg:SI GBR_REG))))]
10253 "mov.<bw> @(0,gbr),%0"
10254 [(set_attr "type" "load")])
10256 (define_insn "*mov<mode>_gbr_store"
10257 [(set (mem:QIHISI (plus:SI (reg:SI GBR_REG)
10258 (match_operand:QIHISI 0 "gbr_displacement")))
10259 (match_operand:QIHISI 1 "register_operand" "z"))]
10261 "mov.<bwl> %1,@(%O0,gbr)"
10262 [(set_attr "type" "store")])
10264 (define_insn "*mov<mode>_gbr_store"
10265 [(set (mem:QIHISI (reg:SI GBR_REG))
10266 (match_operand:QIHISI 0 "register_operand" "z"))]
10268 "mov.<bwl> %0,@(0,gbr)"
10269 [(set_attr "type" "store")])
10271 ;; DImode memory accesses have to be split in two SImode accesses.
10272 ;; Split them before reload, so that it gets a better chance to figure out
10273 ;; how to deal with the R0 restriction for the individual SImode accesses.
10274 ;; Do not match this insn during or after reload because it can't be split
10276 (define_insn_and_split "*movdi_gbr_load"
10277 [(set (match_operand:DI 0 "register_operand")
10278 (match_operand:DI 1 "gbr_address_mem"))]
10279 "TARGET_SH1 && can_create_pseudo_p ()"
10282 [(set (match_dup 3) (match_dup 5))
10283 (set (match_dup 4) (match_dup 6))]
10285 /* Swap low/high part load order on little endian, so that the result reg
10286 of the second load can be used better. */
10287 int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
10288 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10289 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10290 operands[4 - off] = gen_highpart (SImode, operands[0]);
10291 operands[6 - off] = gen_highpart (SImode, operands[1]);
10294 (define_insn_and_split "*movdi_gbr_store"
10295 [(set (match_operand:DI 0 "gbr_address_mem")
10296 (match_operand:DI 1 "register_operand"))]
10297 "TARGET_SH1 && can_create_pseudo_p ()"
10300 [(set (match_dup 3) (match_dup 5))
10301 (set (match_dup 4) (match_dup 6))]
10303 /* Swap low/high part store order on big endian, so that stores of function
10304 call results can save a reg copy. */
10305 int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
10306 operands[3 + off] = gen_lowpart (SImode, operands[0]);
10307 operands[5 + off] = gen_lowpart (SImode, operands[1]);
10308 operands[4 - off] = gen_highpart (SImode, operands[0]);
10309 operands[6 - off] = gen_highpart (SImode, operands[1]);
10312 ;; Sometimes memory accesses do not get combined with the store_gbr insn,
10313 ;; in particular when the displacements are in the range of the regular move
10314 ;; insns. Thus, in the first split pass after the combine pass we search
10315 ;; for missed opportunities and try to fix them up ourselves.
10316 ;; If an equivalent GBR address can be determined the load / store is split
10317 ;; into one of the GBR load / store patterns.
10318 ;; All of that must happen before reload (GBR address modes use R0 as the
10319 ;; other operand) and there's no point of doing it if the GBR is not
10320 ;; referenced in a function at all.
10322 [(set (match_operand:QIHISIDI 0 "register_operand")
10323 (match_operand:QIHISIDI 1 "memory_operand"))]
10324 "TARGET_SH1 && !reload_in_progress && !reload_completed
10325 && df_regs_ever_live_p (GBR_REG)"
10326 [(set (match_dup 0) (match_dup 1))]
10328 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10329 if (gbr_mem != NULL_RTX)
10330 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10336 [(set (match_operand:SI 0 "register_operand")
10337 (sign_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10338 "TARGET_SH1 && !reload_in_progress && !reload_completed
10339 && df_regs_ever_live_p (GBR_REG)"
10340 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
10342 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10343 if (gbr_mem != NULL_RTX)
10344 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10349 ;; On SH2A we've got movu.b and movu.w for doing zero-extending mem loads.
10350 ;; Split those so that a GBR load can be used.
10352 [(set (match_operand:SI 0 "register_operand")
10353 (zero_extend:SI (match_operand:QIHI 1 "memory_operand")))]
10354 "TARGET_SH2A && !reload_in_progress && !reload_completed
10355 && df_regs_ever_live_p (GBR_REG)"
10356 [(set (match_dup 2) (match_dup 1))
10357 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10359 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
10360 if (gbr_mem != NULL_RTX)
10362 operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
10363 operands[1] = replace_equiv_address (operands[1], gbr_mem);
10370 [(set (match_operand:QIHISIDI 0 "memory_operand")
10371 (match_operand:QIHISIDI 1 "register_operand"))]
10372 "TARGET_SH1 && !reload_in_progress && !reload_completed
10373 && df_regs_ever_live_p (GBR_REG)"
10374 [(set (match_dup 0) (match_dup 1))]
10376 rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
10377 if (gbr_mem != NULL_RTX)
10378 operands[0] = replace_equiv_address (operands[0], gbr_mem);
10383 ;;------------------------------------------------------------------------------
10384 ;; case instruction for switch statements.
10386 ;; Operand 0 is index
10387 ;; operand 1 is the minimum bound
10388 ;; operand 2 is the maximum bound - minimum bound + 1
10389 ;; operand 3 is CODE_LABEL for the table;
10390 ;; operand 4 is the CODE_LABEL to go to if index out of range.
10392 (define_expand "casesi"
10393 [(match_operand:SI 0 "arith_reg_operand" "")
10394 (match_operand:SI 1 "arith_reg_operand" "")
10395 (match_operand:SI 2 "arith_reg_operand" "")
10396 (match_operand 3 "" "") (match_operand 4 "" "")]
10399 rtx reg = gen_reg_rtx (SImode);
10400 rtx reg2 = gen_reg_rtx (SImode);
10401 if (TARGET_SHMEDIA)
10403 rtx reg = gen_reg_rtx (DImode);
10404 rtx reg2 = gen_reg_rtx (DImode);
10405 rtx reg3 = gen_reg_rtx (Pmode);
10406 rtx reg4 = gen_reg_rtx (Pmode);
10407 rtx reg5 = gen_reg_rtx (Pmode);
10410 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
10411 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
10412 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
10414 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
10415 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
10416 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
10417 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
10418 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
10419 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
10420 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
10421 (Pmode, operands[3])));
10422 /* Messy: can we subreg to clean this up? */
10423 if (Pmode == DImode)
10424 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
10426 load = gen_casesi_load_media (reg4,
10427 gen_rtx_SUBREG (DImode, reg3, 0),
10428 reg2, operands[3]);
10429 PUT_MODE (SET_SRC (load), Pmode);
10431 /* ??? The following add could be eliminated if we used ptrel. */
10432 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
10433 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
10437 operands[1] = copy_to_mode_reg (SImode, operands[1]);
10438 operands[2] = copy_to_mode_reg (SImode, operands[2]);
10439 /* If optimizing, casesi_worker depends on the mode of the instruction
10440 before label it 'uses' - operands[3]. */
10441 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
10443 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
10445 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
10447 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
10448 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
10449 operands[3], but to lab. We will fix this up in
10450 machine_dependent_reorg. */
10455 (define_expand "casesi_0"
10456 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
10457 (set (match_dup 4) (minus:SI (match_dup 4)
10458 (match_operand:SI 1 "arith_operand" "")))
10459 (set (reg:SI T_REG)
10460 (gtu:SI (match_dup 4)
10461 (match_operand:SI 2 "arith_reg_operand" "")))
10463 (if_then_else (ne (reg:SI T_REG)
10465 (label_ref (match_operand 3 "" ""))
10470 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
10471 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
10472 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
10474 (define_insn "casesi_worker_0"
10475 [(set (match_operand:SI 0 "register_operand" "=r,r")
10476 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
10477 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10478 (clobber (match_scratch:SI 3 "=X,1"))
10479 (clobber (match_scratch:SI 4 "=&z,z"))]
10484 [(set (match_operand:SI 0 "register_operand" "")
10485 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10486 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10487 (clobber (match_scratch:SI 3 ""))
10488 (clobber (match_scratch:SI 4 ""))]
10489 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
10490 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10491 (parallel [(set (match_dup 0)
10492 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10493 (label_ref (match_dup 2))] UNSPEC_CASESI))
10494 (clobber (match_dup 3))])
10495 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
10497 if (GET_CODE (operands[2]) == CODE_LABEL)
10498 LABEL_NUSES (operands[2])++;
10502 [(set (match_operand:SI 0 "register_operand" "")
10503 (unspec:SI [(match_operand:SI 1 "register_operand" "")
10504 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10505 (clobber (match_scratch:SI 3 ""))
10506 (clobber (match_scratch:SI 4 ""))]
10507 "TARGET_SH2 && reload_completed"
10508 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
10509 (parallel [(set (match_dup 0)
10510 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
10511 (label_ref (match_dup 2))] UNSPEC_CASESI))
10512 (clobber (match_dup 3))])]
10514 if (GET_CODE (operands[2]) == CODE_LABEL)
10515 LABEL_NUSES (operands[2])++;
10518 (define_insn "casesi_worker_1"
10519 [(set (match_operand:SI 0 "register_operand" "=r,r")
10520 (unspec:SI [(reg:SI R0_REG)
10521 (match_operand:SI 1 "register_operand" "0,r")
10522 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
10523 (clobber (match_scratch:SI 3 "=X,1"))]
10526 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10528 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10530 switch (GET_MODE (diff_vec))
10533 return "shll2 %1" "\n"
10534 " mov.l @(r0,%1),%0";
10536 return "add %1,%1" "\n"
10537 " mov.w @(r0,%1),%0";
10539 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10540 return "mov.b @(r0,%1),%0" "\n"
10543 return "mov.b @(r0,%1),%0";
10546 gcc_unreachable ();
10549 [(set_attr "length" "4")])
10551 (define_insn "casesi_worker_2"
10552 [(set (match_operand:SI 0 "register_operand" "=r,r")
10553 (unspec:SI [(reg:SI R0_REG)
10554 (match_operand:SI 1 "register_operand" "0,r")
10555 (label_ref (match_operand 2 "" ""))
10556 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
10557 (clobber (match_operand:SI 4 "" "=X,1"))]
10558 "TARGET_SH2 && reload_completed && flag_pic"
10560 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10561 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10563 switch (GET_MODE (diff_vec))
10566 return "shll2 %1" "\n"
10568 " mova %O3,r0" "\n"
10569 " mov.l @(r0,%1),%0";
10571 return "add %1,%1" "\n"
10573 " mova %O3,r0" "\n"
10574 " mov.w @(r0,%1),%0";
10576 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10577 return "add r0,%1" "\n"
10578 " mova %O3,r0" "\n"
10579 " mov.b @(r0,%1),%0" "\n"
10582 return "add r0,%1" "\n"
10583 " mova %O3,r0" "\n"
10584 " mov.b @(r0,%1),%0";
10586 gcc_unreachable ();
10589 [(set_attr "length" "8")])
10591 (define_insn "casesi_shift_media"
10592 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10593 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
10594 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
10598 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
10600 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10602 switch (GET_MODE (diff_vec))
10605 return "shlli %1, 2, %0";
10607 return "shlli %1, 1, %0";
10609 if (rtx_equal_p (operands[0], operands[1]))
10611 return "add %1, r63, %0";
10613 gcc_unreachable ();
10616 [(set_attr "type" "arith_media")])
10618 (define_insn "casesi_load_media"
10619 [(set (match_operand 0 "any_arith_reg_dest" "=r")
10620 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
10621 (match_operand:DI 2 "arith_reg_operand" "r")
10622 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
10625 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
10627 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
10629 switch (GET_MODE (diff_vec))
10632 return "ldx.l %1, %2, %0";
10635 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10636 return "ldx.uw %1, %2, %0";
10638 return "ldx.w %1, %2, %0";
10640 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
10641 return "ldx.ub %1, %2, %0";
10642 return "ldx.b %1, %2, %0";
10644 gcc_unreachable ();
10647 [(set_attr "type" "load_media")])
10649 (define_expand "simple_return"
10651 "sh_can_use_simple_return_p ()")
10653 (define_expand "return"
10655 "reload_completed && epilogue_completed"
10657 if (TARGET_SHMEDIA)
10659 emit_jump_insn (gen_return_media ());
10663 if (TARGET_SHCOMPACT
10664 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
10666 emit_jump_insn (gen_shcompact_return_tramp ());
10671 (define_insn "*<code>_i"
10673 "TARGET_SH1 && ! (TARGET_SHCOMPACT
10674 && (crtl->args.info.call_cookie
10675 & CALL_COOKIE_RET_TRAMP (1)))
10676 && reload_completed
10677 && ! sh_cfun_trap_exit_p ()"
10679 if (TARGET_SH2A && (dbr_sequence_length () == 0)
10680 && !current_function_interrupt)
10685 [(set_attr "type" "return")
10686 (set_attr "needs_delay_slot" "yes")])
10688 ;; trapa has no delay slot.
10689 (define_insn "*return_trapa"
10691 "TARGET_SH1 && !TARGET_SHCOMPACT
10692 && reload_completed"
10694 [(set_attr "type" "return")])
10696 (define_expand "shcompact_return_tramp"
10699 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10701 rtx reg = gen_rtx_REG (Pmode, R0_REG);
10703 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
10704 emit_jump_insn (gen_shcompact_return_tramp_i ());
10708 (define_insn "shcompact_return_tramp_i"
10709 [(parallel [(return) (use (reg:SI R0_REG))])]
10711 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
10713 [(set_attr "type" "jump_ind")
10714 (set_attr "needs_delay_slot" "yes")])
10716 (define_insn "return_media_i"
10717 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
10718 "TARGET_SHMEDIA && reload_completed"
10720 [(set_attr "type" "jump_media")])
10722 (define_insn "return_media_rte"
10724 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
10726 [(set_attr "type" "jump_media")])
10728 (define_expand "return_media"
10730 "TARGET_SHMEDIA && reload_completed"
10732 int tr_regno = sh_media_register_for_return ();
10735 if (current_function_interrupt)
10737 emit_jump_insn (gen_return_media_rte ());
10742 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
10744 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
10745 tr_regno = TR0_REG;
10746 tr = gen_rtx_REG (Pmode, tr_regno);
10747 emit_move_insn (tr, r18);
10750 tr = gen_rtx_REG (Pmode, tr_regno);
10752 emit_jump_insn (gen_return_media_i (tr));
10756 (define_insn "shcompact_preserve_incoming_args"
10757 [(set (match_operand:SI 0 "register_operand" "+r")
10758 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
10761 [(set_attr "length" "0")])
10763 (define_insn "shcompact_incoming_args"
10764 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
10765 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
10766 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
10767 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
10768 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
10769 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
10770 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
10771 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
10772 (set (mem:BLK (reg:SI MACL_REG))
10773 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
10774 (use (reg:SI R0_REG))
10775 (clobber (reg:SI R0_REG))
10776 (clobber (reg:SI MACL_REG))
10777 (clobber (reg:SI MACH_REG))
10778 (clobber (reg:SI PR_REG))]
10781 [(set_attr "needs_delay_slot" "yes")])
10783 (define_insn "shmedia_save_restore_regs_compact"
10784 [(set (reg:SI SP_REG)
10785 (plus:SI (reg:SI SP_REG)
10786 (match_operand:SI 0 "immediate_operand" "i")))
10787 (use (reg:SI R0_REG))
10788 (clobber (reg:SI PR_REG))]
10790 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
10791 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
10793 [(set_attr "needs_delay_slot" "yes")])
10795 (define_expand "prologue"
10799 sh_expand_prologue ();
10803 (define_expand "epilogue"
10807 sh_expand_epilogue (false);
10809 || (TARGET_SHCOMPACT
10810 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
10812 emit_jump_insn (gen_return ());
10817 (define_expand "eh_return"
10818 [(use (match_operand 0 "register_operand" ""))]
10821 rtx ra = operands[0];
10823 if (TARGET_SHMEDIA64)
10824 emit_insn (gen_eh_set_ra_di (ra));
10826 emit_insn (gen_eh_set_ra_si (ra));
10831 ;; Clobber the return address on the stack. We can't expand this
10832 ;; until we know where it will be put in the stack frame.
10834 (define_insn "eh_set_ra_si"
10835 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
10837 (clobber (match_scratch:SI 1 "=&r"))]
10838 "! TARGET_SHMEDIA64"
10841 (define_insn "eh_set_ra_di"
10842 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
10844 (clobber (match_scratch:DI 1 "=&r"))]
10849 [(unspec_volatile [(match_operand 0 "register_operand" "")]
10851 (clobber (match_scratch 1 ""))]
10855 sh_set_return_address (operands[0], operands[1]);
10859 (define_insn "blockage"
10860 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10863 [(set_attr "length" "0")])
10865 ;; Define movml instructions for SH2A target. Currently they are
10866 ;; used to push and pop all banked registers only.
10868 (define_insn "movml_push_banked"
10869 [(set (match_operand:SI 0 "register_operand" "=r")
10870 (plus (match_dup 0) (const_int -32)))
10871 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
10872 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
10873 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
10874 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
10875 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
10876 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
10877 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
10878 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
10879 "TARGET_SH2A && REGNO (operands[0]) == 15"
10881 [(set_attr "in_delay_slot" "no")])
10883 (define_insn "movml_pop_banked"
10884 [(set (match_operand:SI 0 "register_operand" "=r")
10885 (plus (match_dup 0) (const_int 32)))
10886 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
10887 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
10888 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
10889 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
10890 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
10891 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
10892 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
10893 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
10894 "TARGET_SH2A && REGNO (operands[0]) == 15"
10896 [(set_attr "in_delay_slot" "no")])
10898 ;; ------------------------------------------------------------------------
10899 ;; Scc instructions
10900 ;; ------------------------------------------------------------------------
10902 (define_insn "movt"
10903 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10904 (match_operand:SI 1 "t_reg_operand"))]
10907 [(set_attr "type" "arith")])
10909 (define_insn "movrt"
10910 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10911 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
10914 [(set_attr "type" "arith")])
10916 (define_expand "cstore4_media"
10917 [(set (match_operand:SI 0 "register_operand" "=r")
10918 (match_operator:SI 1 "sh_float_comparison_operator"
10919 [(match_operand 2 "logical_operand" "")
10920 (match_operand 3 "cmp_operand" "")]))]
10923 enum machine_mode mode = GET_MODE (operands[2]);
10924 enum rtx_code code = GET_CODE (operands[1]);
10926 if (mode == VOIDmode)
10927 mode = GET_MODE (operands[3]);
10928 if (operands[2] == const0_rtx)
10930 if (code == EQ || code == NE)
10931 operands[2] = operands[3], operands[3] = const0_rtx;
10934 operands[2] = force_reg (mode, operands[2]);
10935 if (operands[3] != const0_rtx)
10936 operands[3] = force_reg (mode, operands[3]);
10942 swap = invert = !FLOAT_MODE_P (mode);
10947 swap = FLOAT_MODE_P (mode), invert = !swap;
10952 swap = true, invert = false;
10959 swap = invert = false;
10963 swap = invert = true;
10967 gcc_unreachable ();
10972 rtx tem = operands[2];
10973 operands[2] = operands[3];
10975 code = swap_condition (code);
10980 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
10981 code = reverse_condition (code);
10982 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
10983 emit_insn (gen_cstore4_media (tem, operands[1],
10984 operands[2], operands[3]));
10987 operands[3] = const0_rtx;
10990 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
10993 (define_expand "cstoresi4"
10994 [(set (match_operand:SI 0 "register_operand" "=r")
10995 (match_operator:SI 1 "comparison_operator"
10996 [(match_operand:SI 2 "cmpsi_operand" "")
10997 (match_operand:SI 3 "arith_operand" "")]))]
10998 "TARGET_SH1 || TARGET_SHMEDIA"
11000 if (TARGET_SHMEDIA)
11002 emit_insn (gen_cstore4_media (operands[0], operands[1],
11003 operands[2], operands[3]));
11007 if (sh_expand_t_scc (operands))
11010 if (! currently_expanding_to_rtl)
11013 sh_emit_compare_and_set (operands, SImode);
11017 (define_expand "cstoredi4"
11018 [(set (match_operand:SI 0 "register_operand" "=r")
11019 (match_operator:SI 1 "comparison_operator"
11020 [(match_operand:DI 2 "arith_operand" "")
11021 (match_operand:DI 3 "arith_operand" "")]))]
11022 "TARGET_SH2 || TARGET_SHMEDIA"
11024 if (TARGET_SHMEDIA)
11026 emit_insn (gen_cstore4_media (operands[0], operands[1],
11027 operands[2], operands[3]));
11031 if (sh_expand_t_scc (operands))
11034 if (! currently_expanding_to_rtl)
11037 sh_emit_compare_and_set (operands, DImode);
11041 ;; Move the complement of the T reg to a reg.
11042 ;; On SH2A the movrt insn can be used.
11043 ;; On anything else than SH2A this has to be done with multiple instructions.
11044 ;; One obvious way would be:
11049 ;; However, this puts pressure on r0 in most cases and thus the following is
11055 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
11056 ;; becomes a one instruction operation. Moreover, care must be taken that
11057 ;; the insn can still be combined with inverted compare and branch code
11058 ;; around it. On the other hand, if a function returns the complement of
11059 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
11060 ;; lead to better code.
11062 (define_expand "movnegt"
11063 [(set (match_operand:SI 0 "arith_reg_dest" "")
11064 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))]
11068 emit_insn (gen_movrt (operands[0], operands[1]));
11071 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
11072 emit_insn (gen_movrt_negc (operands[0], operands[1], val));
11077 (define_insn "movrt_negc"
11078 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11079 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11080 (set (reg:SI T_REG) (const_int 1))
11081 (use (match_operand:SI 2 "arith_reg_operand" "r"))]
11084 [(set_attr "type" "arith")])
11086 ;; The -1 constant will not be CSE-ed for the *movrt_negc pattern, but the
11087 ;; pattern can be used by the combine pass. Using a scratch reg for the
11088 ;; -1 constant results in slightly better register allocations compared to
11089 ;; generating a pseudo reg before reload.
11090 (define_insn_and_split "*movrt_negc"
11091 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11092 (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
11093 (clobber (match_scratch:SI 2 "=r"))
11094 (clobber (reg:SI T_REG))]
11095 "TARGET_SH1 && ! TARGET_SH2A"
11097 "&& reload_completed"
11098 [(set (match_dup 2) (const_int -1))
11100 [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
11101 (set (reg:SI T_REG) (const_int 1))
11102 (use (match_dup 2))])])
11104 ;; Store the negated T bit in a reg using r0 and xor. This one doesn't
11105 ;; clobber the T bit, which is useful when storing the T bit and the
11106 ;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
11107 ;; Usually we don't want this insn to be matched, except for cases where the
11108 ;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
11109 (define_insn_and_split "movrt_xor"
11110 [(set (match_operand:SI 0 "arith_reg_dest" "=z")
11111 (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
11112 (use (reg:SI T_REG))]
11113 "TARGET_SH1 && !TARGET_SH2A"
11115 "&& reload_completed"
11116 [(set (match_dup 0) (reg:SI T_REG))
11117 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
11119 ;; Store the T bit and the negated T bit in two regs in parallel. There is
11120 ;; no real insn to do that, but specifying this pattern will give combine
11121 ;; some opportunities.
11122 (define_insn_and_split "*movt_movrt"
11123 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11124 (match_operand:SI 1 "negt_reg_operand"))
11125 (set (match_operand:SI 2 "arith_reg_dest")
11126 (match_operand:SI 3 "t_reg_operand"))])]
11132 rtx i = TARGET_SH2A
11133 ? gen_movrt (operands[0], get_t_reg_rtx ())
11134 : gen_movrt_xor (operands[0], get_t_reg_rtx ());
11137 emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
11141 (define_insn_and_split "*movt_movrt"
11142 [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
11143 (match_operand:SI 1 "t_reg_operand"))
11144 (set (match_operand:SI 2 "arith_reg_dest")
11145 (match_operand:SI 3 "negt_reg_operand"))])]
11149 [(parallel [(set (match_dup 2) (match_dup 3))
11150 (set (match_dup 0) (match_dup 1))])])
11152 ;; Use negc to store the T bit in a MSB of a reg in the following way:
11153 ;; T = 1: 0x80000000 -> reg
11154 ;; T = 0: 0x7FFFFFFF -> reg
11155 ;; This works because 0 - 0x80000000 = 0x80000000.
11156 (define_insn_and_split "*mov_t_msb_neg"
11157 [(set (match_operand:SI 0 "arith_reg_dest")
11158 (minus:SI (const_int -2147483648) ;; 0x80000000
11159 (match_operand 1 "t_reg_operand")))
11160 (clobber (reg:SI T_REG))]
11163 "&& can_create_pseudo_p ()"
11164 [(set (match_dup 2) (const_int -2147483648))
11165 (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
11167 (clobber (reg:SI T_REG))])]
11169 operands[2] = gen_reg_rtx (SImode);
11172 ;; These are essentially the same as above, but with the inverted T bit.
11173 ;; Combine recognizes the split patterns, but does not take them sometimes
11174 ;; if the T_REG clobber is specified. Instead it tries to split out the
11175 ;; T bit negation. Since these splits are supposed to be taken only by
11176 ;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
11179 [(set (match_operand:SI 0 "arith_reg_dest")
11180 (plus:SI (match_operand 1 "negt_reg_operand")
11181 (const_int 2147483647)))] ;; 0x7fffffff
11182 "TARGET_SH1 && can_create_pseudo_p ()"
11183 [(parallel [(set (match_dup 0)
11184 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11185 (clobber (reg:SI T_REG))])])
11188 [(set (match_operand:SI 0 "arith_reg_dest")
11189 (if_then_else:SI (match_operand 1 "t_reg_operand")
11190 (const_int 2147483647) ;; 0x7fffffff
11191 (const_int -2147483648)))] ;; 0x80000000
11192 "TARGET_SH1 && can_create_pseudo_p ()"
11193 [(parallel [(set (match_dup 0)
11194 (minus:SI (const_int -2147483648) (reg:SI T_REG)))
11195 (clobber (reg:SI T_REG))])])
11197 ;; The *negnegt pattern helps the combine pass to figure out how to fold
11198 ;; an explicit double T bit negation.
11199 (define_insn_and_split "*negnegt"
11200 [(set (reg:SI T_REG)
11201 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
11207 ;; Store T bit as all zeros or ones in a reg.
11208 (define_insn "mov_neg_si_t"
11209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11210 (neg:SI (match_operand 1 "t_reg_operand" "")))]
11213 [(set_attr "type" "arith")])
11215 ;; Store negated T bit as all zeros or ones in a reg.
11216 ;; Use the following sequence:
11217 ;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
11218 ;; not Rn,Rn ! Rn = 0 - Rn
11220 [(set (match_operand:SI 0 "arith_reg_dest" "")
11221 (neg:SI (match_operand 1 "negt_reg_operand" "")))]
11223 [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
11224 (set (match_dup 0) (not:SI (match_dup 0)))])
11226 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
11227 (define_insn_and_split "*movtt"
11228 [(set (reg:SI T_REG)
11229 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
11235 (define_insn_and_split "nott"
11236 [(set (reg:SI T_REG)
11237 (xor:SI (match_operand:SI 0 "t_reg_operand" "") (const_int 1)))]
11240 gcc_assert (TARGET_SH2A);
11243 "! TARGET_SH2A && can_create_pseudo_p ()"
11244 [(set (match_dup 0) (reg:SI T_REG))
11245 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
11247 operands[0] = gen_reg_rtx (SImode);
11250 ;; Store T bit as MSB in a reg.
11251 ;; T = 0: 0x00000000 -> reg
11252 ;; T = 1: 0x80000000 -> reg
11253 (define_insn_and_split "*movt_msb"
11254 [(set (match_operand:SI 0 "arith_reg_dest")
11255 (mult:SI (match_operand:SI 1 "t_reg_operand")
11256 (const_int -2147483648))) ;; 0xffffffff80000000
11257 (clobber (reg:SI T_REG))]
11261 [(set (match_dup 0) (ashift:SI (reg:SI T_REG) (const_int 31)))])
11263 ;; Store inverted T bit as MSB in a reg.
11264 ;; T = 0: 0x80000000 -> reg
11265 ;; T = 1: 0x00000000 -> reg
11266 ;; On SH2A we can get away without clobbering the T_REG.
11267 (define_insn_and_split "*negt_msb"
11268 [(set (match_operand:SI 0 "arith_reg_dest")
11269 (match_operand:SI 1 "negt_reg_shl31_operand"))]
11272 "&& can_create_pseudo_p ()"
11275 rtx tmp = gen_reg_rtx (SImode);
11276 emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
11277 emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
11281 (define_insn_and_split "*negt_msb"
11282 [(set (match_operand:SI 0 "arith_reg_dest")
11283 (match_operand:SI 1 "negt_reg_shl31_operand"))
11284 (clobber (reg:SI T_REG))]
11285 "TARGET_SH1 && !TARGET_SH2A"
11287 "&& can_create_pseudo_p ()"
11290 rtx tmp = gen_reg_rtx (SImode);
11291 emit_move_insn (tmp, get_t_reg_rtx ());
11292 emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
11293 emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
11297 ;; The *cset_zero patterns convert optimizations such as
11298 ;; "if (test) x = 0;" to "x &= -(test == 0);"
11299 ;; back to conditional branch sequences if zero-displacement branches
11301 ;; FIXME: These patterns can be removed when conditional execution patterns
11302 ;; are implemented, since ifcvt will not perform these optimizations if
11303 ;; conditional execution is supported.
11304 (define_insn "*cset_zero"
11305 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11306 (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
11308 (match_operand:SI 2 "arith_reg_operand" "0")))]
11309 "TARGET_SH1 && TARGET_ZDCBRANCH"
11311 return "bf 0f" "\n"
11315 [(set_attr "type" "arith") ;; poor approximation
11316 (set_attr "length" "4")])
11318 (define_insn "*cset_zero"
11319 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
11320 (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
11321 (match_operand:SI 2 "arith_reg_operand" "0")
11323 "TARGET_SH1 && TARGET_ZDCBRANCH"
11325 return "bt 0f" "\n"
11329 [(set_attr "type" "arith") ;; poor approximation
11330 (set_attr "length" "4")])
11332 (define_expand "cstoresf4"
11333 [(set (match_operand:SI 0 "register_operand" "=r")
11334 (match_operator:SI 1 "sh_float_comparison_operator"
11335 [(match_operand:SF 2 "arith_operand" "")
11336 (match_operand:SF 3 "arith_operand" "")]))]
11337 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11339 if (TARGET_SHMEDIA)
11341 emit_insn (gen_cstore4_media (operands[0], operands[1],
11342 operands[2], operands[3]));
11346 if (! currently_expanding_to_rtl)
11349 sh_emit_compare_and_set (operands, SFmode);
11353 (define_expand "cstoredf4"
11354 [(set (match_operand:SI 0 "register_operand" "=r")
11355 (match_operator:SI 1 "sh_float_comparison_operator"
11356 [(match_operand:DF 2 "arith_operand" "")
11357 (match_operand:DF 3 "arith_operand" "")]))]
11358 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11360 if (TARGET_SHMEDIA)
11362 emit_insn (gen_cstore4_media (operands[0], operands[1],
11363 operands[2], operands[3]));
11367 if (! currently_expanding_to_rtl)
11370 sh_emit_compare_and_set (operands, DFmode);
11374 ;; -------------------------------------------------------------------------
11375 ;; Instructions to cope with inline literal tables
11376 ;; -------------------------------------------------------------------------
11378 ; 2 byte integer in line
11380 (define_insn "consttable_2"
11381 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11382 (match_operand 1 "" "")]
11386 if (operands[1] != const0_rtx)
11387 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
11390 [(set_attr "length" "2")
11391 (set_attr "in_delay_slot" "no")])
11393 ; 4 byte integer in line
11395 (define_insn "consttable_4"
11396 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11397 (match_operand 1 "" "")]
11401 if (operands[1] != const0_rtx)
11403 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
11404 mark_symbol_refs_as_used (operands[0]);
11408 [(set_attr "length" "4")
11409 (set_attr "in_delay_slot" "no")])
11411 ; 8 byte integer in line
11413 (define_insn "consttable_8"
11414 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
11415 (match_operand 1 "" "")]
11419 if (operands[1] != const0_rtx)
11420 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
11423 [(set_attr "length" "8")
11424 (set_attr "in_delay_slot" "no")])
11426 ; 4 byte floating point
11428 (define_insn "consttable_sf"
11429 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
11430 (match_operand 1 "" "")]
11434 if (operands[1] != const0_rtx)
11437 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11438 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
11442 [(set_attr "length" "4")
11443 (set_attr "in_delay_slot" "no")])
11445 ; 8 byte floating point
11447 (define_insn "consttable_df"
11448 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
11449 (match_operand 1 "" "")]
11453 if (operands[1] != const0_rtx)
11456 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
11457 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
11461 [(set_attr "length" "8")
11462 (set_attr "in_delay_slot" "no")])
11464 ;; Alignment is needed for some constant tables; it may also be added for
11465 ;; Instructions at the start of loops, or after unconditional branches.
11466 ;; ??? We would get more accurate lengths if we did instruction
11467 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
11468 ;; here is too conservative.
11470 ; align to a two byte boundary
11472 (define_expand "align_2"
11473 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
11477 ; align to a four byte boundary
11478 ;; align_4 and align_log are instructions for the starts of loops, or
11479 ;; after unconditional branches, which may take up extra room.
11481 (define_expand "align_4"
11482 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
11486 ; align to a cache line boundary
11488 (define_insn "align_log"
11489 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
11492 [(set_attr "length" "0")
11493 (set_attr "in_delay_slot" "no")])
11495 ; emitted at the end of the literal table, used to emit the
11496 ; 32bit branch labels if needed.
11498 (define_insn "consttable_end"
11499 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
11502 return output_jump_label_table ();
11504 [(set_attr "in_delay_slot" "no")])
11506 ; emitted at the end of the window in the literal table.
11508 (define_insn "consttable_window_end"
11509 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
11512 [(set_attr "length" "0")
11513 (set_attr "in_delay_slot" "no")])
11515 ;; -------------------------------------------------------------------------
11517 ;; -------------------------------------------------------------------------
11519 ;; String/block move insn.
11521 (define_expand "movmemsi"
11522 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
11523 (mem:BLK (match_operand:BLK 1 "" "")))
11524 (use (match_operand:SI 2 "nonmemory_operand" ""))
11525 (use (match_operand:SI 3 "immediate_operand" ""))
11526 (clobber (reg:SI PR_REG))
11527 (clobber (reg:SI R4_REG))
11528 (clobber (reg:SI R5_REG))
11529 (clobber (reg:SI R0_REG))])]
11530 "TARGET_SH1 && ! TARGET_SH5"
11532 if(expand_block_move (operands))
11537 (define_insn "block_move_real"
11538 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11539 (mem:BLK (reg:SI R5_REG)))
11540 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11541 (clobber (reg:SI PR_REG))
11542 (clobber (reg:SI R0_REG))])]
11543 "TARGET_SH1 && ! TARGET_HARD_SH4"
11545 [(set_attr "type" "sfunc")
11546 (set_attr "needs_delay_slot" "yes")])
11548 (define_insn "block_lump_real"
11549 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11550 (mem:BLK (reg:SI R5_REG)))
11551 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11552 (use (reg:SI R6_REG))
11553 (clobber (reg:SI PR_REG))
11554 (clobber (reg:SI T_REG))
11555 (clobber (reg:SI R4_REG))
11556 (clobber (reg:SI R5_REG))
11557 (clobber (reg:SI R6_REG))
11558 (clobber (reg:SI R0_REG))])]
11559 "TARGET_SH1 && ! TARGET_HARD_SH4"
11561 [(set_attr "type" "sfunc")
11562 (set_attr "needs_delay_slot" "yes")])
11564 (define_insn "block_move_real_i4"
11565 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11566 (mem:BLK (reg:SI R5_REG)))
11567 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11568 (clobber (reg:SI PR_REG))
11569 (clobber (reg:SI R0_REG))
11570 (clobber (reg:SI R1_REG))
11571 (clobber (reg:SI R2_REG))])]
11574 [(set_attr "type" "sfunc")
11575 (set_attr "needs_delay_slot" "yes")])
11577 (define_insn "block_lump_real_i4"
11578 [(parallel [(set (mem:BLK (reg:SI R4_REG))
11579 (mem:BLK (reg:SI R5_REG)))
11580 (use (match_operand:SI 0 "arith_reg_operand" "r"))
11581 (use (reg:SI R6_REG))
11582 (clobber (reg:SI PR_REG))
11583 (clobber (reg:SI T_REG))
11584 (clobber (reg:SI R4_REG))
11585 (clobber (reg:SI R5_REG))
11586 (clobber (reg:SI R6_REG))
11587 (clobber (reg:SI R0_REG))
11588 (clobber (reg:SI R1_REG))
11589 (clobber (reg:SI R2_REG))
11590 (clobber (reg:SI R3_REG))])]
11593 [(set_attr "type" "sfunc")
11594 (set_attr "needs_delay_slot" "yes")])
11596 ;; -------------------------------------------------------------------------
11597 ;; Floating point instructions.
11598 ;; -------------------------------------------------------------------------
11600 ;; ??? All patterns should have a type attribute.
11602 (define_expand "movpsi"
11603 [(set (match_operand:PSI 0 "register_operand" "")
11604 (match_operand:PSI 1 "general_movsrc_operand" ""))]
11605 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11608 ;; The c / m alternative is a fake to guide reload to load directly into
11609 ;; fpscr, since reload doesn't know how to use post-increment.
11610 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
11611 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
11612 ;; predicate after reload.
11613 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
11614 ;; like a mac -> gpr move.
11615 (define_insn "fpu_switch"
11616 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
11617 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
11619 && (! reload_completed
11620 || true_regnum (operands[0]) != FPSCR_REG
11621 || !MEM_P (operands[1])
11622 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
11624 ! precision stays the same
11633 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
11634 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
11637 [(set (reg:PSI FPSCR_REG)
11638 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11639 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
11642 rtx fpscr, mem, new_insn;
11644 fpscr = SET_DEST (PATTERN (curr_insn));
11645 mem = SET_SRC (PATTERN (curr_insn));
11646 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11648 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11649 add_reg_note (new_insn, REG_INC, operands[0]);
11654 [(set (reg:PSI FPSCR_REG)
11655 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
11656 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
11657 && (flag_peephole2 ? epilogue_completed : reload_completed)"
11660 rtx fpscr, mem, new_insn;
11662 fpscr = SET_DEST (PATTERN (curr_insn));
11663 mem = SET_SRC (PATTERN (curr_insn));
11664 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
11666 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
11667 add_reg_note (new_insn, REG_INC, operands[0]);
11669 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
11670 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
11674 ;; ??? This uses the fp unit, but has no type indicating that.
11675 ;; If we did that, this would either give a bogus latency or introduce
11676 ;; a bogus FIFO constraint.
11677 ;; Since this insn is currently only used for prologues/epilogues,
11678 ;; it is probably best to claim no function unit, which matches the
11679 ;; current setting.
11680 (define_insn "toggle_sz"
11681 [(set (reg:PSI FPSCR_REG)
11682 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
11683 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11685 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
11687 ;; There's no way we can use it today, since optimize mode switching
11688 ;; doesn't enable us to know from which mode we're switching to the
11689 ;; mode it requests, to tell whether we can use a relative mode switch
11690 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
11692 (define_insn "toggle_pr"
11693 [(set (reg:PSI FPSCR_REG)
11694 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
11695 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
11697 [(set_attr "type" "fpscr_toggle")])
11699 (define_expand "addsf3"
11700 [(set (match_operand:SF 0 "arith_reg_operand" "")
11701 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
11702 (match_operand:SF 2 "arith_reg_operand" "")))]
11703 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11707 expand_sf_binop (&gen_addsf3_i, operands);
11712 (define_insn "*addsf3_media"
11713 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11714 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
11715 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11716 "TARGET_SHMEDIA_FPU"
11717 "fadd.s %1, %2, %0"
11718 [(set_attr "type" "fparith_media")])
11720 (define_insn_and_split "unary_sf_op"
11721 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11726 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
11727 (match_operator:SF 2 "unary_float_operator"
11728 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11729 (parallel [(match_operand 4
11730 "const_int_operand" "n")]))]))
11731 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
11732 "TARGET_SHMEDIA_FPU"
11734 "TARGET_SHMEDIA_FPU && reload_completed"
11735 [(set (match_dup 5) (match_dup 6))]
11737 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11738 rtx op1 = gen_rtx_REG (SFmode,
11739 (true_regnum (operands[1])
11740 + (INTVAL (operands[4]) ^ endian)));
11742 operands[7] = gen_rtx_REG (SFmode,
11743 (true_regnum (operands[0])
11744 + (INTVAL (operands[3]) ^ endian)));
11745 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
11747 [(set_attr "type" "fparith_media")])
11749 (define_insn_and_split "binary_sf_op0"
11750 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11752 (match_operator:SF 3 "binary_float_operator"
11753 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11754 (parallel [(const_int 0)]))
11755 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11756 (parallel [(const_int 0)]))])
11759 (parallel [(const_int 1)]))))]
11760 "TARGET_SHMEDIA_FPU"
11762 "&& reload_completed"
11763 [(set (match_dup 4) (match_dup 5))]
11765 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11766 rtx op1 = gen_rtx_REG (SFmode,
11767 true_regnum (operands[1]) + endian);
11768 rtx op2 = gen_rtx_REG (SFmode,
11769 true_regnum (operands[2]) + endian);
11771 operands[4] = gen_rtx_REG (SFmode,
11772 true_regnum (operands[0]) + endian);
11773 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
11775 [(set_attr "type" "fparith_media")])
11777 (define_insn_and_split "binary_sf_op1"
11778 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11782 (parallel [(const_int 0)]))
11783 (match_operator:SF 3 "binary_float_operator"
11784 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
11785 (parallel [(const_int 1)]))
11786 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
11787 (parallel [(const_int 1)]))])))]
11788 "TARGET_SHMEDIA_FPU"
11790 "&& reload_completed"
11791 [(set (match_dup 4) (match_dup 5))]
11793 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
11794 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
11795 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
11797 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
11798 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
11800 [(set_attr "type" "fparith_media")])
11802 (define_insn "addsf3_i"
11803 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11804 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
11805 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
11806 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11809 [(set_attr "type" "fp")
11810 (set_attr "fp_mode" "single")])
11812 (define_expand "subsf3"
11813 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11814 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
11815 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
11816 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11820 expand_sf_binop (&gen_subsf3_i, operands);
11825 (define_insn "*subsf3_media"
11826 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11827 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
11828 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11829 "TARGET_SHMEDIA_FPU"
11830 "fsub.s %1, %2, %0"
11831 [(set_attr "type" "fparith_media")])
11833 (define_insn "subsf3_i"
11834 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11835 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
11836 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
11837 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11840 [(set_attr "type" "fp")
11841 (set_attr "fp_mode" "single")])
11843 (define_expand "mulsf3"
11844 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11845 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
11846 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
11847 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11851 emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2],
11852 get_fpscr_rtx ()));
11857 (define_insn "*mulsf3_media"
11858 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11859 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
11860 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11861 "TARGET_SHMEDIA_FPU"
11862 "fmul.s %1, %2, %0"
11863 [(set_attr "type" "fparith_media")])
11865 (define_insn "mulsf3_i"
11866 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11867 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
11868 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
11869 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11872 [(set_attr "type" "fp")
11873 (set_attr "fp_mode" "single")])
11875 ;; FMA (fused multiply-add) patterns
11876 (define_expand "fmasf4"
11877 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11878 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
11879 (match_operand:SF 2 "fp_arith_reg_operand" "")
11880 (match_operand:SF 3 "fp_arith_reg_operand" "")))]
11881 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11885 emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
11886 operands[3], get_fpscr_rtx ()));
11891 (define_insn "fmasf4_i"
11892 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11893 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
11894 (match_operand:SF 2 "fp_arith_reg_operand" "f")
11895 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
11896 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
11899 [(set_attr "type" "fp")
11900 (set_attr "fp_mode" "single")])
11902 (define_insn "fmasf4_media"
11903 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11904 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
11905 (match_operand:SF 2 "fp_arith_reg_operand" "f")
11906 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
11907 "TARGET_SHMEDIA_FPU"
11908 "fmac.s %1, %2, %0"
11909 [(set_attr "type" "fparith_media")])
11911 (define_expand "divsf3"
11912 [(set (match_operand:SF 0 "arith_reg_operand" "")
11913 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
11914 (match_operand:SF 2 "arith_reg_operand" "")))]
11915 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11919 expand_sf_binop (&gen_divsf3_i, operands);
11924 (define_insn "*divsf3_media"
11925 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11926 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
11927 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11928 "TARGET_SHMEDIA_FPU"
11929 "fdiv.s %1, %2, %0"
11930 [(set_attr "type" "fdiv_media")])
11932 (define_insn "divsf3_i"
11933 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
11934 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
11935 (match_operand:SF 2 "arith_reg_operand" "f")))
11936 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11939 [(set_attr "type" "fdiv")
11940 (set_attr "fp_mode" "single")])
11942 (define_insn "floatdisf2"
11943 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11944 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11945 "TARGET_SHMEDIA_FPU"
11947 [(set_attr "type" "fpconv_media")])
11949 (define_expand "floatsisf2"
11950 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11951 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
11952 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11954 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
11956 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
11961 (define_insn "*floatsisf2_media"
11962 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11963 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11964 "TARGET_SHMEDIA_FPU"
11966 [(set_attr "type" "fpconv_media")])
11968 (define_insn "floatsisf2_i4"
11969 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11970 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
11971 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11972 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
11974 [(set_attr "type" "fp")
11975 (set_attr "fp_mode" "single")])
11977 (define_insn "*floatsisf2_ie"
11978 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11979 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
11980 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
11982 [(set_attr "type" "fp")])
11984 (define_insn "fix_truncsfdi2"
11985 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11986 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11987 "TARGET_SHMEDIA_FPU"
11989 [(set_attr "type" "fpconv_media")])
11991 (define_expand "fix_truncsfsi2"
11992 [(set (match_operand:SI 0 "fpul_operand" "=y")
11993 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11994 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11996 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
11998 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
12003 (define_insn "*fix_truncsfsi2_media"
12004 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12005 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12006 "TARGET_SHMEDIA_FPU"
12008 [(set_attr "type" "fpconv_media")])
12010 (define_insn "fix_truncsfsi2_i4"
12011 [(set (match_operand:SI 0 "fpul_operand" "=y")
12012 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12013 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12014 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12016 [(set_attr "type" "ftrc_s")
12017 (set_attr "fp_mode" "single")])
12019 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
12020 ;; fix_truncsfsi2_i4.
12021 ;; (define_insn "fix_truncsfsi2_i4_2"
12022 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12023 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12024 ;; (use (reg:PSI FPSCR_REG))
12025 ;; (clobber (reg:SI FPUL_REG))]
12028 ;; [(set_attr "length" "4")
12029 ;; (set_attr "fp_mode" "single")])
12032 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12033 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
12034 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12035 ;; (clobber (reg:SI FPUL_REG))]
12037 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12038 ;; (use (match_dup 2))])
12039 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
12041 (define_insn "*fixsfsi"
12042 [(set (match_operand:SI 0 "fpul_operand" "=y")
12043 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12044 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12046 [(set_attr "type" "fp")])
12048 (define_insn "cmpgtsf_t"
12049 [(set (reg:SI T_REG)
12050 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12051 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12052 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12054 [(set_attr "type" "fp_cmp")
12055 (set_attr "fp_mode" "single")])
12057 (define_insn "cmpeqsf_t"
12058 [(set (reg:SI T_REG)
12059 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12060 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12061 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12063 [(set_attr "type" "fp_cmp")
12064 (set_attr "fp_mode" "single")])
12066 (define_insn "ieee_ccmpeqsf_t"
12067 [(set (reg:SI T_REG)
12068 (ior:SI (reg:SI T_REG)
12069 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12070 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
12071 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12073 return output_ieee_ccmpeq (insn, operands);
12075 [(set_attr "length" "4")])
12078 (define_insn "cmpgtsf_t_i4"
12079 [(set (reg:SI T_REG)
12080 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12081 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12082 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12083 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12085 [(set_attr "type" "fp_cmp")
12086 (set_attr "fp_mode" "single")])
12088 (define_insn "cmpeqsf_t_i4"
12089 [(set (reg:SI T_REG)
12090 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12091 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
12092 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12093 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
12095 [(set_attr "type" "fp_cmp")
12096 (set_attr "fp_mode" "single")])
12098 (define_insn "*ieee_ccmpeqsf_t_4"
12099 [(set (reg:SI T_REG)
12100 (ior:SI (reg:SI T_REG)
12101 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
12102 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
12103 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12104 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
12106 return output_ieee_ccmpeq (insn, operands);
12108 [(set_attr "length" "4")
12109 (set_attr "fp_mode" "single")])
12111 (define_insn "cmpeqsf_media"
12112 [(set (match_operand:SI 0 "register_operand" "=r")
12113 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12114 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12115 "TARGET_SHMEDIA_FPU"
12116 "fcmpeq.s %1, %2, %0"
12117 [(set_attr "type" "fcmp_media")])
12119 (define_insn "cmpgtsf_media"
12120 [(set (match_operand:SI 0 "register_operand" "=r")
12121 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12122 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12123 "TARGET_SHMEDIA_FPU"
12124 "fcmpgt.s %1, %2, %0"
12125 [(set_attr "type" "fcmp_media")])
12127 (define_insn "cmpgesf_media"
12128 [(set (match_operand:SI 0 "register_operand" "=r")
12129 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12130 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12131 "TARGET_SHMEDIA_FPU"
12132 "fcmpge.s %1, %2, %0"
12133 [(set_attr "type" "fcmp_media")])
12135 (define_insn "cmpunsf_media"
12136 [(set (match_operand:SI 0 "register_operand" "=r")
12137 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
12138 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
12139 "TARGET_SHMEDIA_FPU"
12140 "fcmpun.s %1, %2, %0"
12141 [(set_attr "type" "fcmp_media")])
12143 (define_expand "cbranchsf4"
12145 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12146 [(match_operand:SF 1 "arith_operand" "")
12147 (match_operand:SF 2 "arith_operand" "")])
12148 (match_operand 3 "" "")
12150 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12152 if (TARGET_SHMEDIA)
12153 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12156 sh_emit_compare_and_branch (operands, SFmode);
12160 (define_expand "negsf2"
12161 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12162 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12163 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12167 expand_sf_unop (&gen_negsf2_i, operands);
12172 (define_insn "*negsf2_media"
12173 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12174 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12175 "TARGET_SHMEDIA_FPU"
12177 [(set_attr "type" "fmove_media")])
12179 (define_insn "negsf2_i"
12180 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12181 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12182 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12185 [(set_attr "type" "fmove")
12186 (set_attr "fp_mode" "single")])
12188 (define_expand "sqrtsf2"
12189 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12190 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12191 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
12195 expand_sf_unop (&gen_sqrtsf2_i, operands);
12200 (define_insn "*sqrtsf2_media"
12201 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12202 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12203 "TARGET_SHMEDIA_FPU"
12205 [(set_attr "type" "fdiv_media")])
12207 (define_insn "sqrtsf2_i"
12208 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12209 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12210 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12213 [(set_attr "type" "fdiv")
12214 (set_attr "fp_mode" "single")])
12216 (define_insn "rsqrtsf2"
12217 [(set (match_operand:SF 0 "register_operand" "=f")
12218 (div:SF (match_operand:SF 1 "immediate_operand" "i")
12219 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
12220 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12221 "TARGET_FPU_ANY && TARGET_FSRRA
12222 && operands[1] == CONST1_RTX (SFmode)"
12224 [(set_attr "type" "fsrra")
12225 (set_attr "fp_mode" "single")])
12227 ;; When the sincos pattern is defined, the builtin functions sin and cos
12228 ;; will be expanded to the sincos pattern and one of the output values will
12230 (define_expand "sincossf3"
12231 [(set (match_operand:SF 0 "nonimmediate_operand" "")
12232 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand" "")]
12234 (set (match_operand:SF 1 "nonimmediate_operand" "")
12235 (unspec:SF [(match_dup 2)] UNSPEC_FCOSA))]
12236 "TARGET_FPU_ANY && TARGET_FSCA"
12238 rtx scaled = gen_reg_rtx (SFmode);
12239 rtx truncated = gen_reg_rtx (SImode);
12240 rtx fsca = gen_reg_rtx (V2SFmode);
12241 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
12243 emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
12244 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
12245 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
12246 get_fpscr_rtx ()));
12248 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
12249 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 4));
12253 (define_insn_and_split "fsca"
12254 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
12256 (unspec:SF [(mult:SF
12257 (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
12258 (match_operand:SF 2 "fsca_scale_factor" "i"))
12260 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
12262 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12263 "TARGET_FPU_ANY && TARGET_FSCA"
12265 "&& !fpul_operand (operands[1], SImode)"
12268 /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
12269 to a simple reg, otherwise reload will have trouble reloading the
12270 pseudo into fpul. */
12271 rtx x = XEXP (operands[1], 0);
12272 while (x != NULL_RTX && !fpul_operand (x, SImode))
12274 gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
12278 gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
12279 emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
12282 [(set_attr "type" "fsca")
12283 (set_attr "fp_mode" "single")])
12285 (define_expand "abssf2"
12286 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
12287 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
12288 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
12292 expand_sf_unop (&gen_abssf2_i, operands);
12297 (define_insn "*abssf2_media"
12298 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12299 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12300 "TARGET_SHMEDIA_FPU"
12302 [(set_attr "type" "fmove_media")])
12304 (define_insn "abssf2_i"
12305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12306 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
12307 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12310 [(set_attr "type" "fmove")
12311 (set_attr "fp_mode" "single")])
12313 (define_expand "adddf3"
12314 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12315 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12316 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12317 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12319 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12321 expand_df_binop (&gen_adddf3_i, operands);
12326 (define_insn "*adddf3_media"
12327 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12328 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12329 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12330 "TARGET_SHMEDIA_FPU"
12331 "fadd.d %1, %2, %0"
12332 [(set_attr "type" "dfparith_media")])
12334 (define_insn "adddf3_i"
12335 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12336 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12337 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12338 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12339 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12341 [(set_attr "type" "dfp_arith")
12342 (set_attr "fp_mode" "double")])
12344 (define_expand "subdf3"
12345 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12346 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12347 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12348 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12350 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12352 expand_df_binop (&gen_subdf3_i, operands);
12357 (define_insn "*subdf3_media"
12358 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12359 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12360 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12361 "TARGET_SHMEDIA_FPU"
12362 "fsub.d %1, %2, %0"
12363 [(set_attr "type" "dfparith_media")])
12365 (define_insn "subdf3_i"
12366 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12367 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12368 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12369 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12370 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12372 [(set_attr "type" "dfp_arith")
12373 (set_attr "fp_mode" "double")])
12375 (define_expand "muldf3"
12376 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12377 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12378 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12379 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12381 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12383 expand_df_binop (&gen_muldf3_i, operands);
12388 (define_insn "*muldf3_media"
12389 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12390 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
12391 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12392 "TARGET_SHMEDIA_FPU"
12393 "fmul.d %1, %2, %0"
12394 [(set_attr "type" "dfmul_media")])
12396 (define_insn "muldf3_i"
12397 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12398 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
12399 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12400 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12401 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12403 [(set_attr "type" "dfp_mul")
12404 (set_attr "fp_mode" "double")])
12406 (define_expand "divdf3"
12407 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12408 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
12409 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
12410 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12412 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12414 expand_df_binop (&gen_divdf3_i, operands);
12419 (define_insn "*divdf3_media"
12420 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12421 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
12422 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12423 "TARGET_SHMEDIA_FPU"
12424 "fdiv.d %1, %2, %0"
12425 [(set_attr "type" "dfdiv_media")])
12427 (define_insn "divdf3_i"
12428 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12429 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
12430 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
12431 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
12432 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12434 [(set_attr "type" "dfdiv")
12435 (set_attr "fp_mode" "double")])
12437 (define_insn "floatdidf2"
12438 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12439 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
12440 "TARGET_SHMEDIA_FPU"
12442 [(set_attr "type" "dfpconv_media")])
12444 (define_expand "floatsidf2"
12445 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12446 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
12447 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12449 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12451 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
12452 get_fpscr_rtx ()));
12457 (define_insn "*floatsidf2_media"
12458 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12459 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
12460 "TARGET_SHMEDIA_FPU"
12462 [(set_attr "type" "dfpconv_media")])
12464 (define_insn "floatsidf2_i"
12465 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12466 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
12467 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12468 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12470 [(set_attr "type" "dfp_conv")
12471 (set_attr "fp_mode" "double")])
12473 (define_insn "fix_truncdfdi2"
12474 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
12475 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12476 "TARGET_SHMEDIA_FPU"
12478 [(set_attr "type" "dfpconv_media")])
12480 (define_expand "fix_truncdfsi2"
12481 [(set (match_operand:SI 0 "fpul_operand" "")
12482 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12483 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12485 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12487 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
12488 get_fpscr_rtx ()));
12493 (define_insn "*fix_truncdfsi2_media"
12494 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
12495 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12496 "TARGET_SHMEDIA_FPU"
12498 [(set_attr "type" "dfpconv_media")])
12500 (define_insn "fix_truncdfsi2_i"
12501 [(set (match_operand:SI 0 "fpul_operand" "=y")
12502 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12503 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12504 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12506 [(set_attr "type" "dfp_conv")
12507 (set_attr "dfp_comp" "no")
12508 (set_attr "fp_mode" "double")])
12510 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
12511 ;; fix_truncdfsi2_i.
12512 ;; (define_insn "fix_truncdfsi2_i4"
12513 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12514 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12515 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12516 ;; (clobber (reg:SI FPUL_REG))]
12519 ;; [(set_attr "length" "4")
12520 ;; (set_attr "fp_mode" "double")])
12523 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12524 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
12525 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
12526 ;; (clobber (reg:SI FPUL_REG))]
12528 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
12529 ;; (use (match_dup 2))])
12530 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
12532 (define_insn "cmpgtdf_t"
12533 [(set (reg:SI T_REG)
12534 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
12535 (match_operand:DF 1 "arith_reg_operand" "f")))
12536 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12537 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12539 [(set_attr "type" "dfp_cmp")
12540 (set_attr "fp_mode" "double")])
12542 (define_insn "cmpeqdf_t"
12543 [(set (reg:SI T_REG)
12544 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12545 (match_operand:DF 1 "arith_reg_operand" "f")))
12546 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12547 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12549 [(set_attr "type" "dfp_cmp")
12550 (set_attr "fp_mode" "double")])
12552 (define_insn "*ieee_ccmpeqdf_t"
12553 [(set (reg:SI T_REG)
12554 (ior:SI (reg:SI T_REG)
12555 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
12556 (match_operand:DF 1 "arith_reg_operand" "f"))))
12557 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12558 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12560 return output_ieee_ccmpeq (insn, operands);
12562 [(set_attr "length" "4")
12563 (set_attr "fp_mode" "double")])
12565 (define_insn "cmpeqdf_media"
12566 [(set (match_operand:SI 0 "register_operand" "=r")
12567 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12568 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12569 "TARGET_SHMEDIA_FPU"
12570 "fcmpeq.d %1,%2,%0"
12571 [(set_attr "type" "fcmp_media")])
12573 (define_insn "cmpgtdf_media"
12574 [(set (match_operand:SI 0 "register_operand" "=r")
12575 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12576 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12577 "TARGET_SHMEDIA_FPU"
12578 "fcmpgt.d %1,%2,%0"
12579 [(set_attr "type" "fcmp_media")])
12581 (define_insn "cmpgedf_media"
12582 [(set (match_operand:SI 0 "register_operand" "=r")
12583 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12584 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12585 "TARGET_SHMEDIA_FPU"
12586 "fcmpge.d %1,%2,%0"
12587 [(set_attr "type" "fcmp_media")])
12589 (define_insn "cmpundf_media"
12590 [(set (match_operand:SI 0 "register_operand" "=r")
12591 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
12592 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
12593 "TARGET_SHMEDIA_FPU"
12594 "fcmpun.d %1,%2,%0"
12595 [(set_attr "type" "fcmp_media")])
12597 (define_expand "cbranchdf4"
12599 (if_then_else (match_operator 0 "sh_float_comparison_operator"
12600 [(match_operand:DF 1 "arith_operand" "")
12601 (match_operand:DF 2 "arith_operand" "")])
12602 (match_operand 3 "" "")
12604 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12606 if (TARGET_SHMEDIA)
12607 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
12610 sh_emit_compare_and_branch (operands, DFmode);
12615 (define_expand "negdf2"
12616 [(set (match_operand:DF 0 "arith_reg_operand" "")
12617 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12618 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12620 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12622 expand_df_unop (&gen_negdf2_i, operands);
12627 (define_insn "*negdf2_media"
12628 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12629 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12630 "TARGET_SHMEDIA_FPU"
12632 [(set_attr "type" "fmove_media")])
12634 (define_insn "negdf2_i"
12635 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12636 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12637 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12638 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12640 [(set_attr "type" "fmove")
12641 (set_attr "fp_mode" "double")])
12643 (define_expand "sqrtdf2"
12644 [(set (match_operand:DF 0 "arith_reg_operand" "")
12645 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12646 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12648 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12650 expand_df_unop (&gen_sqrtdf2_i, operands);
12655 (define_insn "*sqrtdf2_media"
12656 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12657 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12658 "TARGET_SHMEDIA_FPU"
12660 [(set_attr "type" "dfdiv_media")])
12662 (define_insn "sqrtdf2_i"
12663 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12664 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12665 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12666 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12668 [(set_attr "type" "dfdiv")
12669 (set_attr "fp_mode" "double")])
12671 (define_expand "absdf2"
12672 [(set (match_operand:DF 0 "arith_reg_operand" "")
12673 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
12674 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12676 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12678 expand_df_unop (&gen_absdf2_i, operands);
12683 (define_insn "*absdf2_media"
12684 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12685 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12686 "TARGET_SHMEDIA_FPU"
12688 [(set_attr "type" "fmove_media")])
12690 (define_insn "absdf2_i"
12691 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12692 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
12693 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12694 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12696 [(set_attr "type" "fmove")
12697 (set_attr "fp_mode" "double")])
12699 (define_expand "extendsfdf2"
12700 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
12701 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
12702 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12704 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12706 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
12707 get_fpscr_rtx ()));
12712 (define_insn "*extendsfdf2_media"
12713 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12714 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
12715 "TARGET_SHMEDIA_FPU"
12717 [(set_attr "type" "dfpconv_media")])
12719 (define_insn "extendsfdf2_i4"
12720 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
12721 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
12722 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12723 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12725 [(set_attr "type" "fp")
12726 (set_attr "fp_mode" "double")])
12728 (define_expand "truncdfsf2"
12729 [(set (match_operand:SF 0 "fpul_operand" "")
12730 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
12731 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
12733 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
12735 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
12736 get_fpscr_rtx ()));
12741 (define_insn "*truncdfsf2_media"
12742 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12743 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
12744 "TARGET_SHMEDIA_FPU"
12746 [(set_attr "type" "dfpconv_media")])
12748 (define_insn "truncdfsf2_i4"
12749 [(set (match_operand:SF 0 "fpul_operand" "=y")
12750 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
12751 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
12752 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
12754 [(set_attr "type" "fp")
12755 (set_attr "fp_mode" "double")])
12757 ;; Bit field extract patterns. These give better code for packed bitfields,
12758 ;; because they allow auto-increment addresses to be generated.
12760 (define_expand "insv"
12761 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
12762 (match_operand:SI 1 "immediate_operand" "")
12763 (match_operand:SI 2 "immediate_operand" ""))
12764 (match_operand:SI 3 "general_operand" ""))]
12765 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
12767 rtx addr_target, orig_address, shift_reg, qi_val;
12768 HOST_WIDE_INT bitsize, size, v = 0;
12769 rtx x = operands[3];
12771 if (TARGET_SH2A && TARGET_BITOPS
12772 && (satisfies_constraint_Sbw (operands[0])
12773 || satisfies_constraint_Sbv (operands[0]))
12774 && satisfies_constraint_M (operands[1])
12775 && satisfies_constraint_K03 (operands[2]))
12777 if (satisfies_constraint_N (operands[3]))
12779 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
12782 else if (satisfies_constraint_M (operands[3]))
12784 emit_insn (gen_bset_m2a (operands[0], operands[2]));
12787 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
12788 && satisfies_constraint_M (operands[1]))
12790 emit_insn (gen_bst_m2a (operands[0], operands[2]));
12793 else if (REG_P (operands[3])
12794 && satisfies_constraint_M (operands[1]))
12796 emit_insn (gen_bld_reg (operands[3], const0_rtx));
12797 emit_insn (gen_bst_m2a (operands[0], operands[2]));
12801 /* ??? expmed doesn't care for non-register predicates. */
12802 if (! memory_operand (operands[0], VOIDmode)
12803 || ! immediate_operand (operands[1], VOIDmode)
12804 || ! immediate_operand (operands[2], VOIDmode)
12805 || ! general_operand (x, VOIDmode))
12807 /* If this isn't a 16 / 24 / 32 bit field, or if
12808 it doesn't start on a byte boundary, then fail. */
12809 bitsize = INTVAL (operands[1]);
12810 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
12811 || (INTVAL (operands[2]) % 8) != 0)
12814 size = bitsize / 8;
12815 orig_address = XEXP (operands[0], 0);
12816 shift_reg = gen_reg_rtx (SImode);
12817 if (CONST_INT_P (x))
12820 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
12824 emit_insn (gen_movsi (shift_reg, operands[3]));
12825 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
12827 addr_target = copy_addr_to_reg (plus_constant (Pmode,
12828 orig_address, size - 1));
12830 operands[0] = replace_equiv_address (operands[0], addr_target);
12831 emit_insn (gen_movqi (operands[0], qi_val));
12835 if (CONST_INT_P (x))
12837 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
12840 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
12841 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
12843 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
12844 emit_insn (gen_movqi (operands[0], qi_val));
12850 (define_insn "movua"
12851 [(set (match_operand:SI 0 "register_operand" "=z")
12852 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
12856 [(set_attr "type" "movua")])
12858 ;; We shouldn't need this, but cse replaces increments with references
12859 ;; to other regs before flow has a chance to create post_inc
12860 ;; addressing modes, and only postreload's cse_move2add brings the
12861 ;; increments back to a usable form.
12863 [(set (match_operand:SI 0 "register_operand" "")
12864 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
12865 (const_int 32) (const_int 0)))
12866 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
12867 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
12868 [(set (match_operand:SI 0 "register_operand" "")
12869 (sign_extract:SI (mem:SI (post_inc:SI
12870 (match_operand:SI 1 "register_operand" "")))
12871 (const_int 32) (const_int 0)))]
12874 (define_expand "extv"
12875 [(set (match_operand:SI 0 "register_operand" "")
12876 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
12877 (match_operand 2 "const_int_operand" "")
12878 (match_operand 3 "const_int_operand" "")))]
12879 "TARGET_SH4A_ARCH || TARGET_SH2A"
12881 if (TARGET_SH2A && TARGET_BITOPS
12882 && (satisfies_constraint_Sbw (operands[1])
12883 || satisfies_constraint_Sbv (operands[1]))
12884 && satisfies_constraint_M (operands[2])
12885 && satisfies_constraint_K03 (operands[3]))
12887 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
12888 if (REGNO (operands[0]) != T_REG)
12889 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
12892 if (TARGET_SH4A_ARCH
12893 && INTVAL (operands[2]) == 32
12894 && INTVAL (operands[3]) == 0
12895 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
12897 rtx src = adjust_address (operands[1], BLKmode, 0);
12898 set_mem_size (src, 4);
12899 emit_insn (gen_movua (operands[0], src));
12906 (define_expand "extzv"
12907 [(set (match_operand:SI 0 "register_operand" "")
12908 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
12909 (match_operand 2 "const_int_operand" "")
12910 (match_operand 3 "const_int_operand" "")))]
12911 "TARGET_SH4A_ARCH || TARGET_SH2A"
12913 if (TARGET_SH2A && TARGET_BITOPS
12914 && (satisfies_constraint_Sbw (operands[1])
12915 || satisfies_constraint_Sbv (operands[1]))
12916 && satisfies_constraint_M (operands[2])
12917 && satisfies_constraint_K03 (operands[3]))
12919 emit_insn (gen_bld_m2a (operands[1], operands[3]));
12920 if (REGNO (operands[0]) != T_REG)
12921 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
12924 if (TARGET_SH4A_ARCH
12925 && INTVAL (operands[2]) == 32
12926 && INTVAL (operands[3]) == 0
12927 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
12929 rtx src = adjust_address (operands[1], BLKmode, 0);
12930 set_mem_size (src, 4);
12931 emit_insn (gen_movua (operands[0], src));
12938 ;; SH2A instructions for bitwise operations.
12940 ;; Clear a bit in a memory location.
12941 (define_insn "bclr_m2a"
12942 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
12944 (not:QI (ashift:QI (const_int 1)
12945 (match_operand:QI 1 "const_int_operand" "K03,K03")))
12947 "TARGET_SH2A && TARGET_BITOPS"
12950 bclr.b %1,@(0,%t0)"
12951 [(set_attr "length" "4,4")])
12953 (define_insn "bclrmem_m2a"
12954 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
12955 (and:QI (match_dup 0)
12956 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
12957 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
12960 bclr.b %W1,@(0,%t0)"
12961 [(set_attr "length" "4,4")])
12963 ;; Set a bit in a memory location.
12964 (define_insn "bset_m2a"
12965 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
12967 (ashift:QI (const_int 1)
12968 (match_operand:QI 1 "const_int_operand" "K03,K03"))
12970 "TARGET_SH2A && TARGET_BITOPS"
12973 bset.b %1,@(0,%t0)"
12974 [(set_attr "length" "4,4")])
12976 (define_insn "bsetmem_m2a"
12977 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
12978 (ior:QI (match_dup 0)
12979 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
12980 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
12983 bset.b %V1,@(0,%t0)"
12984 [(set_attr "length" "4,4")])
12986 ;;; Transfer the contents of the T bit to a specified bit of memory.
12987 (define_insn "bst_m2a"
12988 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
12989 (if_then_else (eq (reg:SI T_REG) (const_int 0))
12991 (not:QI (ashift:QI (const_int 1)
12992 (match_operand:QI 1 "const_int_operand" "K03,K03")))
12995 (ashift:QI (const_int 1) (match_dup 1))
12997 "TARGET_SH2A && TARGET_BITOPS"
13001 [(set_attr "length" "4")])
13003 ;; Store a specified bit of memory in the T bit.
13004 (define_insn "bld_m2a"
13005 [(set (reg:SI T_REG)
13007 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
13009 (match_operand 1 "const_int_operand" "K03,K03")))]
13010 "TARGET_SH2A && TARGET_BITOPS"
13014 [(set_attr "length" "4,4")])
13016 ;; Store a specified bit of memory in the T bit.
13017 (define_insn "bldsign_m2a"
13018 [(set (reg:SI T_REG)
13020 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13022 (match_operand 1 "const_int_operand" "K03,K03")))]
13023 "TARGET_SH2A && TARGET_BITOPS"
13027 [(set_attr "length" "4,4")])
13029 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
13030 (define_insn "bld_reg"
13031 [(set (reg:SI T_REG)
13032 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
13034 (match_operand 1 "const_int_operand" "K03")))]
13038 (define_insn "*bld_regqi"
13039 [(set (reg:SI T_REG)
13040 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
13042 (match_operand 1 "const_int_operand" "K03")))]
13046 ;; Take logical and of a specified bit of memory with the T bit and
13047 ;; store its result in the T bit.
13048 (define_insn "band_m2a"
13049 [(set (reg:SI T_REG)
13050 (and:SI (reg:SI T_REG)
13052 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13054 (match_operand 1 "const_int_operand" "K03,K03"))))]
13055 "TARGET_SH2A && TARGET_BITOPS"
13058 band.b %1,@(0,%t0)"
13059 [(set_attr "length" "4,4")])
13061 (define_insn "bandreg_m2a"
13062 [(set (match_operand:SI 0 "register_operand" "=r,r")
13063 (and:SI (zero_extract:SI
13064 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13066 (match_operand 2 "const_int_operand" "K03,K03"))
13067 (match_operand:SI 3 "register_operand" "r,r")))]
13068 "TARGET_SH2A && TARGET_BITOPS"
13070 static const char* alt[] =
13072 "band.b %2,%1" "\n"
13075 "band.b %2,@(0,%t1)" "\n"
13078 return alt[which_alternative];
13080 [(set_attr "length" "6,6")])
13082 ;; Take logical or of a specified bit of memory with the T bit and
13083 ;; store its result in the T bit.
13084 (define_insn "bor_m2a"
13085 [(set (reg:SI T_REG)
13086 (ior:SI (reg:SI T_REG)
13088 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13090 (match_operand 1 "const_int_operand" "K03,K03"))))]
13091 "TARGET_SH2A && TARGET_BITOPS"
13095 [(set_attr "length" "4,4")])
13097 (define_insn "borreg_m2a"
13098 [(set (match_operand:SI 0 "register_operand" "=r,r")
13099 (ior:SI (zero_extract:SI
13100 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13102 (match_operand 2 "const_int_operand" "K03,K03"))
13103 (match_operand:SI 3 "register_operand" "=r,r")))]
13104 "TARGET_SH2A && TARGET_BITOPS"
13106 static const char* alt[] =
13111 "bor.b %2,@(0,%t1)" "\n"
13114 return alt[which_alternative];
13116 [(set_attr "length" "6,6")])
13118 ;; Take exclusive or of a specified bit of memory with the T bit and
13119 ;; store its result in the T bit.
13120 (define_insn "bxor_m2a"
13121 [(set (reg:SI T_REG)
13122 (xor:SI (reg:SI T_REG)
13124 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
13126 (match_operand 1 "const_int_operand" "K03,K03"))))]
13127 "TARGET_SH2A && TARGET_BITOPS"
13130 bxor.b %1,@(0,%t0)"
13131 [(set_attr "length" "4,4")])
13133 (define_insn "bxorreg_m2a"
13134 [(set (match_operand:SI 0 "register_operand" "=r,r")
13135 (xor:SI (zero_extract:SI
13136 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
13138 (match_operand 2 "const_int_operand" "K03,K03"))
13139 (match_operand:SI 3 "register_operand" "=r,r")))]
13140 "TARGET_SH2A && TARGET_BITOPS"
13142 static const char* alt[] =
13144 "bxor.b %2,%1" "\n"
13147 "bxor.b %2,@(0,%t1)" "\n"
13150 return alt[which_alternative];
13152 [(set_attr "length" "6,6")])
13155 ;; -------------------------------------------------------------------------
13157 ;; -------------------------------------------------------------------------
13158 ;; This matches cases where the bit in a memory location is set.
13160 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13161 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13163 (ior:SI (match_dup 0)
13164 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
13166 (match_operand 3 "arith_reg_operand" "r,r"))]
13167 "TARGET_SH2A && TARGET_BITOPS
13168 && satisfies_constraint_Pso (operands[2])
13169 && REGNO (operands[0]) == REGNO (operands[3])"
13170 [(set (match_dup 1)
13171 (ior:QI (match_dup 1)
13175 ;; This matches cases where the bit in a memory location is cleared.
13177 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
13178 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
13180 (and:SI (match_dup 0)
13181 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
13183 (match_operand 3 "arith_reg_operand" "r,r"))]
13184 "TARGET_SH2A && TARGET_BITOPS
13185 && satisfies_constraint_Psz (operands[2])
13186 && REGNO (operands[0]) == REGNO (operands[3])"
13187 [(set (match_dup 1)
13188 (and:QI (match_dup 1)
13192 ;; This matches cases where a stack pointer increment at the start of the
13193 ;; epilogue combines with a stack slot read loading the return value.
13196 [(set (match_operand:SI 0 "arith_reg_operand" "")
13197 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
13198 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
13199 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
13202 ;; See the comment on the dt combiner pattern above.
13205 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
13206 (plus:SI (match_dup 0)
13208 (set (reg:SI T_REG)
13209 (eq:SI (match_dup 0)
13214 ;; The following peepholes fold load sequences for which reload was not
13215 ;; able to generate a displacement addressing move insn.
13216 ;; This can happen when reload has to transform a move insn
13217 ;; without displacement into one with displacement. Or when reload can't
13218 ;; fit a displacement into the insn's constraints. In the latter case, the
13219 ;; load destination reg remains at r0, which reload compensates by inserting
13220 ;; another mov insn.
13224 ;; mov.{b,w} @(r0,r15),r0
13227 ;; mov.{b,w} @(54,r15),r3
13230 [(set (match_operand:SI 0 "arith_reg_dest" "")
13231 (match_operand:SI 1 "const_int_operand" ""))
13232 (set (match_operand:SI 2 "arith_reg_dest" "")
13234 (mem:QI (plus:SI (match_dup 0)
13235 (match_operand:SI 3 "arith_reg_operand" "")))))
13236 (set (match_operand:QI 4 "arith_reg_dest" "")
13237 (match_operand:QI 5 "arith_reg_operand" ""))]
13239 && sh_legitimate_index_p (QImode, operands[1], true, true)
13240 && REGNO (operands[2]) == REGNO (operands[5])
13241 && peep2_reg_dead_p (3, operands[5])"
13242 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
13246 [(set (match_operand:SI 0 "arith_reg_dest" "")
13247 (match_operand:SI 1 "const_int_operand" ""))
13248 (set (match_operand:SI 2 "arith_reg_dest" "")
13250 (mem:HI (plus:SI (match_dup 0)
13251 (match_operand:SI 3 "arith_reg_operand" "")))))
13252 (set (match_operand:HI 4 "arith_reg_dest" "")
13253 (match_operand:HI 5 "arith_reg_operand" ""))]
13255 && sh_legitimate_index_p (HImode, operands[1], true, true)
13256 && REGNO (operands[2]) == REGNO (operands[5])
13257 && peep2_reg_dead_p (3, operands[5])"
13258 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
13263 ;; mov.{b,w} @(r0,r15),r1
13265 ;; mov.{b,w} @(54,r15),r1
13268 [(set (match_operand:SI 0 "arith_reg_dest" "")
13269 (match_operand:SI 1 "const_int_operand" ""))
13270 (set (match_operand:SI 2 "arith_reg_dest" "")
13272 (mem:QI (plus:SI (match_dup 0)
13273 (match_operand:SI 3 "arith_reg_operand" "")))))]
13275 && sh_legitimate_index_p (QImode, operands[1], true, true)
13276 && (peep2_reg_dead_p (2, operands[0])
13277 || REGNO (operands[0]) == REGNO (operands[2]))"
13278 [(set (match_dup 2)
13279 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
13283 [(set (match_operand:SI 0 "arith_reg_dest" "")
13284 (match_operand:SI 1 "const_int_operand" ""))
13285 (set (match_operand:SI 2 "arith_reg_dest" "")
13287 (mem:HI (plus:SI (match_dup 0)
13288 (match_operand:SI 3 "arith_reg_operand" "")))))]
13290 && sh_legitimate_index_p (HImode, operands[1], true, true)
13291 && (peep2_reg_dead_p (2, operands[0])
13292 || REGNO (operands[0]) == REGNO (operands[2]))"
13293 [(set (match_dup 2)
13294 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
13298 ;; mov.{b,w} @(r0,r15),r0
13301 ;; mov.{b,w} @(r0,r15),r3
13303 ;; This can happen when initially a displacement address is picked, where
13304 ;; the destination reg is fixed to r0, and then the address is transformed
13305 ;; into 'r0 + reg'.
13307 [(set (match_operand:SI 0 "arith_reg_dest" "")
13309 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13310 (match_operand:SI 2 "arith_reg_operand" "")))))
13311 (set (match_operand:QI 3 "arith_reg_dest" "")
13312 (match_operand:QI 4 "arith_reg_operand" ""))]
13314 && REGNO (operands[0]) == REGNO (operands[4])
13315 && peep2_reg_dead_p (2, operands[0])"
13316 [(set (match_dup 3)
13317 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
13321 [(set (match_operand:SI 0 "arith_reg_dest" "")
13323 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
13324 (match_operand:SI 2 "arith_reg_operand" "")))))
13325 (set (match_operand:HI 3 "arith_reg_dest" "")
13326 (match_operand:HI 4 "arith_reg_operand" ""))]
13328 && REGNO (operands[0]) == REGNO (operands[4])
13329 && peep2_reg_dead_p (2, operands[0])"
13330 [(set (match_dup 3)
13331 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
13335 [(set (match_operand:SI 0 "register_operand" "=r")
13336 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13337 (set (mem:SF (match_dup 0))
13338 (match_operand:SF 2 "general_movsrc_operand" ""))]
13339 "TARGET_SH1 && REGNO (operands[0]) == 0
13340 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13341 || (GET_CODE (operands[2]) == SUBREG
13342 && REGNO (SUBREG_REG (operands[2])) < 16))
13343 && reg_unused_after (operands[0], insn)"
13344 "mov.l %2,@(%0,%1)")
13347 [(set (match_operand:SI 0 "register_operand" "=r")
13348 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13349 (set (match_operand:SF 2 "general_movdst_operand" "")
13351 (mem:SF (match_dup 0)))]
13352 "TARGET_SH1 && REGNO (operands[0]) == 0
13353 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
13354 || (GET_CODE (operands[2]) == SUBREG
13355 && REGNO (SUBREG_REG (operands[2])) < 16))
13356 && reg_unused_after (operands[0], insn)"
13357 "mov.l @(%0,%1),%2")
13360 [(set (match_operand:SI 0 "register_operand" "=r")
13361 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13362 (set (mem:SF (match_dup 0))
13363 (match_operand:SF 2 "general_movsrc_operand" ""))]
13364 "TARGET_SH2E && REGNO (operands[0]) == 0
13365 && ((REG_P (operands[2])
13366 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13367 || (GET_CODE (operands[2]) == SUBREG
13368 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13369 && reg_unused_after (operands[0], insn)"
13370 "fmov{.s|} %2,@(%0,%1)")
13373 [(set (match_operand:SI 0 "register_operand" "=r")
13374 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
13375 (set (match_operand:SF 2 "general_movdst_operand" "")
13377 (mem:SF (match_dup 0)))]
13378 "TARGET_SH2E && REGNO (operands[0]) == 0
13379 && ((REG_P (operands[2])
13380 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
13381 || (GET_CODE (operands[2]) == SUBREG
13382 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
13383 && reg_unused_after (operands[0], insn)"
13384 "fmov{.s|} @(%0,%1),%2")
13386 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).
13387 (define_insn "sp_switch_1"
13388 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
13391 return "mov.l r0,@-r15" "\n"
13392 " mov.l %0,r0" "\n"
13393 " mov.l @r0,r0" "\n"
13394 " mov.l r15,@-r0" "\n"
13397 [(set_attr "length" "10")])
13399 ;; Switch back to the original stack for interrupt functions with the
13400 ;; sp_switch attribute.
13401 (define_insn "sp_switch_2"
13405 return "mov.l @r15+,r15" "\n"
13408 [(set_attr "length" "4")])
13410 ;; Integer vector moves
13412 (define_expand "movv8qi"
13413 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
13414 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
13417 prepare_move_operands (operands, V8QImode);
13420 (define_insn "movv8qi_i"
13421 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
13422 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13424 && (register_operand (operands[0], V8QImode)
13425 || sh_register_operand (operands[1], V8QImode))"
13432 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13433 (set_attr "length" "4,4,16,4,4")])
13436 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
13437 (subreg:V8QI (const_int 0) 0))]
13439 [(set (match_dup 0)
13440 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
13441 (const_int 0) (const_int 0) (const_int 0)
13442 (const_int 0) (const_int 0)]))])
13445 [(set (match_operand 0 "arith_reg_dest" "")
13446 (match_operand 1 "sh_rep_vec" ""))]
13447 "TARGET_SHMEDIA && reload_completed
13448 && GET_MODE (operands[0]) == GET_MODE (operands[1])
13449 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
13450 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
13451 && (XVECEXP (operands[1], 0, 0) != const0_rtx
13452 || XVECEXP (operands[1], 0, 1) != const0_rtx)
13453 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
13454 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
13455 [(set (match_dup 0) (match_dup 1))
13458 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
13459 rtx elt1 = XVECEXP (operands[1], 0, 1);
13462 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
13466 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
13467 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
13469 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
13470 operands[1] = XVECEXP (operands[1], 0, 0);
13473 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
13475 = GEN_INT (TARGET_LITTLE_ENDIAN
13476 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
13477 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
13480 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
13482 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
13488 [(set (match_operand 0 "arith_reg_dest" "")
13489 (match_operand 1 "sh_const_vec" ""))]
13490 "TARGET_SHMEDIA && reload_completed
13491 && GET_MODE (operands[0]) == GET_MODE (operands[1])
13492 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
13493 [(set (match_dup 0) (match_dup 1))]
13495 rtx v = operands[1];
13496 enum machine_mode new_mode
13497 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
13499 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
13501 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
13504 (define_expand "movv2hi"
13505 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
13506 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
13509 prepare_move_operands (operands, V2HImode);
13512 (define_insn "movv2hi_i"
13513 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13514 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13516 && (register_operand (operands[0], V2HImode)
13517 || sh_register_operand (operands[1], V2HImode))"
13524 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13525 (set_attr "length" "4,4,16,4,4")
13526 (set (attr "highpart")
13527 (cond [(match_test "sh_contains_memref_p (insn)")
13528 (const_string "user")]
13529 (const_string "ignore")))])
13531 (define_expand "movv4hi"
13532 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
13533 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
13536 prepare_move_operands (operands, V4HImode);
13539 (define_insn "movv4hi_i"
13540 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
13541 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13543 && (register_operand (operands[0], V4HImode)
13544 || sh_register_operand (operands[1], V4HImode))"
13551 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13552 (set_attr "length" "4,4,16,4,4")
13553 (set_attr "highpart" "depend")])
13555 (define_expand "movv2si"
13556 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
13557 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
13560 prepare_move_operands (operands, V2SImode);
13563 (define_insn "movv2si_i"
13564 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
13565 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
13567 && (register_operand (operands[0], V2SImode)
13568 || sh_register_operand (operands[1], V2SImode))"
13575 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
13576 (set_attr "length" "4,4,16,4,4")
13577 (set_attr "highpart" "depend")])
13579 ;; Multimedia Intrinsics
13581 (define_insn "absv2si2"
13582 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13583 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
13586 [(set_attr "type" "mcmp_media")
13587 (set_attr "highpart" "depend")])
13589 (define_insn "absv4hi2"
13590 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13591 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
13594 [(set_attr "type" "mcmp_media")
13595 (set_attr "highpart" "depend")])
13597 (define_insn "addv2si3"
13598 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13599 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13600 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13602 "madd.l %1, %2, %0"
13603 [(set_attr "type" "arith_media")
13604 (set_attr "highpart" "depend")])
13606 (define_insn "addv4hi3"
13607 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13608 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13609 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13611 "madd.w %1, %2, %0"
13612 [(set_attr "type" "arith_media")
13613 (set_attr "highpart" "depend")])
13615 (define_insn_and_split "addv2hi3"
13616 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13617 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
13618 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
13624 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13625 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13626 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13627 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13628 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13630 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
13631 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13634 [(set_attr "highpart" "must_split")])
13636 (define_insn "ssaddv2si3"
13637 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13638 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
13639 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13641 "madds.l %1, %2, %0"
13642 [(set_attr "type" "mcmp_media")
13643 (set_attr "highpart" "depend")])
13645 (define_insn "usaddv8qi3"
13646 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13647 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
13648 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13650 "madds.ub %1, %2, %0"
13651 [(set_attr "type" "mcmp_media")
13652 (set_attr "highpart" "depend")])
13654 (define_insn "ssaddv4hi3"
13655 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13656 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
13657 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13659 "madds.w %1, %2, %0"
13660 [(set_attr "type" "mcmp_media")
13661 (set_attr "highpart" "depend")])
13663 (define_insn "negcmpeqv8qi"
13664 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13665 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13666 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13668 "mcmpeq.b %N1, %N2, %0"
13669 [(set_attr "type" "mcmp_media")
13670 (set_attr "highpart" "depend")])
13672 (define_insn "negcmpeqv2si"
13673 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13674 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13675 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13677 "mcmpeq.l %N1, %N2, %0"
13678 [(set_attr "type" "mcmp_media")
13679 (set_attr "highpart" "depend")])
13681 (define_insn "negcmpeqv4hi"
13682 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13683 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13684 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13686 "mcmpeq.w %N1, %N2, %0"
13687 [(set_attr "type" "mcmp_media")
13688 (set_attr "highpart" "depend")])
13690 (define_insn "negcmpgtuv8qi"
13691 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13692 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
13693 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
13695 "mcmpgt.ub %N1, %N2, %0"
13696 [(set_attr "type" "mcmp_media")
13697 (set_attr "highpart" "depend")])
13699 (define_insn "negcmpgtv2si"
13700 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13701 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
13702 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13704 "mcmpgt.l %N1, %N2, %0"
13705 [(set_attr "type" "mcmp_media")
13706 (set_attr "highpart" "depend")])
13708 (define_insn "negcmpgtv4hi"
13709 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13710 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
13711 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13713 "mcmpgt.w %N1, %N2, %0"
13714 [(set_attr "type" "mcmp_media")
13715 (set_attr "highpart" "depend")])
13717 (define_insn "mcmv"
13718 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13719 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13720 (match_operand:DI 2 "arith_reg_operand" "r"))
13721 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
13722 (not:DI (match_dup 2)))))]
13725 [(set_attr "type" "arith_media")
13726 (set_attr "highpart" "depend")])
13728 (define_insn "mcnvs_lw"
13729 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13731 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
13732 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
13734 "mcnvs.lw %N1, %N2, %0"
13735 [(set_attr "type" "mcmp_media")])
13737 (define_insn "mcnvs_wb"
13738 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13740 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13741 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13743 "mcnvs.wb %N1, %N2, %0"
13744 [(set_attr "type" "mcmp_media")])
13746 (define_insn "mcnvs_wub"
13747 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13749 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
13750 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
13752 "mcnvs.wub %N1, %N2, %0"
13753 [(set_attr "type" "mcmp_media")])
13755 (define_insn "mextr_rl"
13756 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13757 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13758 (match_operand:HI 3 "mextr_bit_offset" "i"))
13759 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13760 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
13761 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
13763 static char templ[21];
13764 sprintf (templ, "mextr%d %%N1, %%N2, %%0",
13765 (int) INTVAL (operands[3]) >> 3);
13768 [(set_attr "type" "arith_media")])
13770 (define_insn "*mextr_lr"
13771 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13772 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13773 (match_operand:HI 3 "mextr_bit_offset" "i"))
13774 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13775 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
13776 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
13778 static char templ[21];
13779 sprintf (templ, "mextr%d %%N2, %%N1, %%0",
13780 (int) INTVAL (operands[4]) >> 3);
13783 [(set_attr "type" "arith_media")])
13785 ; mextrN can be modelled with vec_select / vec_concat, but the selection
13786 ; vector then varies depending on endianness.
13787 (define_expand "mextr1"
13788 [(match_operand:DI 0 "arith_reg_dest" "")
13789 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13790 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13793 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13794 GEN_INT (1 * 8), GEN_INT (7 * 8)));
13798 (define_expand "mextr2"
13799 [(match_operand:DI 0 "arith_reg_dest" "")
13800 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13801 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13804 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13805 GEN_INT (2 * 8), GEN_INT (6 * 8)));
13809 (define_expand "mextr3"
13810 [(match_operand:DI 0 "arith_reg_dest" "")
13811 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13812 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13815 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13816 GEN_INT (3 * 8), GEN_INT (5 * 8)));
13820 (define_expand "mextr4"
13821 [(match_operand:DI 0 "arith_reg_dest" "")
13822 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13823 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13826 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13827 GEN_INT (4 * 8), GEN_INT (4 * 8)));
13831 (define_expand "mextr5"
13832 [(match_operand:DI 0 "arith_reg_dest" "")
13833 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13834 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13837 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13838 GEN_INT (5 * 8), GEN_INT (3 * 8)));
13842 (define_expand "mextr6"
13843 [(match_operand:DI 0 "arith_reg_dest" "")
13844 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13845 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13848 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13849 GEN_INT (6 * 8), GEN_INT (2 * 8)));
13853 (define_expand "mextr7"
13854 [(match_operand:DI 0 "arith_reg_dest" "")
13855 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13856 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
13859 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
13860 GEN_INT (7 * 8), GEN_INT (1 * 8)));
13864 (define_expand "mmacfx_wl"
13865 [(match_operand:V2SI 0 "arith_reg_dest" "")
13866 (match_operand:V2HI 1 "extend_reg_operand" "")
13867 (match_operand:V2HI 2 "extend_reg_operand" "")
13868 (match_operand:V2SI 3 "arith_reg_operand" "")]
13871 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
13872 operands[1], operands[2]));
13876 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
13878 (define_insn "mmacfx_wl_i"
13879 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13881 (match_operand:V2SI 1 "arith_reg_operand" "0")
13886 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
13887 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
13890 "mmacfx.wl %2, %3, %0"
13891 [(set_attr "type" "mac_media")
13892 (set_attr "highpart" "depend")])
13894 (define_expand "mmacnfx_wl"
13895 [(match_operand:V2SI 0 "arith_reg_dest" "")
13896 (match_operand:V2HI 1 "extend_reg_operand" "")
13897 (match_operand:V2HI 2 "extend_reg_operand" "")
13898 (match_operand:V2SI 3 "arith_reg_operand" "")]
13901 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
13902 operands[1], operands[2]));
13906 (define_insn "mmacnfx_wl_i"
13907 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13909 (match_operand:V2SI 1 "arith_reg_operand" "0")
13914 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
13915 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
13918 "mmacnfx.wl %2, %3, %0"
13919 [(set_attr "type" "mac_media")
13920 (set_attr "highpart" "depend")])
13922 (define_insn "mulv2si3"
13923 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13924 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13925 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13927 "mmul.l %1, %2, %0"
13928 [(set_attr "type" "d2mpy_media")
13929 (set_attr "highpart" "depend")])
13931 (define_insn "mulv4hi3"
13932 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13933 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13934 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13936 "mmul.w %1, %2, %0"
13937 [(set_attr "type" "dmpy_media")
13938 (set_attr "highpart" "depend")])
13940 (define_insn "mmulfx_l"
13941 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13945 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
13946 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
13949 "mmulfx.l %1, %2, %0"
13950 [(set_attr "type" "d2mpy_media")
13951 (set_attr "highpart" "depend")])
13953 (define_insn "mmulfx_w"
13954 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13958 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
13959 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
13962 "mmulfx.w %1, %2, %0"
13963 [(set_attr "type" "dmpy_media")
13964 (set_attr "highpart" "depend")])
13966 (define_insn "mmulfxrp_w"
13967 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13972 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
13973 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
13977 "mmulfxrp.w %1, %2, %0"
13978 [(set_attr "type" "dmpy_media")
13979 (set_attr "highpart" "depend")])
13982 (define_expand "mmulhi_wl"
13983 [(match_operand:V2SI 0 "arith_reg_dest" "")
13984 (match_operand:V4HI 1 "arith_reg_operand" "")
13985 (match_operand:V4HI 2 "arith_reg_operand" "")]
13988 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
13989 (operands[0], operands[1], operands[2]));
13993 (define_expand "mmullo_wl"
13994 [(match_operand:V2SI 0 "arith_reg_dest" "")
13995 (match_operand:V4HI 1 "arith_reg_operand" "")
13996 (match_operand:V4HI 2 "arith_reg_operand" "")]
13999 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
14000 (operands[0], operands[1], operands[2]));
14004 (define_insn "mmul23_wl"
14005 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14008 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14009 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14010 (parallel [(const_int 2) (const_int 3)])))]
14013 return (TARGET_LITTLE_ENDIAN
14014 ? "mmulhi.wl %1, %2, %0"
14015 : "mmullo.wl %1, %2, %0");
14017 [(set_attr "type" "dmpy_media")
14018 (set (attr "highpart")
14019 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14020 (const_string "user")))])
14022 (define_insn "mmul01_wl"
14023 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14026 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14027 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
14028 (parallel [(const_int 0) (const_int 1)])))]
14031 return (TARGET_LITTLE_ENDIAN
14032 ? "mmullo.wl %1, %2, %0"
14033 : "mmulhi.wl %1, %2, %0");
14035 [(set_attr "type" "dmpy_media")
14036 (set (attr "highpart")
14037 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14038 (const_string "user")))])
14041 (define_expand "mmulsum_wq"
14042 [(match_operand:DI 0 "arith_reg_dest" "")
14043 (match_operand:V4HI 1 "arith_reg_operand" "")
14044 (match_operand:V4HI 2 "arith_reg_operand" "")
14045 (match_operand:DI 3 "arith_reg_operand" "")]
14048 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
14049 operands[1], operands[2]));
14053 (define_insn "mmulsum_wq_i"
14054 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14055 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
14060 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
14061 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
14062 (parallel [(const_int 0)]))
14063 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14064 (sign_extend:V4DI (match_dup 3)))
14065 (parallel [(const_int 1)])))
14067 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14068 (sign_extend:V4DI (match_dup 3)))
14069 (parallel [(const_int 2)]))
14070 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
14071 (sign_extend:V4DI (match_dup 3)))
14072 (parallel [(const_int 3)]))))))]
14074 "mmulsum.wq %2, %3, %0"
14075 [(set_attr "type" "mac_media")])
14077 (define_expand "mperm_w"
14078 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
14079 (match_operand:V4HI 1 "arith_reg_operand" "r")
14080 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
14083 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
14084 (operands[0], operands[1], operands[2]));
14088 ; This use of vec_select isn't exactly correct according to rtl.texi
14089 ; (because not constant), but it seems a straightforward extension.
14090 (define_insn "mperm_w_little"
14091 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14093 (match_operand:V4HI 1 "arith_reg_operand" "r")
14095 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
14096 (const_int 2) (const_int 0))
14097 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
14098 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
14099 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
14100 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
14101 "mperm.w %1, %N2, %0"
14102 [(set_attr "type" "arith_media")])
14104 (define_insn "mperm_w_big"
14105 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14107 (match_operand:V4HI 1 "arith_reg_operand" "r")
14109 [(zero_extract:QI (not:QI (match_operand:QI 2
14110 "extend_reg_or_0_operand" "rZ"))
14111 (const_int 2) (const_int 0))
14112 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
14113 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
14114 (zero_extract:QI (not:QI (match_dup 2))
14115 (const_int 2) (const_int 6))])))]
14116 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
14117 "mperm.w %1, %N2, %0"
14118 [(set_attr "type" "arith_media")])
14120 (define_insn "mperm_w0"
14121 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14122 (vec_duplicate:V4HI (truncate:HI (match_operand 1
14123 "trunc_hi_operand" "r"))))]
14125 "mperm.w %1, r63, %0"
14126 [(set_attr "type" "arith_media")
14127 (set_attr "highpart" "ignore")])
14129 (define_expand "msad_ubq"
14130 [(match_operand:DI 0 "arith_reg_dest" "")
14131 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
14132 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
14133 (match_operand:DI 3 "arith_reg_operand" "")]
14136 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
14137 operands[1], operands[2]));
14141 (define_insn "msad_ubq_i"
14142 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14147 (match_operand:DI 1 "arith_reg_operand" "0")
14148 (abs:DI (vec_select:DI
14151 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14153 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
14154 (parallel [(const_int 0)]))))
14155 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14156 (zero_extend:V8DI (match_dup 3)))
14157 (parallel [(const_int 1)]))))
14159 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14160 (zero_extend:V8DI (match_dup 3)))
14161 (parallel [(const_int 2)])))
14162 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14163 (zero_extend:V8DI (match_dup 3)))
14164 (parallel [(const_int 3)])))))
14167 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14168 (zero_extend:V8DI (match_dup 3)))
14169 (parallel [(const_int 4)])))
14170 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14171 (zero_extend:V8DI (match_dup 3)))
14172 (parallel [(const_int 5)]))))
14174 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14175 (zero_extend:V8DI (match_dup 3)))
14176 (parallel [(const_int 6)])))
14177 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
14178 (zero_extend:V8DI (match_dup 3)))
14179 (parallel [(const_int 7)])))))))]
14181 "msad.ubq %N2, %N3, %0"
14182 [(set_attr "type" "mac_media")])
14184 (define_insn "mshalds_l"
14185 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14188 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
14189 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14190 (const_int 31)))))]
14192 "mshalds.l %1, %2, %0"
14193 [(set_attr "type" "mcmp_media")
14194 (set_attr "highpart" "depend")])
14196 (define_insn "mshalds_w"
14197 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14200 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
14201 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
14202 (const_int 15)))))]
14204 "mshalds.w %1, %2, %0"
14205 [(set_attr "type" "mcmp_media")
14206 (set_attr "highpart" "depend")])
14208 (define_insn "ashrv2si3"
14209 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14210 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14211 (match_operand:DI 2 "arith_reg_operand" "r")))]
14213 "mshard.l %1, %2, %0"
14214 [(set_attr "type" "arith_media")
14215 (set_attr "highpart" "depend")])
14217 (define_insn "ashrv4hi3"
14218 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14219 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14220 (match_operand:DI 2 "arith_reg_operand" "r")))]
14222 "mshard.w %1, %2, %0"
14223 [(set_attr "type" "arith_media")
14224 (set_attr "highpart" "depend")])
14226 (define_insn "mshards_q"
14227 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
14229 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
14230 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
14232 "mshards.q %1, %N2, %0"
14233 [(set_attr "type" "mcmp_media")])
14235 (define_expand "mshfhi_b"
14236 [(match_operand:V8QI 0 "arith_reg_dest" "")
14237 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14238 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14241 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
14242 (operands[0], operands[1], operands[2]));
14246 (define_expand "mshflo_b"
14247 [(match_operand:V8QI 0 "arith_reg_dest" "")
14248 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14249 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
14252 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
14253 (operands[0], operands[1], operands[2]));
14257 (define_insn "mshf4_b"
14259 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14261 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14262 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14263 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
14264 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
14267 return (TARGET_LITTLE_ENDIAN
14268 ? "mshfhi.b %N1, %N2, %0"
14269 : "mshflo.b %N1, %N2, %0");
14271 [(set_attr "type" "arith_media")
14272 (set (attr "highpart")
14273 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14274 (const_string "user")))])
14276 (define_insn "mshf0_b"
14278 (match_operand:V8QI 0 "arith_reg_dest" "=r")
14280 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14281 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
14282 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
14283 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
14286 return (TARGET_LITTLE_ENDIAN
14287 ? "mshflo.b %N1, %N2, %0"
14288 : "mshfhi.b %N1, %N2, %0");
14290 [(set_attr "type" "arith_media")
14291 (set (attr "highpart")
14292 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14293 (const_string "user")))])
14295 (define_expand "mshfhi_l"
14296 [(match_operand:V2SI 0 "arith_reg_dest" "")
14297 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14298 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14301 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
14302 (operands[0], operands[1], operands[2]));
14306 (define_expand "mshflo_l"
14307 [(match_operand:V2SI 0 "arith_reg_dest" "")
14308 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14309 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
14312 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
14313 (operands[0], operands[1], operands[2]));
14317 (define_insn "mshf4_l"
14318 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14320 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14321 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14322 (parallel [(const_int 1) (const_int 3)])))]
14325 return (TARGET_LITTLE_ENDIAN
14326 ? "mshfhi.l %N1, %N2, %0"
14327 : "mshflo.l %N1, %N2, %0");
14329 [(set_attr "type" "arith_media")
14330 (set (attr "highpart")
14331 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14332 (const_string "user")))])
14334 (define_insn "mshf0_l"
14335 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14337 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14338 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
14339 (parallel [(const_int 0) (const_int 2)])))]
14342 return (TARGET_LITTLE_ENDIAN
14343 ? "mshflo.l %N1, %N2, %0"
14344 : "mshfhi.l %N1, %N2, %0");
14346 [(set_attr "type" "arith_media")
14347 (set (attr "highpart")
14348 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14349 (const_string "user")))])
14351 (define_expand "mshfhi_w"
14352 [(match_operand:V4HI 0 "arith_reg_dest" "")
14353 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14354 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14357 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
14358 (operands[0], operands[1], operands[2]));
14362 (define_expand "mshflo_w"
14363 [(match_operand:V4HI 0 "arith_reg_dest" "")
14364 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14365 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
14368 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
14369 (operands[0], operands[1], operands[2]));
14373 (define_insn "mshf4_w"
14374 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14376 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14377 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14378 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
14381 return (TARGET_LITTLE_ENDIAN
14382 ? "mshfhi.w %N1, %N2, %0"
14383 : "mshflo.w %N1, %N2, %0");
14385 [(set_attr "type" "arith_media")
14386 (set (attr "highpart")
14387 (cond [(eq_attr "endian" "big") (const_string "ignore")]
14388 (const_string "user")))])
14390 (define_insn "mshf0_w"
14391 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14393 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14394 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
14395 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
14398 return (TARGET_LITTLE_ENDIAN
14399 ? "mshflo.w %N1, %N2, %0"
14400 : "mshfhi.w %N1, %N2, %0");
14402 [(set_attr "type" "arith_media")
14403 (set (attr "highpart")
14404 (cond [(eq_attr "endian" "little") (const_string "ignore")]
14405 (const_string "user")))])
14407 (define_insn "mshflo_w_x"
14408 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14410 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
14411 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
14412 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
14414 "mshflo.w %N1, %N2, %0"
14415 [(set_attr "type" "arith_media")
14416 (set_attr "highpart" "ignore")])
14418 ;; These are useful to expand ANDs and as combiner patterns.
14419 (define_insn_and_split "mshfhi_l_di"
14420 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
14421 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
14423 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
14424 (const_int -4294967296))))]
14427 mshfhi.l %N1, %N2, %0
14429 "TARGET_SHMEDIA && reload_completed
14430 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14431 [(set (match_dup 3) (match_dup 4))
14432 (set (match_dup 5) (match_dup 6))]
14434 operands[3] = gen_lowpart (SImode, operands[0]);
14435 operands[4] = gen_highpart (SImode, operands[1]);
14436 operands[5] = gen_highpart (SImode, operands[0]);
14437 operands[6] = gen_highpart (SImode, operands[2]);
14439 [(set_attr "type" "arith_media")])
14441 (define_insn "*mshfhi_l_di_rev"
14442 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14443 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14444 (const_int -4294967296))
14445 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14448 "mshfhi.l %N2, %N1, %0"
14449 [(set_attr "type" "arith_media")])
14452 [(set (match_operand:DI 0 "arith_reg_dest" "")
14453 (ior:DI (zero_extend:DI (match_operand:SI 1
14454 "extend_reg_or_0_operand" ""))
14455 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
14456 (const_int -4294967296))))
14457 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
14461 emit_insn (gen_ashldi3_media (operands[3],
14462 simplify_gen_subreg (DImode, operands[1],
14465 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
14469 (define_insn "mshflo_l_di"
14470 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14471 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14472 (const_int 4294967295))
14473 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14477 "mshflo.l %N1, %N2, %0"
14478 [(set_attr "type" "arith_media")
14479 (set_attr "highpart" "ignore")])
14481 (define_insn "*mshflo_l_di_rev"
14482 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14483 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14485 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14486 (const_int 4294967295))))]
14489 "mshflo.l %N2, %N1, %0"
14490 [(set_attr "type" "arith_media")
14491 (set_attr "highpart" "ignore")])
14493 ;; Combiner pattern for trampoline initialization.
14494 (define_insn_and_split "*double_shori"
14495 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14496 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
14498 (match_operand:DI 2 "const_int_operand" "n")))]
14500 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
14502 "rtx_equal_p (operands[0], operands[1])"
14505 HOST_WIDE_INT v = INTVAL (operands[2]);
14507 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
14508 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
14511 [(set_attr "highpart" "ignore")])
14514 (define_insn "*mshflo_l_di_x"
14515 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14516 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
14518 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
14522 "mshflo.l %N1, %N2, %0"
14523 [(set_attr "type" "arith_media")
14524 (set_attr "highpart" "ignore")])
14526 (define_insn_and_split "concat_v2sf"
14527 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
14528 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
14529 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
14530 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
14534 mshflo.l %N1, %N2, %0
14537 "TARGET_SHMEDIA && reload_completed
14538 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
14539 [(set (match_dup 3) (match_dup 1))
14540 (set (match_dup 4) (match_dup 2))]
14542 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
14543 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
14545 [(set_attr "type" "arith_media")
14546 (set_attr "highpart" "ignore")])
14548 (define_insn "*mshflo_l_di_x_rev"
14549 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14550 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
14552 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
14555 "mshflo.l %N2, %N1, %0"
14556 [(set_attr "type" "arith_media")
14557 (set_attr "highpart" "ignore")])
14559 (define_insn "ashlv2si3"
14560 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14561 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14562 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14564 "mshlld.l %1, %2, %0"
14565 [(set_attr "type" "arith_media")
14566 (set_attr "highpart" "depend")])
14569 [(set (match_operand 0 "any_register_operand" "")
14570 (match_operator 3 "shift_operator"
14571 [(match_operand 1 "any_register_operand" "")
14572 (match_operand 2 "shift_count_reg_operand" "")]))]
14573 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
14574 [(set (match_dup 0) (match_dup 3))]
14576 rtx count = operands[2];
14577 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
14579 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
14580 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
14581 || GET_CODE (count) == TRUNCATE)
14582 count = XEXP (count, 0);
14583 inner_mode = GET_MODE (count);
14584 count = simplify_gen_subreg (outer_mode, count, inner_mode,
14585 subreg_lowpart_offset (outer_mode, inner_mode));
14586 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
14587 operands[1], count);
14590 (define_insn "ashlv4hi3"
14591 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14592 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14593 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14595 "mshlld.w %1, %2, %0"
14596 [(set_attr "type" "arith_media")
14597 (set_attr "highpart" "depend")])
14599 (define_insn "lshrv2si3"
14600 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14601 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
14602 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14604 "mshlrd.l %1, %2, %0"
14605 [(set_attr "type" "arith_media")
14606 (set_attr "highpart" "depend")])
14608 (define_insn "lshrv4hi3"
14609 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14610 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
14611 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
14613 "mshlrd.w %1, %2, %0"
14614 [(set_attr "type" "arith_media")
14615 (set_attr "highpart" "depend")])
14617 (define_insn "subv2si3"
14618 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14619 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14620 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14622 "msub.l %N1, %2, %0"
14623 [(set_attr "type" "arith_media")
14624 (set_attr "highpart" "depend")])
14626 (define_insn "subv4hi3"
14627 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14628 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14629 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14631 "msub.w %N1, %2, %0"
14632 [(set_attr "type" "arith_media")
14633 (set_attr "highpart" "depend")])
14635 (define_insn_and_split "subv2hi3"
14636 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
14637 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
14638 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
14644 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
14645 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
14646 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
14647 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
14648 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
14650 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
14651 emit_insn (gen_truncdisi2 (si_dst, di_dst));
14654 [(set_attr "highpart" "must_split")])
14656 (define_insn "sssubv2si3"
14657 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
14658 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
14659 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
14661 "msubs.l %N1, %2, %0"
14662 [(set_attr "type" "mcmp_media")
14663 (set_attr "highpart" "depend")])
14665 (define_insn "ussubv8qi3"
14666 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14667 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
14668 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
14670 "msubs.ub %N1, %2, %0"
14671 [(set_attr "type" "mcmp_media")
14672 (set_attr "highpart" "depend")])
14674 (define_insn "sssubv4hi3"
14675 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
14676 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
14677 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
14679 "msubs.w %N1, %2, %0"
14680 [(set_attr "type" "mcmp_media")
14681 (set_attr "highpart" "depend")])
14683 ;; Floating Point Intrinsics
14685 (define_insn "fcosa_s"
14686 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14687 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14691 [(set_attr "type" "atrans_media")])
14693 (define_insn "fsina_s"
14694 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14695 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
14699 [(set_attr "type" "atrans_media")])
14701 (define_insn "fipr"
14702 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14703 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
14704 "fp_arith_reg_operand" "f")
14705 (match_operand:V4SF 2
14706 "fp_arith_reg_operand" "f"))
14707 (parallel [(const_int 0)]))
14708 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14709 (parallel [(const_int 1)])))
14710 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14711 (parallel [(const_int 2)]))
14712 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
14713 (parallel [(const_int 3)])))))]
14715 "fipr.s %1, %2, %0"
14716 [(set_attr "type" "fparith_media")])
14718 (define_insn "fsrra_s"
14719 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
14720 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
14724 [(set_attr "type" "atrans_media")])
14726 (define_insn "ftrv"
14727 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
14731 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
14732 (parallel [(const_int 0) (const_int 5)
14733 (const_int 10) (const_int 15)]))
14734 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
14736 (vec_select:V4SF (match_dup 1)
14737 (parallel [(const_int 4) (const_int 9)
14738 (const_int 14) (const_int 3)]))
14739 (vec_select:V4SF (match_dup 2)
14740 (parallel [(const_int 1) (const_int 2)
14741 (const_int 3) (const_int 0)]))))
14744 (vec_select:V4SF (match_dup 1)
14745 (parallel [(const_int 8) (const_int 13)
14746 (const_int 2) (const_int 7)]))
14747 (vec_select:V4SF (match_dup 2)
14748 (parallel [(const_int 2) (const_int 3)
14749 (const_int 0) (const_int 1)])))
14751 (vec_select:V4SF (match_dup 1)
14752 (parallel [(const_int 12) (const_int 1)
14753 (const_int 6) (const_int 11)]))
14754 (vec_select:V4SF (match_dup 2)
14755 (parallel [(const_int 3) (const_int 0)
14756 (const_int 1) (const_int 2)]))))))]
14758 "ftrv.s %1, %2, %0"
14759 [(set_attr "type" "fparith_media")])
14761 (define_insn "ldhi_l"
14762 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
14764 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
14767 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
14771 [(set_attr "type" "load_media")])
14773 (define_insn "ldhi_q"
14774 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14776 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
14779 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
14783 [(set_attr "type" "load_media")])
14785 (define_insn_and_split "*ldhi_q_comb0"
14786 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14788 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
14789 "register_operand" "r")
14790 (match_operand:SI 2
14791 "ua_offset" "I06"))
14794 (plus:SI (and:SI (match_dup 1) (const_int 7))
14797 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
14802 emit_insn (gen_ldhi_q (operands[0],
14803 gen_rtx_PLUS (SImode, operands[1], operands[2])));
14807 (define_insn_and_split "*ldhi_q_comb1"
14808 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14810 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
14811 "register_operand" "r")
14812 (match_operand:SI 2
14813 "ua_offset" "I06"))
14816 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
14817 "ua_offset" "I06"))
14821 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
14822 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
14827 emit_insn (gen_ldhi_q (operands[0],
14828 gen_rtx_PLUS (SImode, operands[1], operands[2])));
14832 (define_insn "ldlo_l"
14833 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
14835 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
14837 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
14838 (and:SI (match_dup 1) (const_int 3))))]
14841 [(set_attr "type" "load_media")])
14843 (define_insn "ldlo_q"
14844 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14846 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
14848 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
14849 (and:SI (match_dup 1) (const_int 7))))]
14852 [(set_attr "type" "load_media")])
14854 (define_insn_and_split "*ldlo_q_comb0"
14855 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14857 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
14858 (match_operand:SI 2 "ua_offset" "I06"))
14860 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
14861 (and:SI (match_dup 1) (const_int 7))))]
14862 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
14867 emit_insn (gen_ldlo_q (operands[0],
14868 gen_rtx_PLUS (SImode, operands[1], operands[2])));
14872 (define_insn_and_split "*ldlo_q_comb1"
14873 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
14875 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
14876 (match_operand:SI 2 "ua_offset" "I06"))
14878 (minus:SI (const_int 8)
14879 (and:SI (plus:SI (match_dup 1)
14880 (match_operand:SI 3 "ua_offset" "I06"))
14882 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
14883 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
14884 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
14889 emit_insn (gen_ldlo_q (operands[0],
14890 gen_rtx_PLUS (SImode, operands[1], operands[2])));
14894 (define_insn "sthi_l"
14895 [(set (zero_extract:SI
14896 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
14899 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
14901 (match_operand:SI 1 "arith_reg_operand" "r"))]
14904 [(set_attr "type" "ustore_media")])
14906 ;; All unaligned stores are considered to be 'narrow' because they typically
14907 ;; operate on less that a quadword, and when they operate on a full quadword,
14908 ;; the vanilla store high / store low sequence will cause a stall if not
14909 ;; scheduled apart.
14910 (define_insn "sthi_q"
14911 [(set (zero_extract:DI
14912 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
14915 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
14917 (match_operand:DI 1 "arith_reg_operand" "r"))]
14920 [(set_attr "type" "ustore_media")])
14922 (define_insn_and_split "*sthi_q_comb0"
14923 [(set (zero_extract:DI
14924 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
14925 "register_operand" "r")
14926 (match_operand:SI 1 "ua_offset"
14930 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
14932 (match_operand:DI 2 "arith_reg_operand" "r"))]
14933 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
14938 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
14943 (define_insn_and_split "*sthi_q_comb1"
14944 [(set (zero_extract:DI
14945 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
14946 "register_operand" "r")
14947 (match_operand:SI 1 "ua_offset"
14951 (plus:SI (and:SI (plus:SI (match_dup 0)
14952 (match_operand:SI 2 "ua_offset" "I06"))
14956 (match_operand:DI 3 "arith_reg_operand" "r"))]
14957 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
14958 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
14963 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
14968 ;; This is highpart user because the address is used as full 64 bit.
14969 (define_insn "stlo_l"
14970 [(set (zero_extract:SI
14971 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
14973 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
14974 (and:SI (match_dup 0) (const_int 3)))
14975 (match_operand:SI 1 "arith_reg_operand" "r"))]
14978 [(set_attr "type" "ustore_media")])
14980 (define_insn "stlo_q"
14981 [(set (zero_extract:DI
14982 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
14984 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
14985 (and:SI (match_dup 0) (const_int 7)))
14986 (match_operand:DI 1 "arith_reg_operand" "r"))]
14989 [(set_attr "type" "ustore_media")])
14991 (define_insn_and_split "*stlo_q_comb0"
14992 [(set (zero_extract:DI
14993 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
14994 (match_operand:SI 1 "ua_offset" "I06"))
14996 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
14997 (and:SI (match_dup 0) (const_int 7)))
14998 (match_operand:DI 2 "arith_reg_operand" "r"))]
14999 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
15004 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15009 (define_insn_and_split "*stlo_q_comb1"
15010 [(set (zero_extract:DI
15011 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
15012 (match_operand:SI 1 "ua_offset" "I06"))
15014 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
15015 (match_operand:SI 2
15016 "ua_offset" "I06"))
15018 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
15019 (match_operand:DI 3 "arith_reg_operand" "r"))]
15020 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
15025 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
15030 (define_insn "ldhi_l64"
15031 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15033 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15036 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
15040 [(set_attr "type" "load_media")])
15042 (define_insn "ldhi_q64"
15043 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15045 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
15048 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
15052 [(set_attr "type" "load_media")])
15054 (define_insn "ldlo_l64"
15055 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15057 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15059 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
15060 (and:DI (match_dup 1) (const_int 3))))]
15063 [(set_attr "type" "load_media")])
15065 (define_insn "ldlo_q64"
15066 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15068 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
15070 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
15071 (and:DI (match_dup 1) (const_int 7))))]
15074 [(set_attr "type" "load_media")])
15076 (define_insn "sthi_l64"
15077 [(set (zero_extract:SI
15078 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15081 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
15083 (match_operand:SI 1 "arith_reg_operand" "r"))]
15086 [(set_attr "type" "ustore_media")])
15088 (define_insn "sthi_q64"
15089 [(set (zero_extract:DI
15090 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
15093 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
15095 (match_operand:DI 1 "arith_reg_operand" "r"))]
15098 [(set_attr "type" "ustore_media")])
15100 (define_insn "stlo_l64"
15101 [(set (zero_extract:SI
15102 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15104 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
15105 (and:DI (match_dup 0) (const_int 3)))
15106 (match_operand:SI 1 "arith_reg_operand" "r"))]
15109 [(set_attr "type" "ustore_media")])
15111 (define_insn "stlo_q64"
15112 [(set (zero_extract:DI
15113 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
15115 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
15116 (and:DI (match_dup 0) (const_int 7)))
15117 (match_operand:DI 1 "arith_reg_operand" "r"))]
15120 [(set_attr "type" "ustore_media")])
15123 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
15124 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15128 [(set_attr "type" "arith_media")])
15130 (define_insn "nsbsi"
15131 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
15133 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15137 [(set_attr "type" "arith_media")])
15139 (define_insn "nsbdi"
15140 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
15142 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
15146 [(set_attr "type" "arith_media")])
15148 (define_expand "ffsdi2"
15149 [(set (match_operand:DI 0 "arith_reg_dest" "")
15150 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
15153 rtx scratch = gen_reg_rtx (DImode);
15156 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
15157 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
15158 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
15159 emit_insn (gen_nsbdi (scratch, scratch));
15160 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
15161 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
15162 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
15163 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
15168 (define_expand "ffssi2"
15169 [(set (match_operand:SI 0 "arith_reg_dest" "")
15170 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
15173 rtx scratch = gen_reg_rtx (SImode);
15174 rtx discratch = gen_reg_rtx (DImode);
15177 emit_insn (gen_adddi3 (discratch,
15178 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15180 emit_insn (gen_andcdi3 (discratch,
15181 simplify_gen_subreg (DImode, operands[1], SImode, 0),
15183 emit_insn (gen_nsbsi (scratch, discratch));
15184 last = emit_insn (gen_subsi3 (operands[0],
15185 force_reg (SImode, GEN_INT (63)), scratch));
15186 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
15191 (define_insn "byterev"
15192 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
15193 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
15194 (parallel [(const_int 7) (const_int 6) (const_int 5)
15195 (const_int 4) (const_int 3) (const_int 2)
15196 (const_int 1) (const_int 0)])))]
15199 [(set_attr "type" "arith_media")])
15201 ;; In user mode, the "pref" instruction will raise a RADDERR exception
15202 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
15203 ;; implementation of __builtin_prefetch for VxWorks RTPs.
15204 (define_expand "prefetch"
15205 [(prefetch (match_operand 0 "address_operand" "")
15206 (match_operand:SI 1 "const_int_operand" "")
15207 (match_operand:SI 2 "const_int_operand" ""))]
15208 "(TARGET_SH2A || TARGET_SH3 || TARGET_SH5)
15209 && (TARGET_SHMEDIA || ! TARGET_VXWORKS_RTP)")
15211 (define_insn "*prefetch"
15212 [(prefetch (match_operand:SI 0 "register_operand" "r")
15213 (match_operand:SI 1 "const_int_operand" "n")
15214 (match_operand:SI 2 "const_int_operand" "n"))]
15215 "(TARGET_SH2A || TARGET_SH3 || TARGET_SHCOMPACT) && ! TARGET_VXWORKS_RTP"
15217 [(set_attr "type" "other")])
15219 (define_insn "*prefetch_media"
15220 [(prefetch (match_operand:QI 0 "address_operand" "p")
15221 (match_operand:SI 1 "const_int_operand" "n")
15222 (match_operand:SI 2 "const_int_operand" "n"))]
15225 operands[0] = gen_rtx_MEM (QImode, operands[0]);
15226 output_asm_insn ("ld%M0.b %m0,r63", operands);
15229 [(set_attr "type" "other")])
15231 (define_insn "alloco_i"
15232 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
15233 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
15238 if (GET_CODE (operands[0]) == PLUS)
15240 xops[0] = XEXP (operands[0], 0);
15241 xops[1] = XEXP (operands[0], 1);
15245 xops[0] = operands[0];
15246 xops[1] = const0_rtx;
15248 output_asm_insn ("alloco %0, %1", xops);
15251 [(set_attr "type" "other")])
15254 [(set (match_operand 0 "any_register_operand" "")
15255 (match_operand 1 "" ""))]
15256 "TARGET_SHMEDIA && reload_completed"
15257 [(set (match_dup 0) (match_dup 1))]
15261 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
15266 ; Stack Protector Patterns
15268 (define_expand "stack_protect_set"
15269 [(set (match_operand 0 "memory_operand" "")
15270 (match_operand 1 "memory_operand" ""))]
15273 if (TARGET_SHMEDIA)
15275 if (TARGET_SHMEDIA64)
15276 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
15278 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
15281 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
15286 (define_insn "stack_protect_set_si"
15287 [(set (match_operand:SI 0 "memory_operand" "=m")
15288 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15289 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15292 return "mov.l %1,%2" "\n"
15293 " mov.l %2,%0" "\n"
15296 [(set_attr "type" "other")
15297 (set_attr "length" "6")])
15299 (define_insn "stack_protect_set_si_media"
15300 [(set (match_operand:SI 0 "memory_operand" "=m")
15301 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15302 (set (match_scratch:SI 2 "=&r") (const_int 0))]
15305 return "ld%M1.l %m1,%2" "\n"
15306 " st%M0.l %m0,%2" "\n"
15309 [(set_attr "type" "other")
15310 (set_attr "length" "12")])
15312 (define_insn "stack_protect_set_di_media"
15313 [(set (match_operand:DI 0 "memory_operand" "=m")
15314 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
15315 (set (match_scratch:DI 2 "=&r") (const_int 0))]
15318 return "ld%M1.q %m1,%2" "\n"
15319 " st%M0.q %m0,%2" "\n"
15322 [(set_attr "type" "other")
15323 (set_attr "length" "12")])
15325 (define_expand "stack_protect_test"
15326 [(match_operand 0 "memory_operand" "")
15327 (match_operand 1 "memory_operand" "")
15328 (match_operand 2 "" "")]
15331 if (TARGET_SHMEDIA)
15333 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
15336 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
15337 if (TARGET_SHMEDIA64)
15339 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
15341 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
15345 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
15347 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
15352 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
15353 emit_jump_insn (gen_branch_true (operands[2]));
15359 (define_insn "stack_protect_test_si"
15360 [(set (reg:SI T_REG)
15361 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
15362 (match_operand:SI 1 "memory_operand" "m")]
15364 (set (match_scratch:SI 2 "=&r") (const_int 0))
15365 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15368 return "mov.l %0,%2" "\n"
15369 " mov.l %1,%3" "\n"
15370 " cmp/eq %2,%3" "\n"
15374 [(set_attr "type" "other")
15375 (set_attr "length" "10")])
15377 (define_insn "stack_protect_test_si_media"
15378 [(set (match_operand:SI 0 "register_operand" "=&r")
15379 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
15380 (match_operand:SI 2 "memory_operand" "m")]
15382 (set (match_scratch:SI 3 "=&r") (const_int 0))]
15385 return "ld%M1.l %m1,%0" "\n"
15386 " ld%M2.l %m2,%3" "\n"
15387 " cmpeq %0,%3,%0" "\n"
15390 [(set_attr "type" "other")
15391 (set_attr "length" "16")])
15393 (define_insn "stack_protect_test_di_media"
15394 [(set (match_operand:DI 0 "register_operand" "=&r")
15395 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
15396 (match_operand:DI 2 "memory_operand" "m")]
15398 (set (match_scratch:DI 3 "=&r") (const_int 0))]
15401 return "ld%M1.q %m1,%0" "\n"
15402 " ld%M2.q %m2,%3" "\n"
15403 " cmpeq %0,%3,%0" "\n"
15406 [(set_attr "type" "other")
15407 (set_attr "length" "16")])
15409 (include "sync.md")